summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--code/fe310/eos/i2s.c34
-rw-r--r--code/fe310/eos/i2s.h2
-rw-r--r--code/fe310/eos/i2s_def.h5
-rw-r--r--code/fe310/eos/trap_entry.S44
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