diff options
| -rw-r--r-- | fw/fe310/eos/board.h | 8 | ||||
| -rw-r--r-- | fw/fe310/eos/eos.c | 4 | ||||
| -rw-r--r-- | fw/fe310/eos/eve/eve.c | 10 | ||||
| -rw-r--r-- | fw/fe310/eos/i2s.c | 52 | ||||
| -rw-r--r-- | fw/fe310/eos/trap_entry.S | 163 | 
5 files changed, 146 insertions, 91 deletions
diff --git a/fw/fe310/eos/board.h b/fw/fe310/eos/board.h index a695029..a18b58f 100644 --- a/fw/fe310/eos/board.h +++ b/fw/fe310/eos/board.h @@ -30,14 +30,14 @@  #define I2S_PIN_SD_IN           13  #define I2S_PIN_SD_OUT          12 -#define I2S_IRQ_WS_ID           (INT_PWM2_BASE + 0) -#define I2S_IRQ_SD_ID           (INT_PWM2_BASE + 3) +#define I2S_IRQ_WS_ID           (INT_PWM1_BASE + 0) +#define I2S_IRQ_SD_ID           (INT_PWM1_BASE + 3)  #define I2S_CTRL_ADDR_CK        PWM0_CTRL_ADDR  #define I2S_CTRL_ADDR_WS_MIC    PWM1_CTRL_ADDR  #define I2S_CTRL_ADDR_WS_SPK    PWM2_CTRL_ADDR -#define I2S_IDLE_CYCLES         8 +#define I2S_IDLE_CYCLES         1  #define CTP_PIN_INT             1  #define CTP_PIN_RST             19 @@ -46,5 +46,5 @@  #define EVE_GPIO_CAM            0  #define EVE_GPIO_LCD_EN         1 -#define EVE_GPIO_GAIN_SEL       2 +#define EVE_GPIO_GAIN           2  #define EVE_GPIO_HAPT           3 diff --git a/fw/fe310/eos/eos.c b/fw/fe310/eos/eos.c index bf0f0da..b52ed93 100644 --- a/fw/fe310/eos/eos.c +++ b/fw/fe310/eos/eos.c @@ -28,13 +28,13 @@ void eos_init(void) {      int touch_calibrate = 0;      int rv; -    printf("INIT:%d\n", wakeup_cause); -      eos_evtq_init(wakeup_cause);      eos_intr_init(wakeup_cause);      eos_timer_init(wakeup_cause);      eos_uart_init(wakeup_cause); +    printf("INIT:%d\n", wakeup_cause); +      rv = eos_pwr_init(wakeup_cause);      if (rv) printf("PWR INIT ERR:%d\n", rv);      rv = eos_i2s_init(wakeup_cause); diff --git a/fw/fe310/eos/eve/eve.c b/fw/fe310/eos/eve/eve.c index 91458d8..e1191fc 100644 --- a/fw/fe310/eos/eve/eve.c +++ b/fw/fe310/eos/eve/eve.c @@ -458,27 +458,27 @@ void eve_brightness(uint8_t b) {  int eve_gpio_get(int gpio) {      uint16_t reg = eve_read16(REG_GPIOX); +      return !!(reg & (1 << gpio));  }  void eve_gpio_set(int gpio, int val) {      uint16_t reg = eve_read16(REG_GPIOX);      uint16_t reg_val = (1 << gpio); -    if (val) { -        reg |= reg_val; -    } else { -        reg &= ~reg_val; -    } + +    reg = val ? reg | reg_val : reg & ~reg_val;      eve_write16(REG_GPIOX, reg);  }  uint8_t eve_gpio_get_dir(void) {      uint16_t reg = eve_read16(REG_GPIOX_DIR); +      return reg & 0x000f;  }  void eve_gpio_set_dir(uint8_t dir) {      uint16_t reg = eve_read16(REG_GPIOX_DIR); +      reg &= 0xfff0;      reg |= dir & 0x0f;      eve_write16(REG_GPIOX_DIR, reg); diff --git a/fw/fe310/eos/i2s.c b/fw/fe310/eos/i2s.c index 5e5eaa7..9cc32e0 100644 --- a/fw/fe310/eos/i2s.c +++ b/fw/fe310/eos/i2s.c @@ -28,6 +28,8 @@  EOSABuf _eos_i2s_mic_buf;  EOSABuf _eos_i2s_spk_buf;  uint32_t _eos_i2s_fmt = 0; +uint32_t _eos_i2s_mode = 0; +uint32_t _eos_i2s_sample = 0;  uint32_t _eos_i2s_mic_wm = 0;  uint32_t _eos_i2s_spk_wm = 0;  uint32_t _eos_i2s_mic_evt_enable = 0; @@ -102,12 +104,14 @@ static void i2s_handle_evt(unsigned char type, unsigned char *buffer, uint16_t l              _eos_i2s_mic_evt_enable = 1;              set_csr(mstatus, MSTATUS_MIE);              break; +          case EOS_I2S_ETYPE_SPK:              if (i2s_spk_handler) i2s_spk_handler(type);              clear_csr(mstatus, MSTATUS_MIE);              _eos_i2s_spk_evt_enable = 1;              set_csr(mstatus, MSTATUS_MIE);              break; +          default:              eos_evtq_bad_handler(type, buffer, len);              break; @@ -125,12 +129,10 @@ static void _spk_vol_set(uint8_t vol) {      if (spk_cmp <= 0) {          I2S_REG_WS_SPK(PWM_CMP1) = i2s_clk_period * (32 + spk_cmp);          I2S_REG_WS_SPK(PWM_CMP2) = i2s_clk_period * (64 + spk_cmp); -        I2S_REG_WS_SPK(PWM_CMP3) = i2s_clk_period * 33;          GPIO_REG(GPIO_OUTPUT_XOR) &= ~(1 << I2S_PIN_WS_SPK);      } else {          I2S_REG_WS_SPK(PWM_CMP1) = i2s_clk_period * spk_cmp;          I2S_REG_WS_SPK(PWM_CMP2) = i2s_clk_period * (32 + spk_cmp); -        I2S_REG_WS_SPK(PWM_CMP3) = i2s_clk_period * (33 + spk_cmp);          GPIO_REG(GPIO_OUTPUT_XOR) |= (1 << I2S_PIN_WS_SPK);      }  } @@ -140,6 +142,10 @@ extern void _eos_i2s_start_pwm(void);  int eos_i2s_init(uint8_t wakeup_cause) {      eos_evtq_set_handler(EOS_EVT_I2S, i2s_handle_evt); +    I2S_REG_CK(PWM_CFG)         = 0; +    I2S_REG_WS_MIC(PWM_CFG)     = 0; +    I2S_REG_WS_SPK(PWM_CFG)     = 0; +      eos_i2s_init_mux();      GPIO_REG(GPIO_OUTPUT_VAL)   |=  (1 << I2S_PIN_CK_SW); @@ -202,10 +208,10 @@ void eos_i2s_start(uint32_t sample_rate, unsigned char fmt) {      _eos_i2s_mic_evt_enable = 1;      _eos_i2s_spk_evt_enable = 1; +    eos_intr_set_priority(I2S_IRQ_SD_ID, IRQ_PRIORITY_I2S_SD);      eos_intr_set_priority(I2S_IRQ_WS_ID, IRQ_PRIORITY_I2S_WS); -    eos_intr_set_priority(I2S_IRQ_SD_ID, 0); -    eos_intr_enable(I2S_IRQ_WS_ID);      eos_intr_enable(I2S_IRQ_SD_ID); +    eos_intr_enable(I2S_IRQ_WS_ID);      _eos_i2s_start_pwm();      /* @@ -214,9 +220,13 @@ void eos_i2s_start(uint32_t sample_rate, unsigned char fmt) {      I2S_REG_WS_SPK(PWM_CFG)     = PWM_CFG_ENALWAYS | PWM_CFG_ZEROCMP | PWM_CFG_CMP1GANG;      */ -    GPIO_REG(GPIO_OUTPUT_VAL)   |= (1 << I2S_PIN_CK_SR); -    GPIO_REG(GPIO_IOF_SEL)      |= I2S_PIN_PWM; -    GPIO_REG(GPIO_IOF_EN)       |= I2S_PIN_PWM; +    GPIO_REG(GPIO_OUTPUT_VAL)   |=  (1 << I2S_PIN_WS_MIC); +    GPIO_REG(GPIO_INPUT_EN)     &= ~(1 << I2S_PIN_WS_MIC); +    GPIO_REG(GPIO_OUTPUT_EN)    |=  (1 << I2S_PIN_WS_MIC); + +    GPIO_REG(GPIO_OUTPUT_VAL)   |=  (1 << I2S_PIN_CK_SR); +    GPIO_REG(GPIO_IOF_SEL)      |=  I2S_PIN_PWM; +    GPIO_REG(GPIO_IOF_EN)       |=  I2S_PIN_PWM;  }  void eos_i2s_stop(void) { @@ -229,8 +239,7 @@ void eos_i2s_stop(void) {      _eos_i2s_mic_evt_enable = 0;      _eos_i2s_spk_evt_enable = 0; -    eos_intr_set_priority(I2S_IRQ_WS_ID, 0); -    eos_intr_set_priority(I2S_IRQ_SD_ID, 0); +      eos_intr_disable(I2S_IRQ_WS_ID);      eos_intr_disable(I2S_IRQ_SD_ID); @@ -239,10 +248,13 @@ void eos_i2s_stop(void) {      GPIO_REG(GPIO_OUTPUT_XOR)   &= ~(1 << I2S_PIN_WS_SPK);      GPIO_REG(GPIO_IOF_EN)       &= ~I2S_PIN_PWM; + +    eos_i2s_mic_set_wm(0); +    eos_i2s_spk_set_wm(0);  }  int eos_i2s_running(void) { -    return !!(GPIO_REG(GPIO_IOF_EN) & I2S_PIN_PWM); +    return !!(GPIO_REG(GPIO_IOF_EN) & (1 << I2S_PIN_CK));  }  void eos_i2s_mic_init(uint8_t *mic_arr, uint16_t mic_arr_size) { @@ -291,16 +303,22 @@ uint16_t eos_i2s_mic_read(uint8_t *sample, uint16_t ssize) {  }  int eos_i2s_mic_pop8(uint8_t *sample) { +    int ret; +      clear_csr(mstatus, MSTATUS_MIE); -    int ret = _abuf_pop8(&_eos_i2s_mic_buf, sample); +    ret = _abuf_pop8(&_eos_i2s_mic_buf, sample);      set_csr(mstatus, MSTATUS_MIE); +      return ret;  }  int eos_i2s_mic_pop16(uint16_t *sample) { +    int ret; +      clear_csr(mstatus, MSTATUS_MIE); -    int ret = _abuf_pop16(&_eos_i2s_mic_buf, sample); +    ret = _abuf_pop16(&_eos_i2s_mic_buf, sample);      set_csr(mstatus, MSTATUS_MIE); +      return ret;  } @@ -364,16 +382,22 @@ uint16_t eos_i2s_spk_write(uint8_t *sample, uint16_t ssize) {  }  int eos_i2s_spk_push8(uint8_t sample) { +    int ret; +      clear_csr(mstatus, MSTATUS_MIE); -    int ret = _abuf_push8(&_eos_i2s_spk_buf, sample); +    ret = _abuf_push8(&_eos_i2s_spk_buf, sample);      set_csr(mstatus, MSTATUS_MIE); +      return ret;  }  int eos_i2s_spk_push16(uint16_t sample) { +    int ret; +      clear_csr(mstatus, MSTATUS_MIE); -    int ret = _abuf_push16(&_eos_i2s_spk_buf, sample); +    ret = _abuf_push16(&_eos_i2s_spk_buf, sample);      set_csr(mstatus, MSTATUS_MIE); +      return ret;  } diff --git a/fw/fe310/eos/trap_entry.S b/fw/fe310/eos/trap_entry.S index 96024cb..506683b 100644 --- a/fw/fe310/eos/trap_entry.S +++ b/fw/fe310/eos/trap_entry.S @@ -37,7 +37,7 @@  .global eos_trap_entry  eos_trap_entry: -  addi sp, sp, -8*REGBYTES +  addi sp, sp, -10*REGBYTES    STORE x8, 0*REGBYTES(sp)    STORE x9, 1*REGBYTES(sp)    STORE x18, 2*REGBYTES(sp) @@ -46,6 +46,8 @@ eos_trap_entry:    STORE x21, 5*REGBYTES(sp)    STORE x22, 6*REGBYTES(sp)    STORE x23, 7*REGBYTES(sp) +  STORE x24, 8*REGBYTES(sp) +  STORE x25, 9*REGBYTES(sp)    csrr x8, mcause    li x18, MCAUSE_EXT @@ -84,34 +86,62 @@ evtq_push:    jalr x0, x21  i2s_handle_sd: -  # exit if too early -  li x18, I2S_CTRL_ADDR_WS_SPK -  lw x8, PWM_COUNT(x18) -  lw x9, PWM_CMP3(x18) -  bltu x8, x9, i2s_handle_sd_exit +  li x9, I2S_CTRL_ADDR_WS_MIC +  lw x18, PWM_COUNT(x9) +  lw x19, PWM_CMP1(x9) +  lw x20, PWM_CMP2(x9) +  lw x21, PWM_CMP3(x9) -  # disable sd irq -  li x18, PLIC_PRIORITY -  sw x0, 4*I2S_IRQ_SD_ID(x18) +  # exit if too early +  bltu x18, x21, i2s_sd_exit + +  # move CMPs for next channel and store parity to x25 +  li x25, 0 +  bltu x20, x19, 0f +  li x25, 1 +  neg x19, x19 +  li x22, PLIC_PRIORITY +  sw x0, 4*I2S_IRQ_SD_ID(x22) +0: +  add x20, x20, x19 +  add x21, x21, x19 +  sw x20, PWM_CMP2(x9) +  sw x21, PWM_CMP3(x9)    la x9, _eos_i2s_fmt -  lw x23, 0(x9) +  lw x24, 0(x9)  i2s_abuf_pop: -  # pop from spk buf -> x8 +  la x9, _eos_i2s_mode +  lw x22, 0(x9) +  and x22, x22, x25 +  beqz x22, 0f + +  la x9, _eos_i2s_sample +  lw x8, 0(x9) +  j i2s_sd_xchg + +0:    mv x8, x0 + +  # check for pop from spk buf +  la x9, _eos_i2s_spk_wm +  lw x22, 0(x9) +  beqz x22, i2s_sd_xchg + +  # pop from spk buf -> x8    la x9, _eos_i2s_spk_buf    lhu x18, I2S_ABUF_OFF_IDXR(x9)    lhu x19, I2S_ABUF_OFF_IDXW(x9)    lhu x20, I2S_ABUF_OFF_SIZE(x9) -  beq x18, x19, i2s_handle_sd_xchg +  beq x18, x19, 2f    addi x20, x20, -1    and x20, x20, x18    lw x21, I2S_ABUF_OFF_ARRAY(x9)    add x21, x21, x20 -  beqz x23, 0f +  beqz x24, 0f    lbu x8, 0(x21)    addi x18, x18, 1    j 1f @@ -124,15 +154,13 @@ i2s_abuf_pop:  1:    sh x18, I2S_ABUF_OFF_IDXR(x9) +2:    li x21, 0xffff    sub x18, x19, x18    and x18, x18, x21    # check for push to event queue -  la x9, _eos_i2s_spk_wm -  lw x20, 0(x9) -  beqz x20, i2s_decode -  bgtu x18, x20, i2s_decode +  bgtu x18, x22, i2s_decode    la x9, _eos_i2s_spk_evt_enable    lw x18, 0(x9) @@ -146,7 +174,7 @@ i2s_abuf_pop:    sb x18, MSGQ_ITEM_OFF_TYPE(x21)  i2s_decode: -  beqz x23, i2s_handle_sd_xchg +  beqz x24, 3f    # aLaw decode -> x8    xori x8, x8, 0x55    andi x9, x8, 0x80 @@ -181,10 +209,13 @@ i2s_decode:    slli x8, x8, 1    ori x8, x8, 1  2: -  beqz x9, i2s_handle_sd_xchg +  beqz x9, 3f    mul x8, x8, x9 +3: +  la x9, _eos_i2s_sample +  sw x8, 0(x9) -i2s_handle_sd_xchg: +i2s_sd_xchg:    # read/write shift reg: x8 -> sr -> x8    li x18, GPIO_CTRL_ADDR    li x19, (0x1 << I2S_PIN_SD_IN) @@ -234,17 +265,15 @@ i2s_handle_sd_xchg:    xor x22, x22, x21    sw x22, GPIO_OUTPUT_VAL(x18) +  addi x23, x23, -1 +  bnez x23, 0b +    # idle    li x9, I2S_IDLE_CYCLES  1:    addi x9, x9, -1    bnez x9, 1b -  addi x23, x23, -1 -  beqz x23, 2f -  j 0b - -2:    # 74HC595 ck low (I2S_PIN_CK_SR high)    xor x22, x22, x21    sw x22, GPIO_OUTPUT_VAL(x18) @@ -256,11 +285,8 @@ i2s_handle_sd_xchg:    slli x8, x8, 16    srai x8, x8, 16 -  la x9, _eos_i2s_fmt -  lw x23, 0(x9) -  i2s_encode: -  beqz x23, i2s_abuf_push +  beqz x24, i2s_abuf_push    # aLaw encode -> x8    li x18, 0x800    li x19, 7 @@ -292,6 +318,14 @@ i2s_encode:    andi x8, x8, 0xff  i2s_abuf_push: +  # check parity +  # bnez x25, i2s_sd_exit + +  # check for push to mic buf +  la x9, _eos_i2s_mic_wm +  lw x22, 0(x9) +  beqz x22, i2s_sd_exit +    # push to mic buf    la x9, _eos_i2s_mic_buf    lhu x18, I2S_ABUF_OFF_IDXR(x9) @@ -301,13 +335,13 @@ i2s_abuf_push:    sub x18, x19, x18    and x18, x18, x21 -  beq x18, x20, i2s_handle_sd_exit +  beq x18, x20, 2f    addi x20, x20, -1    and x20, x20, x19    lw x21, I2S_ABUF_OFF_ARRAY(x9)    add x21, x21, x20 -  beqz x23, 0f +  beqz x24, 0f    sb x8, 0(x21)    addi x19, x19, 1    addi x18, x18, 1 @@ -321,24 +355,22 @@ i2s_abuf_push:  1:    sh x19, I2S_ABUF_OFF_IDXW(x9) +2:    # check for push to event queue -  la x9, _eos_i2s_mic_wm -  lw x20, 0(x9) -  beqz x20, i2s_handle_sd_exit -  bltu x18, x20, i2s_handle_sd_exit +  bltu x18, x22, i2s_sd_exit    la x9, _eos_i2s_mic_evt_enable    lw x18, 0(x9) -  beqz x18, i2s_handle_sd_exit +  beqz x18, i2s_sd_exit    sw x0, 0(x9)    # push to event queue    jal x22, evtq_push -  beqz x21, i2s_handle_sd_exit +  beqz x21, i2s_sd_exit    li x18, (EOS_EVT_I2S | EOS_I2S_ETYPE_MIC)    sb x18, MSGQ_ITEM_OFF_TYPE(x21) -i2s_handle_sd_exit: +i2s_sd_exit:    # complete    li x18, I2S_IRQ_SD_ID    li x19, PLIC_CLAIM @@ -418,7 +450,9 @@ trap_exit_data:    LOAD x21, 5*REGBYTES(sp)    LOAD x22, 6*REGBYTES(sp)    LOAD x23, 7*REGBYTES(sp) -  addi sp, sp, 8*REGBYTES +  LOAD x24, 8*REGBYTES(sp) +  LOAD x25, 9*REGBYTES(sp) +  addi sp, sp, 10*REGBYTES    mret @@ -431,7 +465,7 @@ handle_intr:    .align 4  trap_entry_text: -  addi sp, sp, -24*REGBYTES +  addi sp, sp, -22*REGBYTES    STORE x1, 0*REGBYTES(sp)    STORE x2, 1*REGBYTES(sp) @@ -448,14 +482,12 @@ trap_entry_text:    STORE x15, 12*REGBYTES(sp)    STORE x16, 13*REGBYTES(sp)    STORE x17, 14*REGBYTES(sp) -  STORE x24, 15*REGBYTES(sp) -  STORE x25, 16*REGBYTES(sp) -  STORE x26, 17*REGBYTES(sp) -  STORE x27, 18*REGBYTES(sp) -  STORE x28, 19*REGBYTES(sp) -  STORE x29, 20*REGBYTES(sp) -  STORE x30, 21*REGBYTES(sp) -  STORE x31, 22*REGBYTES(sp) +  STORE x26, 15*REGBYTES(sp) +  STORE x27, 16*REGBYTES(sp) +  STORE x28, 17*REGBYTES(sp) +  STORE x29, 18*REGBYTES(sp) +  STORE x30, 19*REGBYTES(sp) +  STORE x31, 20*REGBYTES(sp)    li x18, MCAUSE_TIMER    beq x8, x18, handle_timer @@ -473,7 +505,6 @@ handle_ext:    call eos_intr_handle    li x18, PLIC_CLAIM    sw a0, 0(x18) -  j trap_exit_text  trap_exit_text:    # Remain in M-mode after mret @@ -495,23 +526,23 @@ trap_exit_text:    LOAD x15, 12*REGBYTES(sp)    LOAD x16, 13*REGBYTES(sp)    LOAD x17, 14*REGBYTES(sp) -  LOAD x24, 15*REGBYTES(sp) -  LOAD x25, 16*REGBYTES(sp) -  LOAD x26, 17*REGBYTES(sp) -  LOAD x27, 18*REGBYTES(sp) -  LOAD x28, 19*REGBYTES(sp) -  LOAD x29, 20*REGBYTES(sp) -  LOAD x30, 21*REGBYTES(sp) -  LOAD x31, 22*REGBYTES(sp) - -  LOAD x8, 24*REGBYTES(sp) -  LOAD x9, 25*REGBYTES(sp) -  LOAD x18, 26*REGBYTES(sp) -  LOAD x19, 27*REGBYTES(sp) -  LOAD x20, 28*REGBYTES(sp) -  LOAD x21, 29*REGBYTES(sp) -  LOAD x22, 30*REGBYTES(sp) -  LOAD x23, 31*REGBYTES(sp) +  LOAD x26, 15*REGBYTES(sp) +  LOAD x27, 16*REGBYTES(sp) +  LOAD x28, 17*REGBYTES(sp) +  LOAD x29, 18*REGBYTES(sp) +  LOAD x30, 19*REGBYTES(sp) +  LOAD x31, 20*REGBYTES(sp) + +  LOAD x8, 22*REGBYTES(sp) +  LOAD x9, 23*REGBYTES(sp) +  LOAD x18, 24*REGBYTES(sp) +  LOAD x19, 25*REGBYTES(sp) +  LOAD x20, 26*REGBYTES(sp) +  LOAD x21, 27*REGBYTES(sp) +  LOAD x22, 28*REGBYTES(sp) +  LOAD x23, 29*REGBYTES(sp) +  LOAD x24, 30*REGBYTES(sp) +  LOAD x25, 31*REGBYTES(sp)    addi sp, sp, 32*REGBYTES    mret  | 
