diff options
Diffstat (limited to 'code/fe310/eos')
-rw-r--r-- | code/fe310/eos/i2s.c | 34 | ||||
-rw-r--r-- | code/fe310/eos/i2s.h | 2 | ||||
-rw-r--r-- | code/fe310/eos/i2s_def.h | 5 | ||||
-rw-r--r-- | code/fe310/eos/trap_entry.S | 44 |
4 files changed, 42 insertions, 43 deletions
diff --git a/code/fe310/eos/i2s.c b/code/fe310/eos/i2s.c index 34cbfc4..543102f 100644 --- a/code/fe310/eos/i2s.c +++ b/code/fe310/eos/i2s.c @@ -20,11 +20,10 @@ EOSABuf _eos_i2s_spk_buf; uint32_t _eos_i2s_ck_period = 0; uint32_t _eos_i2s_mic_wm = 0; uint32_t _eos_i2s_spk_wm = 0; -uint32_t _eos_i2s_mic_volume = 3; +uint32_t _eos_i2s_mic_volume = 2; uint32_t _eos_i2s_spk_volume = 3; -uint32_t _eos_i2s_mic_rd = 0; -uint32_t _eos_i2s_spk_wr = 0; static eos_evt_fptr_t evt_handler[I2S_MAX_HANDLER]; +uint32_t _eos_i2s_evt_enable[I2S_MAX_HANDLER]; static void _abuf_init(EOSABuf *buf, uint8_t *array, uint16_t size) { buf->idx_r = 0; @@ -78,18 +77,21 @@ static uint16_t _abuf_len(EOSABuf *buf) { } static void audio_handler(unsigned char cmd, unsigned char *buffer, uint16_t len) { - if ((cmd & ~EOS_EVT_MASK) < I2S_MAX_HANDLER) { - evt_handler[cmd & ~EOS_EVT_MASK](cmd, buffer, len); + cmd = cmd & ~EOS_EVT_MASK; + + if (cmd < I2S_MAX_HANDLER) { + evt_handler[cmd](cmd, buffer, len); + _eos_i2s_evt_enable[cmd] = 1; } else { eos_evtq_bad_handler(cmd, buffer, len); } } -void eos_i2s_init(void) { +void eos_i2s_init(uint32_t sample_rate) { int i; unsigned long f = get_cpu_freq(); - _eos_i2s_ck_period = 512; + _eos_i2s_ck_period = (f / (sample_rate * 64)) & ~I2S_PWM_SCALE_CK_MASK; uint32_t _ck_period_scaled = _eos_i2s_ck_period >> I2S_PWM_SCALE_CK; GPIO_REG(GPIO_INPUT_EN) &= ~(1 << I2S_PIN_LR); GPIO_REG(GPIO_OUTPUT_EN) |= (1 << I2S_PIN_LR); @@ -113,13 +115,13 @@ void eos_i2s_init(void) { I2S_PWM_REG_CK(PWM_COUNT) = 0; I2S_PWM_REG_CK(PWM_CMP0) = _ck_period_scaled; I2S_PWM_REG_CK(PWM_CMP1) = _ck_period_scaled / 2; - I2S_PWM_REG_CK(PWM_CMP2) = _ck_period_scaled / 4; + I2S_PWM_REG_CK(PWM_CMP2) = _ck_period_scaled / 8; I2S_PWM_REG_WS(PWM_CFG) = 0; I2S_PWM_REG_WS(PWM_COUNT) = 0; I2S_PWM_REG_WS(PWM_CMP0) = (_eos_i2s_ck_period + 1) * 64 - 1; I2S_PWM_REG_WS(PWM_CMP1) = (_eos_i2s_ck_period + 1) * 32; - I2S_PWM_REG_WS(PWM_CMP2) = (_eos_i2s_ck_period + 1) * 64 - 2 * _eos_i2s_ck_period; + I2S_PWM_REG_WS(PWM_CMP2) = (_eos_i2s_ck_period + 1) * 64 - 512; eos_intr_set(I2S_IRQ_SD_ID, 0, NULL); eos_intr_set(I2S_IRQ_CK_ID, 0, NULL); @@ -136,9 +138,9 @@ void eos_i2s_init_mic(uint8_t *mic_arr, uint16_t mic_arr_size, eos_evt_fptr_t mi _eos_i2s_mic_wm = mic_wm; evt_handler[I2S_EVT_MIC] = mic_wm_handler; if (mic_wm) { - _eos_i2s_mic_rd = 1; + _eos_i2s_evt_enable[I2S_EVT_MIC] = 1; } else { - _eos_i2s_mic_rd = 0; + _eos_i2s_evt_enable[I2S_EVT_MIC] = 0; } } @@ -147,9 +149,9 @@ void eos_i2s_init_spk(uint8_t *spk_arr, uint16_t spk_arr_size, eos_evt_fptr_t sp _eos_i2s_spk_wm = spk_wm; evt_handler[I2S_EVT_SPK] = spk_wm_handler; if (spk_wm) { - _eos_i2s_spk_wr = 1; + _eos_i2s_evt_enable[I2S_EVT_SPK] = 1; } else { - _eos_i2s_spk_wr = 0; + _eos_i2s_evt_enable[I2S_EVT_SPK] = 0; } } @@ -209,13 +211,11 @@ uint16_t eos_i2s_mic_read(uint8_t *sample, uint16_t ssize) { for (i=0; i<ssize/I2S_ABUF_SIZE_CHUNK && _ssize == i*I2S_ABUF_SIZE_CHUNK; i++) { clear_csr(mstatus, MSTATUS_MIE); _ssize += _abuf_read(&_eos_i2s_mic_buf, sample+i*I2S_ABUF_SIZE_CHUNK, I2S_ABUF_SIZE_CHUNK); - if ((ssize == _ssize) || (_ssize != (i+1)*I2S_ABUF_SIZE_CHUNK)) _eos_i2s_mic_rd = 1; set_csr(mstatus, MSTATUS_MIE); } if ((ssize > _ssize) && (_ssize == i*I2S_ABUF_SIZE_CHUNK)) { clear_csr(mstatus, MSTATUS_MIE); _ssize += _abuf_read(&_eos_i2s_mic_buf, sample+i*I2S_ABUF_SIZE_CHUNK, ssize - _ssize); - _eos_i2s_mic_rd = 1; set_csr(mstatus, MSTATUS_MIE); } return _ssize; @@ -224,7 +224,6 @@ uint16_t eos_i2s_mic_read(uint8_t *sample, uint16_t ssize) { int eos_i2s_mic_pop(uint8_t *sample) { clear_csr(mstatus, MSTATUS_MIE); int ret = _abuf_pop(&_eos_i2s_mic_buf, sample); - _eos_i2s_mic_rd = 1; set_csr(mstatus, MSTATUS_MIE); return ret; } @@ -242,13 +241,11 @@ uint16_t eos_i2s_spk_write(uint8_t *sample, uint16_t ssize) { for (i=0; i<ssize/I2S_ABUF_SIZE_CHUNK && _ssize == i*I2S_ABUF_SIZE_CHUNK; i++) { clear_csr(mstatus, MSTATUS_MIE); _ssize += _abuf_write(&_eos_i2s_spk_buf, sample+i*I2S_ABUF_SIZE_CHUNK, I2S_ABUF_SIZE_CHUNK); - if ((ssize == _ssize) || (_ssize != (i+1)*I2S_ABUF_SIZE_CHUNK)) _eos_i2s_spk_wr = 1; set_csr(mstatus, MSTATUS_MIE); } if ((ssize > _ssize) && (_ssize == i*I2S_ABUF_SIZE_CHUNK)) { clear_csr(mstatus, MSTATUS_MIE); _ssize += _abuf_write(&_eos_i2s_spk_buf, sample+i*I2S_ABUF_SIZE_CHUNK, ssize - _ssize); - _eos_i2s_spk_wr = 1; set_csr(mstatus, MSTATUS_MIE); } return _ssize; @@ -258,7 +255,6 @@ uint16_t eos_i2s_spk_write(uint8_t *sample, uint16_t ssize) { int eos_i2s_spk_push(uint8_t sample) { clear_csr(mstatus, MSTATUS_MIE); int ret = _abuf_push(&_eos_i2s_spk_buf, sample); - _eos_i2s_spk_wr = 1; set_csr(mstatus, MSTATUS_MIE); return ret; } diff --git a/code/fe310/eos/i2s.h b/code/fe310/eos/i2s.h index 6833948..7b267ec 100644 --- a/code/fe310/eos/i2s.h +++ b/code/fe310/eos/i2s.h @@ -7,7 +7,7 @@ typedef struct EOSABuf { uint8_t *array; } EOSABuf; -void eos_i2s_init(void); +void eos_i2s_init(uint32_t sample_rate); void eos_i2s_init_mic(uint8_t *mic_arr, uint16_t mic_arr_size, eos_evt_fptr_t mic_wm_handler, uint16_t mic_wm); void eos_i2s_init_spk(uint8_t *spk_arr, uint16_t spk_arr_size, eos_evt_fptr_t spk_wm_handler, uint16_t spk_wm); void eos_i2s_start(void); diff --git a/code/fe310/eos/i2s_def.h b/code/fe310/eos/i2s_def.h index 0f3207e..4a7fd85 100644 --- a/code/fe310/eos/i2s_def.h +++ b/code/fe310/eos/i2s_def.h @@ -15,15 +15,16 @@ #define I2S_IRQ_CI_ID (INT_PWM2_BASE + 2) #define I2S_IRQ_SD_PRIORITY 7 -#define I2S_IRQ_CK_PRIORITY 7 +#define I2S_IRQ_CK_PRIORITY 6 #define I2S_IRQ_WS_PRIORITY 6 -#define I2S_IRQ_CI_PRIORITY 6 +#define I2S_IRQ_CI_PRIORITY 7 #define I2S_IRQ_MASK 5 #define I2S_SMPL_BITS 13 #define I2S_SMPL_BITS_S 5 #define I2S_PWM_SCALE_CK 2 +#define I2S_PWM_SCALE_CK_MASK 0x0003 #define I2S_ABUF_SIZE_CHUNK 16 /* asm */ diff --git a/code/fe310/eos/trap_entry.S b/code/fe310/eos/trap_entry.S index 687493d..33f863b 100644 --- a/code/fe310/eos/trap_entry.S +++ b/code/fe310/eos/trap_entry.S @@ -170,19 +170,18 @@ i2s_handler_sd: la x18, sd_sample_mask sw x0, 0(x18) - # correct for missed bits + # correct for missing bits # la x18, sd_sample_save - # don't correct - # j 0f li x19, 0x80000000 srai x19, x19, I2S_SMPL_BITS_S-1 and x20, x20, x19 beq x19, x20, 0f - # drop missing - # bne x19, x20, i2s_handler_sd_exit + # 1. drop missing + # j i2s_handler_sd_exit + # 2. zero missing sample + # mv x8, x0 + # 3. put saved sample to missing # lw x8, 0(x18) - # zero missing frame - mv x8, x0 0: # sw x8, 0(x18) srai x8, x8, 32-I2S_SMPL_BITS @@ -225,28 +224,27 @@ i2s_handler_sd: lhu x20, I2S_ABUF_OFF_SIZE(x9) sub x18, x19, x18 - beq x18, x20, i2s_handler_sd_exit + beq x18, x20, 5f + + addi x19, x19, 1 + sh x19, I2S_ABUF_OFF_IDXW(x9) addi x20, x20, -1 and x20, x20, x19 - lw x18, I2S_ABUF_OFF_ARRAY(x9) - add x20, x20, x18 + lw x19, I2S_ABUF_OFF_ARRAY(x9) + add x20, x19, x20 + sb x8, 0(x20) + addi x18, x18, 1 - addi x19, x19, 1 - sh x19, I2S_ABUF_OFF_IDXW(x9) - +5: # check for push to event queue la x9, _eos_i2s_mic_wm lw x20, 0(x9) beqz x20, i2s_handler_sd_exit - - la x9, _eos_i2s_mic_buf - lhu x18, I2S_ABUF_OFF_IDXR(x9) - sub x18, x19, x18 bltu x18, x20, i2s_handler_sd_exit - la x9, _eos_i2s_mic_rd + la x9, _eos_i2s_evt_enable lw x18, 0(x9) beqz x18, i2s_handler_sd_exit sw x0, 0(x9) @@ -660,9 +658,9 @@ spi_handler_cts: sw x8, GPIO_RISE_IP(x19) la x20, _eos_spi_state_flags - lw x21, 0(x20) + lbu x21, 0(x20) ori x21, x21, SPI_FLAG_CTS - sw x21, 0(x20) + sb x21, 0(x20) andi x9, x21, SPI_FLAG_RDY beqz x9, 2f @@ -691,6 +689,10 @@ spi_handler_cts: j spi_handler_cts_exit 1: + andi x9, x21, SPI_FLAG_RTS + beqz x9, spi_handler_cts_exit + + # pop from spi buf queue la x9, _eos_spi_buf_q lbu x18, SPI_BUFQ_OFF_IDXR(x9) lbu x19, SPI_BUFQ_OFF_IDXW(x9) @@ -700,7 +702,7 @@ spi_handler_cts: slli x8, x8, 2 add x8, x9, x8 addi x18, x18, 1 - sb x18, SPI_BUFQ_OFF_IDXW(x9) + sb x18, SPI_BUFQ_OFF_IDXR(x9) mv x9, x0 lw x18, SPI_BUFQ_OFF_ARRAY(x8) mv x19, x0 |