summaryrefslogtreecommitdiff
path: root/fw/fe310/eos/soc/i2s.c
diff options
context:
space:
mode:
Diffstat (limited to 'fw/fe310/eos/soc/i2s.c')
-rw-r--r--fw/fe310/eos/soc/i2s.c355
1 files changed, 170 insertions, 185 deletions
diff --git a/fw/fe310/eos/soc/i2s.c b/fw/fe310/eos/soc/i2s.c
index bcce0b7..8bd5600 100644
--- a/fw/fe310/eos/soc/i2s.c
+++ b/fw/fe310/eos/soc/i2s.c
@@ -3,17 +3,19 @@
#include "encoding.h"
#include "platform.h"
+#include "board.h"
#include "prci_driver.h"
#include "eos.h"
+#include "log.h"
#include "event.h"
#include "interrupt.h"
-#include "board.h"
-
-#include "dev/eve.h"
-
#include "uart.h"
+#include "dev/egpio.h"
+#include "dev/egpio_priv.h"
+
+#include "dev/hpamp.h"
#include "i2s.h"
#include "i2s_priv.h"
@@ -32,80 +34,63 @@
static eos_i2s_handler_t i2s_mic_handler = NULL;
static eos_i2s_handler_t i2s_spk_handler = NULL;
static uint32_t i2s_clk_period;
-static uint8_t i2s_mic_volume = 0; /* 0 - 8 */
-static uint8_t i2s_spk_volume = 16; /* 0 - 16 */
+static uint8_t i2s_mic_volume = 0; /* 0 - 8 */
+static uint8_t i2s_spk_volume = 16; /* 0 - 16 */
EOSABuf _eos_i2s_mic_buf;
EOSABuf _eos_i2s_spk_buf;
uint32_t _eos_i2s_drvr[] = {
- EOS_I2S_FMT_PCM16, /* I2S_FMT */
- EOS_I2S_MODE_STEREO, /* I2S_MODE */
- 0, /* I2S_MIC_WM */
- 0, /* I2S_SPK_WM */
- 0, /* I2S_MIC_EVT */
- 0, /* I2S_SPK_EVT */
+ 0, /* I2S_MIC_WM */
+ 0, /* I2S_SPK_WM */
+ 0, /* I2S_MIC_EVT */
+ 0, /* I2S_SPK_EVT */
};
-#define I2S_FMT 0
-#define I2S_MODE 1
-#define I2S_MIC_WM 2
-#define I2S_SPK_WM 3
-#define I2S_MIC_EVT 4
-#define I2S_SPK_EVT 5
+#define I2S_MIC_WM 0
+#define I2S_SPK_WM 1
+#define I2S_MIC_EVT 2
+#define I2S_SPK_EVT 3
-static void _abuf_init(EOSABuf *buf, uint8_t *array, uint16_t size) {
+static void _abuf_init(EOSABuf *buf, uint16_t *array, uint16_t size) {
buf->idx_r = 0;
buf->idx_w = 0;
buf->size = size;
buf->array = array;
}
-static int _abuf_push8(EOSABuf *buf, uint8_t sample) {
- if ((uint16_t)(buf->idx_w - buf->idx_r) == buf->size) return EOS_ERR_FULL;
-
- buf->array[EOS_ABUF_IDX_MASK(buf->idx_w, buf->size)] = sample;
- buf->idx_w++;
- return EOS_OK;
+static void _abuf_flush(EOSABuf *buf) {
+ buf->idx_r = 0;
+ buf->idx_w = 0;
}
-static int _abuf_push16(EOSABuf *buf, uint16_t sample) {
- if ((uint16_t)(buf->idx_w - buf->idx_r) == buf->size) return EOS_ERR_FULL;
-
- buf->array[EOS_ABUF_IDX_MASK(buf->idx_w, buf->size)] = sample >> 8;
- buf->array[EOS_ABUF_IDX_MASK(buf->idx_w + 1, buf->size)] = sample & 0xFF;
- buf->idx_w += 2;
- return EOS_OK;
+static uint16_t _abuf_len(EOSABuf *buf) {
+ return (uint16_t)(buf->idx_w - buf->idx_r);
}
-static int _abuf_pop8(EOSABuf *buf, uint8_t *sample) {
- if (buf->idx_r == buf->idx_w) {
- return EOS_ERR_EMPTY;
- } else {
- *sample = buf->array[EOS_ABUF_IDX_MASK(buf->idx_r, buf->size)];
- buf->idx_r++;
- return EOS_OK;
- }
+static uint16_t _abuf_size(EOSABuf *buf) {
+ return buf->size;
}
-static int _abuf_pop16(EOSABuf *buf, uint16_t *sample) {
- if (buf->idx_r == buf->idx_w) {
- return EOS_ERR_EMPTY;
- } else {
- *sample = buf->array[EOS_ABUF_IDX_MASK(buf->idx_r, buf->size)] << 8;
- *sample |= buf->array[EOS_ABUF_IDX_MASK(buf->idx_r + 1, buf->size)];
- buf->idx_r += 2;
- return EOS_OK;
- }
-}
+/* mic buffer only */
+static int _mbuf_pop(uint16_t *sample) {
+ if (_eos_i2s_mic_buf.idx_r == _eos_i2s_mic_buf.idx_w) return EOS_ERR_EMPTY;
-static void _abuf_flush(EOSABuf *buf) {
- buf->idx_r = 0;
- buf->idx_w = 0;
+ *sample = _eos_i2s_mic_buf.array[EOS_ABUF_IDX_MASK(_eos_i2s_mic_buf.idx_r, _eos_i2s_mic_buf.size)];
+ _eos_i2s_mic_buf.idx_r += 1;
+ return EOS_OK;
}
-static uint16_t _abuf_len(EOSABuf *buf) {
- return buf->idx_w - buf->idx_r;
+/* spk buffer only */
+static int _sbuf_push(uint16_t sample) {
+ if ((uint16_t)(_eos_i2s_spk_buf.idx_w - _eos_i2s_spk_buf.idx_r) == _eos_i2s_spk_buf.size) return EOS_ERR_FULL;
+
+ if (_eos_i2s_spk_buf.idx_r != _eos_i2s_spk_buf.idx_w) {
+ _eos_i2s_spk_buf.array[EOS_ABUF_IDX_MASK(_eos_i2s_spk_buf.idx_w - 1, _eos_i2s_spk_buf.size)] |= sample >> 15;
+ }
+ _eos_i2s_spk_buf.array[EOS_ABUF_IDX_MASK(_eos_i2s_spk_buf.idx_w, _eos_i2s_spk_buf.size)] = sample << 1;
+ _eos_i2s_spk_buf.idx_w += 1;
+ return EOS_OK;
}
static void i2s_handle_evt(unsigned char type, unsigned char *buffer, uint16_t len) {
@@ -135,7 +120,9 @@ static void i2s_handle_evt(unsigned char type, unsigned char *buffer, uint16_t l
}
static void i2s_set_cmp(void) {
- int spk_ws_offset = i2s_spk_volume - 16 + i2s_mic_volume;
+ int spk_ws_offset;
+
+ spk_ws_offset = i2s_spk_volume - 16 + i2s_mic_volume;
/* adjust spk ws relative to mic ws */
if (spk_ws_offset <= 0) {
@@ -147,36 +134,50 @@ static void i2s_set_cmp(void) {
I2S_REG_WS(PWM_CMP2) = spk_ws_offset * i2s_clk_period - i2s_clk_period / 2;
I2S_REG_WS(PWM_CMP3) = (32 + spk_ws_offset) * i2s_clk_period - i2s_clk_period / 2;
- I2S_REG_SR_SEL(PWM_CMP1) = (1 + i2s_mic_volume) * i2s_clk_period;
- I2S_REG_SR_SEL(PWM_CMP2) = (17 + i2s_mic_volume) * i2s_clk_period - (i2s_clk_period / 4);
+ I2S_REG_SR_SEL(PWM_CMP1) = (1 + i2s_mic_volume) * i2s_clk_period + i2s_clk_period / 4;
+ I2S_REG_SR_SEL(PWM_CMP2) = (17 + i2s_mic_volume) * i2s_clk_period - i2s_clk_period / 4;
}
-extern void _eos_i2s_start_pwm(void);
+extern void _eos_i2s_start_pwm(unsigned int);
-int eos_i2s_init(uint8_t wakeup_cause) {
+int eos_i2s_init(void) {
eos_evtq_set_handler(EOS_EVT_I2S, i2s_handle_evt);
I2S_REG_CK(PWM_CFG) = 0;
I2S_REG_WS(PWM_CFG) = 0;
I2S_REG_SR_SEL(PWM_CFG) = 0;
+ clear_csr(mstatus, MSTATUS_MIE);
GPIO_REG(GPIO_OUTPUT_VAL) |= (1 << I2S_PIN_SR_SEL);
GPIO_REG(GPIO_OUTPUT_VAL) &= ~(1 << I2S_PIN_SR_CK);
+ GPIO_REG(GPIO_OUTPUT_VAL) &= ~(1 << I2S_PIN_SD_OUT);
+ set_csr(mstatus, MSTATUS_MIE);
GPIO_REG(GPIO_OUTPUT_EN) |= (1 << I2S_PIN_SR_SEL);
GPIO_REG(GPIO_OUTPUT_EN) |= (1 << I2S_PIN_SR_CK);
GPIO_REG(GPIO_INPUT_EN) |= (1 << I2S_PIN_SD_IN);
+ GPIO_REG(GPIO_INPUT_EN) |= (1 << I2S_PIN_SD_OUT);
+ GPIO_REG(GPIO_INPUT_EN) |= (1 << I2S_PIN_INT);
return EOS_OK;
}
-void eos_i2s_start(uint32_t sample_rate) {
- uint32_t iof_mask;
+int eos_i2s_start(uint32_t sample_rate, int mode) {
+ unsigned int scale_ck;
+ int rv;
+
i2s_clk_period = PRCI_get_cpu_freq() / (sample_rate * 64);
- i2s_clk_period = (i2s_clk_period & ~I2S_PWM_SCALE_CK_MASK) + 1;
+ i2s_clk_period &= ~0x01; /* clear last bit */
- I2S_REG_CK(PWM_CMP0) = i2s_clk_period >> I2S_PWM_SCALE_CK;
+ /* if half of clock period does not fit in 8 bits we need to scale clock */
+ scale_ck = 0;
+ if ((i2s_clk_period >> 1) & ~0xFF) {
+ scale_ck = 1;
+ i2s_clk_period &= ~0x03; /* clear last two bits */
+ }
+
+ I2S_REG_CK(PWM_CMP0) = i2s_clk_period >> (1 + scale_ck); /* master clock: double bit clock frequency */
I2S_REG_CK(PWM_CMP1) = I2S_REG_CK(PWM_CMP0) / 2;
I2S_REG_CK(PWM_CMP2) = 0;
I2S_REG_CK(PWM_CMP3) = 0;
@@ -184,42 +185,64 @@ void eos_i2s_start(uint32_t sample_rate) {
I2S_REG_WS(PWM_CMP0) = i2s_clk_period * 64 - 1;
I2S_REG_WS(PWM_CMP1) = i2s_clk_period * 32;
- I2S_REG_SR_SEL(PWM_CMP0) = i2s_clk_period * 32 - 1;
+ if (mode == EOS_I2S_MODE_STEREO) {
+ I2S_REG_SR_SEL(PWM_CMP0) = i2s_clk_period * 32 - 1;
+ } else {
+ I2S_REG_SR_SEL(PWM_CMP0) = i2s_clk_period * 64 - 1;
+ }
I2S_REG_SR_SEL(PWM_CMP3) = 0;
i2s_set_cmp();
- I2S_REG_CK(PWM_COUNT) = 0;
+ I2S_REG_CK(PWM_COUNT) = I2S_REG_CK(PWM_CMP1); /* master clock starts high */
I2S_REG_WS(PWM_COUNT) = 0;
- I2S_REG_SR_SEL(PWM_COUNT) = 0;
+ if (mode == EOS_I2S_MODE_MONO_R) {
+ I2S_REG_SR_SEL(PWM_COUNT) = i2s_clk_period * 32;
+ } else {
+ I2S_REG_SR_SEL(PWM_COUNT) = 0;
+ }
- eos_eve_intr_disable();
eos_uart_disable();
+ rv = eos_egpio_i2s_start();
+ if (rv) {
+ eos_i2s_stop();
+ return rv;
+ }
+
+ GPIO_REG(GPIO_IOF_SEL) |= I2S_PIN_PWM;
+ GPIO_REG(GPIO_IOF_EN) |= I2S_PIN_PWM;
- GPIO_REG(GPIO_INPUT_EN) |= (1 << I2S_PIN_INT);
GPIO_REG(GPIO_FALL_IE) |= (1 << I2S_PIN_INT);
+ clear_csr(mstatus, MSTATUS_MIE);
GPIO_REG(GPIO_OUTPUT_VAL) |= (1 << I2S_PIN_SR_CK);
+ set_csr(mstatus, MSTATUS_MIE);
- iof_mask = I2S_PIN_PWM;
- if (_eos_i2s_mic_buf.size == 0) {
- iof_mask &= ~(1 << I2S_PIN_WS_MIC);
- }
- if (_eos_i2s_spk_buf.size == 0) {
- iof_mask &= ~(1 << I2S_PIN_WS_SPK);
+ /* XXX should set stereo pin to 1 !!! */
+
+ eos_intr_set_priority(I2S_IRQ_ID, IRQ_PRIORITY_I2S);
+ eos_intr_enable(I2S_IRQ_ID);
+
+ /* initialise headphones if present */
+ if (!eos_egpio_get_val(EGPIO_PIN_HP_NDET)) {
+ rv = eos_hpamp_init();
+ if (rv) {
+ eos_i2s_stop();
+ return rv;
+ }
}
- GPIO_REG(GPIO_IOF_SEL) |= I2S_PIN_PWM;
- GPIO_REG(GPIO_IOF_EN) |= iof_mask;
- eos_intr_set_priority(I2S_IRQ_SD_ID, IRQ_PRIORITY_I2S_SD);
- eos_intr_enable(I2S_IRQ_SD_ID);
- _eos_i2s_start_pwm();
+ clear_csr(mstatus, MSTATUS_MIE);
+ _eos_i2s_start_pwm(scale_ck);
+ set_csr(mstatus, MSTATUS_MIE);
/*
- I2S_REG_CK(PWM_CFG) = PWM_CFG_ENALWAYS | PWM_CFG_ZEROCMP | I2S_PWM_SCALE_CK;
+ I2S_REG_CK(PWM_CFG) = PWM_CFG_ENALWAYS | PWM_CFG_ZEROCMP | scale_ck;
I2S_REG_WS(PWM_CFG) = PWM_CFG_ENALWAYS | PWM_CFG_ZEROCMP | PWM_CFG_CMP2GANG;
I2S_REG_SR_SEL(PWM_CFG) = PWM_CFG_ENALWAYS | PWM_CFG_ZEROCMP | PWM_CFG_CMP1GANG;
*/
}
void eos_i2s_stop(void) {
+ int rv;
+
I2S_REG_CK(PWM_CFG) = 0;
I2S_REG_WS(PWM_CFG) = 0;
I2S_REG_SR_SEL(PWM_CFG) = 0;
@@ -227,17 +250,18 @@ void eos_i2s_stop(void) {
I2S_REG_WS(PWM_COUNT) = 0;
I2S_REG_SR_SEL(PWM_COUNT) = 0;
- eos_intr_disable(I2S_IRQ_SD_ID);
+ eos_intr_disable(I2S_IRQ_ID);
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);
+ clear_csr(mstatus, MSTATUS_MIE);
GPIO_REG(GPIO_OUTPUT_VAL) &= ~(1 << I2S_PIN_SR_CK);
+ set_csr(mstatus, MSTATUS_MIE);
GPIO_REG(GPIO_OUTPUT_XOR) &= ~(1 << I2S_PIN_WS_SPK);
GPIO_REG(GPIO_IOF_EN) &= ~I2S_PIN_PWM;
eos_uart_enable();
- eos_eve_intr_enable();
+ rv = eos_egpio_i2s_stop();
+ if (rv) EOS_LOG(EOS_LOG_ERR, "I2S STOP: EGPIO ERR:%d\n", rv);
_eos_i2s_drvr[I2S_MIC_EVT] = 0;
_eos_i2s_drvr[I2S_SPK_EVT] = 0;
@@ -253,12 +277,8 @@ int eos_i2s_running(void) {
return !!(GPIO_REG(GPIO_IOF_EN) & (1 << I2S_PIN_CK));
}
-void eos_i2s_set_fmt(unsigned char fmt) {
- _eos_i2s_drvr[I2S_FMT] = fmt;
-}
-
-void eos_i2s_set_mode(unsigned char mode) {
- _eos_i2s_drvr[I2S_MODE] = mode;
+int eos_i2s_set_lsgain(int gain) {
+ return eos_egpio_set_val(EGPIO_PIN_LSGAIN_SEL, gain);
}
void eos_i2s_mic_set_handler(eos_i2s_handler_t handler, uint16_t wm) {
@@ -270,72 +290,55 @@ void eos_i2s_mic_set_handler(eos_i2s_handler_t handler, uint16_t wm) {
set_csr(mstatus, MSTATUS_MIE);
}
-void eos_i2s_mic_set_buf(uint8_t *mic_arr, uint16_t mic_arr_size) {
- int run = eos_i2s_running();
-
+void eos_i2s_mic_set_buf(uint16_t *mic_arr, uint16_t mic_arr_size) {
clear_csr(mstatus, MSTATUS_MIE);
_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);
}
-uint8_t *eos_i2s_mic_get_buf(void) {
+uint16_t *eos_i2s_mic_get_buf(void) {
return _eos_i2s_mic_buf.array;
}
uint16_t eos_i2s_mic_len(void) {
- uint16_t ret;
+ uint16_t rv;
clear_csr(mstatus, MSTATUS_MIE);
- ret = _abuf_len(&_eos_i2s_mic_buf);
+ rv = _abuf_len(&_eos_i2s_mic_buf);
set_csr(mstatus, MSTATUS_MIE);
- return ret;
+ return rv;
}
-uint16_t eos_i2s_mic_read(uint8_t *sample, uint16_t ssize) {
- uint16_t i;
- uint16_t _ssize = 0;
+uint16_t eos_i2s_mic_read(uint16_t *smpl_buf, uint16_t buf_size) {
+ int i;
+ uint16_t smpl_len;
clear_csr(mstatus, MSTATUS_MIE);
- _ssize = MIN(ssize, _abuf_len(&_eos_i2s_mic_buf));
+ smpl_len = MIN(buf_size, _abuf_len(&_eos_i2s_mic_buf));
set_csr(mstatus, MSTATUS_MIE);
- for (i=0; i<_ssize; i++) {
- sample[i] = _eos_i2s_mic_buf.array[EOS_ABUF_IDX_MASK(_eos_i2s_mic_buf.idx_r + i, _eos_i2s_mic_buf.size)];
- }
-
- clear_csr(mstatus, MSTATUS_MIE);
- _eos_i2s_mic_buf.idx_r += _ssize;
- set_csr(mstatus, MSTATUS_MIE);
-
- return _ssize;
-}
+ if (smpl_len == 0) return 0;
-int eos_i2s_mic_pop8(uint8_t *sample) {
- int ret;
+ for (i=0; i<smpl_len; i++) {
+ smpl_buf[i] = _eos_i2s_mic_buf.array[EOS_ABUF_IDX_MASK(_eos_i2s_mic_buf.idx_r + i, _eos_i2s_mic_buf.size)];
+ }
clear_csr(mstatus, MSTATUS_MIE);
- ret = _abuf_pop8(&_eos_i2s_mic_buf, sample);
+ _eos_i2s_mic_buf.idx_r += smpl_len;
set_csr(mstatus, MSTATUS_MIE);
- return ret;
+ return smpl_len;
}
-int eos_i2s_mic_pop16(uint16_t *sample) {
- int ret;
+int eos_i2s_mic_pop(uint16_t *sample) {
+ int rv;
clear_csr(mstatus, MSTATUS_MIE);
- ret = _abuf_pop16(&_eos_i2s_mic_buf, sample);
+ rv = _mbuf_pop(sample);
set_csr(mstatus, MSTATUS_MIE);
- return ret;
+ return rv;
}
int eos_i2s_mic_get_vol(void) {
@@ -361,95 +364,65 @@ void eos_i2s_spk_set_handler(eos_i2s_handler_t handler, uint16_t wm) {
set_csr(mstatus, MSTATUS_MIE);
}
-void eos_i2s_spk_set_buf(uint8_t *spk_arr, uint16_t spk_arr_size) {
- int run = eos_i2s_running();
-
+void eos_i2s_spk_set_buf(uint16_t *spk_arr, uint16_t spk_arr_size) {
clear_csr(mstatus, MSTATUS_MIE);
_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);
}
-uint8_t *eos_i2s_spk_get_buf(void) {
+uint16_t *eos_i2s_spk_get_buf(void) {
return _eos_i2s_spk_buf.array;
}
uint16_t eos_i2s_spk_len(void) {
- uint16_t ret;
+ uint16_t rv;
clear_csr(mstatus, MSTATUS_MIE);
- ret = _abuf_len(&_eos_i2s_spk_buf);
+ rv = _abuf_len(&_eos_i2s_spk_buf);
set_csr(mstatus, MSTATUS_MIE);
- return ret;
+ return rv;
}
-uint16_t eos_i2s_spk_write(uint8_t *sample, uint16_t ssize, uint8_t transform) {
- uint16_t i;
- uint16_t abuf_free;
- uint8_t transform_l, transform_r;
+uint16_t eos_i2s_spk_write(uint16_t *smpl_buf, uint16_t buf_len) {
+ int i;
+ uint16_t sample;
+ uint16_t abuf_size, abuf_len, smpl_len;
clear_csr(mstatus, MSTATUS_MIE);
- 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);
-
- 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];
- }
+ abuf_size = _abuf_size(&_eos_i2s_spk_buf);
+ abuf_len = _abuf_len(&_eos_i2s_spk_buf);
+ smpl_len = MIN(buf_len, abuf_size - abuf_len);
+ if (smpl_len && abuf_len) {
+ _eos_i2s_spk_buf.array[EOS_ABUF_IDX_MASK(_eos_i2s_spk_buf.idx_w - 1, _eos_i2s_spk_buf.size)] |= smpl_buf[0] >> 15;
}
-
- if (transform) ssize *= 2;
-
- clear_csr(mstatus, MSTATUS_MIE);
- _eos_i2s_spk_buf.idx_w += ssize;
set_csr(mstatus, MSTATUS_MIE);
- return ssize;
-}
+ if (smpl_len == 0) return 0;
-int eos_i2s_spk_push8(uint8_t sample) {
- int ret;
+ for (i=0; i<smpl_len; i++) {
+ sample = smpl_buf[i] << 1;
+ if (i + 1 < smpl_len) {
+ sample |= (smpl_buf[i + 1] >> 15);
+ }
+ _eos_i2s_spk_buf.array[EOS_ABUF_IDX_MASK(_eos_i2s_spk_buf.idx_w + i, _eos_i2s_spk_buf.size)] = sample;
+ }
clear_csr(mstatus, MSTATUS_MIE);
- ret = _abuf_push8(&_eos_i2s_spk_buf, sample);
+ _eos_i2s_spk_buf.idx_w += smpl_len;
set_csr(mstatus, MSTATUS_MIE);
- return ret;
+ return smpl_len;
}
-int eos_i2s_spk_push16(uint16_t sample) {
- int ret;
+int eos_i2s_spk_push(uint16_t sample) {
+ int rv;
clear_csr(mstatus, MSTATUS_MIE);
- ret = _abuf_push16(&_eos_i2s_spk_buf, sample);
+ rv = _sbuf_push(sample);
set_csr(mstatus, MSTATUS_MIE);
- return ret;
+ return rv;
}
int eos_i2s_spk_get_vol(void) {
@@ -465,3 +438,15 @@ void eos_i2s_spk_set_vol(int vol) {
i2s_set_cmp();
set_csr(mstatus, MSTATUS_MIE);
}
+
+void eos_i2s_hp_change(int hp_det) {
+ if (hp_det) {
+ int rv;
+
+ rv = eos_hpamp_init();
+ if (rv) {
+ EOS_LOG(EOS_LOG_ERR, "I2S HP CHANGE: PCM1770 INIT ERR:%d\n", rv);
+ return;
+ }
+ }
+}