summaryrefslogtreecommitdiff
path: root/fw/fe310/eos/soc/i2s.c
diff options
context:
space:
mode:
authorUros Majstorovic <majstor@majstor.org>2023-04-21 21:13:50 +0200
committerUros Majstorovic <majstor@majstor.org>2023-04-21 21:13:50 +0200
commita0059ab4365f41c84bb8bdf914477f5d4feeb985 (patch)
tree73baeb6706e44c8ccfe675fbf0001aa773af0a77 /fw/fe310/eos/soc/i2s.c
parent8c6001b298271bb52fa7142235ce7faa24b3e90e (diff)
improved i2s driver
Diffstat (limited to 'fw/fe310/eos/soc/i2s.c')
-rw-r--r--fw/fe310/eos/soc/i2s.c109
1 files changed, 67 insertions, 42 deletions
diff --git a/fw/fe310/eos/soc/i2s.c b/fw/fe310/eos/soc/i2s.c
index 8416ec1..052efa2 100644
--- a/fw/fe310/eos/soc/i2s.c
+++ b/fw/fe310/eos/soc/i2s.c
@@ -192,9 +192,6 @@ void eos_i2s_start(uint32_t sample_rate) {
I2S_REG_WS(PWM_COUNT) = 0;
I2S_REG_SR_SEL(PWM_COUNT) = 0;
- if (i2s_mic_handler) _eos_i2s_drvr[I2S_MIC_EVT] = 1;
- if (i2s_spk_handler) _eos_i2s_drvr[I2S_SPK_EVT] = 1;
-
eos_eve_intr_disable();
eos_uart_disable();
eos_intr_set_priority(I2S_IRQ_SD_ID, IRQ_PRIORITY_I2S_SD);
@@ -207,20 +204,11 @@ void eos_i2s_start(uint32_t sample_rate) {
iof_mask = I2S_PIN_PWM;
if (_eos_i2s_mic_buf.size == 0) {
iof_mask &= ~(1 << I2S_PIN_WS_MIC);
- GPIO_REG(GPIO_OUTPUT_VAL) &= ~(1 << I2S_PIN_WS_MIC);
- GPIO_REG(GPIO_OUTPUT_EN) |= (1 << I2S_PIN_WS_MIC);
- } else if (_eos_i2s_drvr[I2S_MIC_WM] == 0) {
- _eos_i2s_drvr[I2S_MIC_WM] = _eos_i2s_mic_buf.size / 2;
}
if (_eos_i2s_spk_buf.size == 0) {
iof_mask &= ~(1 << I2S_PIN_WS_SPK);
- GPIO_REG(GPIO_OUTPUT_VAL) &= ~(1 << I2S_PIN_SD_OUT);
- GPIO_REG(GPIO_OUTPUT_VAL) &= ~(1 << I2S_PIN_WS_SPK);
- GPIO_REG(GPIO_OUTPUT_EN) |= (1 << I2S_PIN_WS_SPK);
- } else if (_eos_i2s_drvr[I2S_SPK_WM] == 0) {
- _eos_i2s_drvr[I2S_SPK_WM] = _eos_i2s_spk_buf.size / 2;
}
- GPIO_REG(GPIO_IOF_SEL) |= iof_mask;
+ GPIO_REG(GPIO_IOF_SEL) |= I2S_PIN_PWM;
GPIO_REG(GPIO_IOF_EN) |= iof_mask;
_eos_i2s_start_pwm();
@@ -241,12 +229,6 @@ void eos_i2s_stop(void) {
eos_intr_disable(I2S_IRQ_SD_ID);
- if (!(GPIO_REG(GPIO_IOF_EN) & I2S_PIN_WS_MIC)) {
- GPIO_REG(GPIO_OUTPUT_EN) &= ~(1 << I2S_PIN_WS_MIC);
- }
- if (!(GPIO_REG(GPIO_IOF_EN) & I2S_PIN_WS_SPK)) {
- GPIO_REG(GPIO_OUTPUT_EN) &= ~(1 << I2S_PIN_WS_SPK);
- }
GPIO_REG(GPIO_FALL_IE) &= ~(1 << I2S_PIN_INT);
GPIO_REG(GPIO_INPUT_EN) &= ~(1 << I2S_PIN_INT);
GPIO_REG(GPIO_OUTPUT_VAL) |= (1 << I2S_PIN_SR_SEL);
@@ -279,22 +261,32 @@ void eos_i2s_set_mode(unsigned char mode) {
_eos_i2s_drvr[I2S_MODE] = mode;
}
-void eos_i2s_mic_init(uint8_t *mic_arr, uint16_t mic_arr_size) {
+void eos_i2s_mic_set_handler(eos_i2s_handler_t handler, uint16_t wm) {
clear_csr(mstatus, MSTATUS_MIE);
- _abuf_init(&_eos_i2s_mic_buf, mic_arr, mic_arr_size);
+ if ((i2s_mic_handler == NULL) && handler) _eos_i2s_drvr[I2S_MIC_EVT] = 1;
+ if (i2s_mic_handler && (handler == NULL)) _eos_i2s_drvr[I2S_MIC_EVT] = 0;
+ _eos_i2s_drvr[I2S_MIC_WM] = wm;
+ i2s_mic_handler = handler;
set_csr(mstatus, MSTATUS_MIE);
}
-void eos_i2s_mic_set_handler(eos_i2s_handler_t wm_handler) {
+void eos_i2s_mic_set_buf(uint8_t *mic_arr, uint16_t mic_arr_size) {
+ int run = eos_i2s_running();
+
clear_csr(mstatus, MSTATUS_MIE);
- i2s_mic_handler = wm_handler;
+ _abuf_init(&_eos_i2s_mic_buf, mic_arr, mic_arr_size);
+ if (run) {
+ if (mic_arr_size == 0) {
+ GPIO_REG(GPIO_IOF_EN) &= ~(1 << I2S_PIN_WS_MIC);
+ } else {
+ GPIO_REG(GPIO_IOF_EN) |= (1 << I2S_PIN_WS_MIC);
+ }
+ }
set_csr(mstatus, MSTATUS_MIE);
}
-void eos_i2s_mic_set_wm(uint16_t wm) {
- clear_csr(mstatus, MSTATUS_MIE);
- _eos_i2s_drvr[I2S_MIC_WM] = wm;
- set_csr(mstatus, MSTATUS_MIE);
+uint8_t *eos_i2s_mic_get_buf(void) {
+ return _eos_i2s_mic_buf.array;
}
uint16_t eos_i2s_mic_len(void) {
@@ -360,22 +352,32 @@ void eos_i2s_mic_set_vol(int vol) {
set_csr(mstatus, MSTATUS_MIE);
}
-void eos_i2s_spk_init(uint8_t *spk_arr, uint16_t spk_arr_size) {
+void eos_i2s_spk_set_handler(eos_i2s_handler_t handler, uint16_t wm) {
clear_csr(mstatus, MSTATUS_MIE);
- _abuf_init(&_eos_i2s_spk_buf, spk_arr, spk_arr_size);
+ if ((i2s_spk_handler == NULL) && handler) _eos_i2s_drvr[I2S_SPK_EVT] = 1;
+ if (i2s_spk_handler && (handler == NULL)) _eos_i2s_drvr[I2S_SPK_EVT] = 0;
+ _eos_i2s_drvr[I2S_SPK_WM] = wm;
+ i2s_spk_handler = handler;
set_csr(mstatus, MSTATUS_MIE);
}
-void eos_i2s_spk_set_handler(eos_i2s_handler_t wm_handler) {
+void eos_i2s_spk_set_buf(uint8_t *spk_arr, uint16_t spk_arr_size) {
+ int run = eos_i2s_running();
+
clear_csr(mstatus, MSTATUS_MIE);
- i2s_spk_handler = wm_handler;
+ _abuf_init(&_eos_i2s_spk_buf, spk_arr, spk_arr_size);
+ if (run) {
+ if (spk_arr_size == 0) {
+ GPIO_REG(GPIO_IOF_EN) &= ~(1 << I2S_PIN_WS_SPK);
+ } else {
+ GPIO_REG(GPIO_IOF_EN) |= (1 << I2S_PIN_WS_SPK);
+ }
+ }
set_csr(mstatus, MSTATUS_MIE);
}
-void eos_i2s_spk_set_wm(uint16_t wm) {
- clear_csr(mstatus, MSTATUS_MIE);
- _eos_i2s_drvr[I2S_SPK_WM] = wm;
- set_csr(mstatus, MSTATUS_MIE);
+uint8_t *eos_i2s_spk_get_buf(void) {
+ return _eos_i2s_spk_buf.array;
}
uint16_t eos_i2s_spk_len(void) {
@@ -388,23 +390,46 @@ uint16_t eos_i2s_spk_len(void) {
return ret;
}
-uint16_t eos_i2s_spk_write(uint8_t *sample, uint16_t ssize) {
+uint16_t eos_i2s_spk_write(uint8_t *sample, uint16_t ssize, uint8_t transform) {
uint16_t i;
- uint16_t _ssize = 0;
+ uint16_t abuf_free;
+ uint8_t transform_l, transform_r;
clear_csr(mstatus, MSTATUS_MIE);
- _ssize = MIN(ssize, _eos_i2s_spk_buf.size - _abuf_len(&_eos_i2s_spk_buf));
+ abuf_free = _eos_i2s_spk_buf.size - _abuf_len(&_eos_i2s_spk_buf);
+ if (transform) abuf_free = abuf_free / 2;
+ ssize = MIN(ssize, abuf_free);
set_csr(mstatus, MSTATUS_MIE);
- for (i=0; i<_ssize; i++) {
- _eos_i2s_spk_buf.array[EOS_ABUF_IDX_MASK(_eos_i2s_spk_buf.idx_w + i, _eos_i2s_spk_buf.size)] = sample[i];
+ transform_l = (transform == EOS_I2S_TRANS_MONO2D) || (transform == EOS_I2S_TRANS_MONO2L);
+ transform_r = (transform == EOS_I2S_TRANS_MONO2D) || (transform == EOS_I2S_TRANS_MONO2R);
+ if (transform) {
+ if (_eos_i2s_drvr[I2S_FMT] == EOS_I2S_FMT_PCM16) {
+ for (i=0; i<ssize / 2; i++) {
+ _eos_i2s_spk_buf.array[EOS_ABUF_IDX_MASK(_eos_i2s_spk_buf.idx_w + i * 4, _eos_i2s_spk_buf.size)] = transform_l ? sample[i * 2] : 0;
+ _eos_i2s_spk_buf.array[EOS_ABUF_IDX_MASK(_eos_i2s_spk_buf.idx_w + i * 4 + 2, _eos_i2s_spk_buf.size)] = transform_r ? sample[i * 2] : 0;
+ _eos_i2s_spk_buf.array[EOS_ABUF_IDX_MASK(_eos_i2s_spk_buf.idx_w + i * 4 + 1, _eos_i2s_spk_buf.size)] = transform_l ? sample[i * 2 + 1] : 0;
+ _eos_i2s_spk_buf.array[EOS_ABUF_IDX_MASK(_eos_i2s_spk_buf.idx_w + i * 4 + 3, _eos_i2s_spk_buf.size)] = transform_r ? sample[i * 2 + 1] : 0;
+ }
+ } else {
+ for (i=0; i<ssize; i++) {
+ _eos_i2s_spk_buf.array[EOS_ABUF_IDX_MASK(_eos_i2s_spk_buf.idx_w + i * 2, _eos_i2s_spk_buf.size)] = transform_l ? sample[i] : 0;
+ _eos_i2s_spk_buf.array[EOS_ABUF_IDX_MASK(_eos_i2s_spk_buf.idx_w + i * 2 + 1, _eos_i2s_spk_buf.size)] = transform_r ? sample[i] : 0;
+ }
+ }
+ } else {
+ for (i=0; i<ssize; i++) {
+ _eos_i2s_spk_buf.array[EOS_ABUF_IDX_MASK(_eos_i2s_spk_buf.idx_w + i, _eos_i2s_spk_buf.size)] = sample[i];
+ }
}
+ if (transform) ssize *= 2;
+
clear_csr(mstatus, MSTATUS_MIE);
- _eos_i2s_spk_buf.idx_w += _ssize;
+ _eos_i2s_spk_buf.idx_w += ssize;
set_csr(mstatus, MSTATUS_MIE);
- return _ssize;
+ return ssize;
}
int eos_i2s_spk_push8(uint8_t sample) {