diff options
author | Uros Majstorovic <majstor@majstor.org> | 2022-08-09 22:23:08 +0200 |
---|---|---|
committer | Uros Majstorovic <majstor@majstor.org> | 2022-08-09 22:23:08 +0200 |
commit | 3f913efda03fd840cd526ef72e6f397c7da61bd7 (patch) | |
tree | 08f62c93e0e0660fdb7beba32276ff1ceb7a8a3c /fw/fe310/eos/soc/i2s.c | |
parent | 810dde21ee65653c15606917b19566cfbaaf165e (diff) |
code layout
Diffstat (limited to 'fw/fe310/eos/soc/i2s.c')
-rw-r--r-- | fw/fe310/eos/soc/i2s.c | 217 |
1 files changed, 66 insertions, 151 deletions
diff --git a/fw/fe310/eos/soc/i2s.c b/fw/fe310/eos/soc/i2s.c index 9cc9d9c..5e5eaa7 100644 --- a/fw/fe310/eos/soc/i2s.c +++ b/fw/fe310/eos/soc/i2s.c @@ -25,41 +25,20 @@ #define EOS_ABUF_IDX_MASK(IDX, SIZE) ((IDX) & ((SIZE) - 1)) -EOSABuf i2s_mic_buf; -EOSABuf i2s_spk_buf; +EOSABuf _eos_i2s_mic_buf; +EOSABuf _eos_i2s_spk_buf; +uint32_t _eos_i2s_fmt = 0; +uint32_t _eos_i2s_mic_wm = 0; +uint32_t _eos_i2s_spk_wm = 0; +uint32_t _eos_i2s_mic_evt_enable = 0; +uint32_t _eos_i2s_spk_evt_enable = 0; -static eos_i2s_handler_t i2s_mic_handler = NULL; static eos_i2s_handler_t i2s_spk_handler = NULL; +static eos_i2s_handler_t i2s_mic_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 */ -uint32_t _eos_i2s_drvr[] = { - 0, /* I2S_MIC_BUF */ - 0, /* I2S_SPK_BUF */ - 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_CMP2 */ - 0, /* I2S_MIC_CMP3 */ - 0, /* I2S_SAMPLE */ -}; - -#define I2S_MIC_BUF 0 -#define I2S_SPK_BUF 1 -#define I2S_FMT 2 -#define I2S_MODE 3 -#define I2S_MIC_WM 4 -#define I2S_SPK_WM 5 -#define I2S_MIC_EVT 6 -#define I2S_SPK_EVT 7 -#define I2S_MIC_CMP2 8 -#define I2S_MIC_CMP3 9 -#define I2S_SAMPLE 10 - static void _abuf_init(EOSABuf *buf, uint8_t *array, uint16_t size) { buf->idx_r = 0; buf->idx_w = 0; @@ -105,6 +84,7 @@ static int _abuf_pop16(EOSABuf *buf, uint16_t *sample) { } } + static void _abuf_flush(EOSABuf *buf) { buf->idx_r = 0; buf->idx_w = 0; @@ -117,63 +97,42 @@ static uint16_t _abuf_len(EOSABuf *buf) { static void i2s_handle_evt(unsigned char type, unsigned char *buffer, uint16_t len) { switch(type & ~EOS_EVT_MASK) { case EOS_I2S_ETYPE_MIC: - if (i2s_mic_handler) { - i2s_mic_handler(type); - clear_csr(mstatus, MSTATUS_MIE); - _eos_i2s_drvr[I2S_MIC_EVT] = 1; - set_csr(mstatus, MSTATUS_MIE); - } + if (i2s_mic_handler) i2s_mic_handler(type); + clear_csr(mstatus, MSTATUS_MIE); + _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_drvr[I2S_SPK_EVT] = 1; - set_csr(mstatus, MSTATUS_MIE); - } + 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; } } -#define PLIC_PRIORITY 0x0C000000 - -static void i2s_cmp_set(void) { - int c = 7; /* interrupt will trigger c i2s clocks before spk ws */ - int spk_ws_offset = i2s_spk_volume - 16 + i2s_mic_volume; - volatile uint32_t *p = (uint32_t *)PLIC_PRIORITY+I2S_IRQ_SD_ID; - - /* interrupt trigger - will start with left channel */ - if (spk_ws_offset - c < 0) { - I2S_REG_WS_SPK(PWM_CMP3) = i2s_clk_period * (64 + spk_ws_offset - c); - } else { - I2S_REG_WS_SPK(PWM_CMP3) = i2s_clk_period * (spk_ws_offset - c); - } - - /* disable interrupt for this cycle */ - *p = 0; +static void _mic_vol_set(uint8_t vol) { + I2S_REG_WS_MIC(PWM_CMP2) = i2s_clk_period * (vol + 1); + I2S_REG_WS_MIC(PWM_CMP3) = I2S_REG_WS_MIC(PWM_CMP2) + i2s_clk_period * 16; +} - /* empty buffers */ - // i2s_mic_buf.idx_r = i2s_mic_buf.idx_w; - // i2s_spk_buf.idx_w = i2s_spk_buf.idx_r; +static void _spk_vol_set(uint8_t vol) { + int spk_cmp = vol + i2s_mic_volume - 16; - /* adjust spk ws relative to mic ws */ - if (spk_ws_offset <= 0) { - spk_ws_offset += 32; + 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 { - GPIO_REG(GPIO_OUTPUT_XOR) |= (1 << I2S_PIN_WS_SPK); + 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); } - I2S_REG_WS_SPK(PWM_CMP1) = i2s_clk_period * spk_ws_offset; - I2S_REG_WS_SPK(PWM_CMP2) = i2s_clk_period * (32 + spk_ws_offset); - - /* mic cmp2 relative to interrupt trigger */ - _eos_i2s_drvr[I2S_MIC_CMP2] = (17 + c - i2s_spk_volume) * i2s_clk_period; /* (17 + c - i2s_spk_volume) == (1 + i2s_mic_volume) - (spk_ws_offset - c) */ - _eos_i2s_drvr[I2S_MIC_CMP3] = 16 * i2s_clk_period; } extern void _eos_i2s_start_pwm(void); @@ -181,10 +140,6 @@ 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); @@ -218,7 +173,7 @@ void eos_i2s_init_mux(void) { GPIO_REG(GPIO_OUTPUT_EN) &= ~(1 << I2S_PIN_SD_OUT); } -void eos_i2s_start(uint32_t sample_rate) { +void eos_i2s_start(uint32_t sample_rate, unsigned char fmt) { i2s_clk_period = ((PRCI_get_cpu_freq() / (sample_rate * 64)) & ~I2S_PWM_SCALE_CK_MASK) + 1; GPIO_REG(GPIO_INPUT_EN) |= (1 << I2S_PIN_SD_IN); @@ -234,33 +189,23 @@ void eos_i2s_start(uint32_t sample_rate) { I2S_REG_WS_MIC(PWM_CMP0) = i2s_clk_period * 64 - 1; I2S_REG_WS_MIC(PWM_CMP1) = i2s_clk_period * 32; + _mic_vol_set(i2s_mic_volume); I2S_REG_WS_SPK(PWM_CMP0) = i2s_clk_period * 64 - 1; - i2s_cmp_set(); + _spk_vol_set(i2s_spk_volume); I2S_REG_CK(PWM_COUNT) = 0; I2S_REG_WS_MIC(PWM_COUNT) = 0; I2S_REG_WS_SPK(PWM_COUNT) = i2s_clk_period / 2; - if (i2s_mic_buf.array && i2s_mic_buf.size) { - _eos_i2s_drvr[I2S_MIC_BUF] = (uint32_t)&i2s_mic_buf; - if (_eos_i2s_drvr[I2S_MIC_WM] == 0) { - _eos_i2s_drvr[I2S_MIC_WM] = i2s_mic_buf.size / 2; - } - } - if (i2s_spk_buf.array && i2s_spk_buf.size) { - _eos_i2s_drvr[I2S_SPK_BUF] = (uint32_t)&i2s_spk_buf; - if (_eos_i2s_drvr[I2S_SPK_WM] == 0) { - _eos_i2s_drvr[I2S_SPK_WM] = i2s_spk_buf.size / 2; - } - } - if (i2s_mic_handler) _eos_i2s_drvr[I2S_MIC_EVT] = 1; - if (i2s_spk_handler) _eos_i2s_drvr[I2S_SPK_EVT] = 1; + _eos_i2s_fmt = 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_enable(I2S_IRQ_SD_ID); + eos_intr_set_priority(I2S_IRQ_SD_ID, 0); eos_intr_enable(I2S_IRQ_WS_ID); + eos_intr_enable(I2S_IRQ_SD_ID); _eos_i2s_start_pwm(); /* @@ -269,13 +214,9 @@ void eos_i2s_start(uint32_t sample_rate) { I2S_REG_WS_SPK(PWM_CFG) = PWM_CFG_ENALWAYS | PWM_CFG_ZEROCMP | PWM_CFG_CMP1GANG; */ - 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; + 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) { @@ -286,14 +227,10 @@ void eos_i2s_stop(void) { I2S_REG_WS_MIC(PWM_COUNT) = 0; I2S_REG_WS_SPK(PWM_COUNT) = 0; - _eos_i2s_drvr[I2S_MIC_BUF] = 0; - _eos_i2s_drvr[I2S_MIC_EVT] = 0; - _eos_i2s_drvr[I2S_MIC_WM] = 0; - - _eos_i2s_drvr[I2S_SPK_BUF] = 0; - _eos_i2s_drvr[I2S_SPK_EVT] = 0; - _eos_i2s_drvr[I2S_SPK_WM] = 0; - + _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); @@ -302,26 +239,15 @@ 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) & (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; + return !!(GPIO_REG(GPIO_IOF_EN) & I2S_PIN_PWM); } void eos_i2s_mic_init(uint8_t *mic_arr, uint16_t mic_arr_size) { clear_csr(mstatus, MSTATUS_MIE); - _abuf_init(&i2s_mic_buf, mic_arr, mic_arr_size); + _abuf_init(&_eos_i2s_mic_buf, mic_arr, mic_arr_size); set_csr(mstatus, MSTATUS_MIE); } @@ -333,14 +259,14 @@ void eos_i2s_mic_set_handler(eos_i2s_handler_t wm_handler) { void eos_i2s_mic_set_wm(uint16_t wm) { clear_csr(mstatus, MSTATUS_MIE); - _eos_i2s_drvr[I2S_MIC_WM] = wm; + _eos_i2s_mic_wm = wm; set_csr(mstatus, MSTATUS_MIE); } uint16_t eos_i2s_mic_len(void) { clear_csr(mstatus, MSTATUS_MIE); - uint16_t ret = _abuf_len(&i2s_mic_buf); + uint16_t ret = _abuf_len(&_eos_i2s_mic_buf); set_csr(mstatus, MSTATUS_MIE); return ret; } @@ -350,37 +276,31 @@ uint16_t eos_i2s_mic_read(uint8_t *sample, uint16_t ssize) { uint16_t _ssize = 0; clear_csr(mstatus, MSTATUS_MIE); - _ssize = MIN(ssize, _abuf_len(&i2s_mic_buf)); + _ssize = MIN(ssize, _abuf_len(&_eos_i2s_mic_buf)); set_csr(mstatus, MSTATUS_MIE); for (i=0; i<_ssize; i++) { - sample[i] = i2s_mic_buf.array[EOS_ABUF_IDX_MASK(i2s_mic_buf.idx_r + i, i2s_mic_buf.size)]; + 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); - i2s_mic_buf.idx_r += _ssize; + _eos_i2s_mic_buf.idx_r += _ssize; set_csr(mstatus, MSTATUS_MIE); return _ssize; } int eos_i2s_mic_pop8(uint8_t *sample) { - int ret; - clear_csr(mstatus, MSTATUS_MIE); - ret = _abuf_pop8(&i2s_mic_buf, sample); + int 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); - ret = _abuf_pop16(&i2s_mic_buf, sample); + int ret = _abuf_pop16(&_eos_i2s_mic_buf, sample); set_csr(mstatus, MSTATUS_MIE); - return ret; } @@ -394,13 +314,14 @@ void eos_i2s_mic_vol_set(int vol) { i2s_mic_volume = vol; clear_csr(mstatus, MSTATUS_MIE); - i2s_cmp_set(); + _mic_vol_set(vol); + _spk_vol_set(i2s_spk_volume); set_csr(mstatus, MSTATUS_MIE); } void eos_i2s_spk_init(uint8_t *spk_arr, uint16_t spk_arr_size) { clear_csr(mstatus, MSTATUS_MIE); - _abuf_init(&i2s_spk_buf, spk_arr, spk_arr_size); + _abuf_init(&_eos_i2s_spk_buf, spk_arr, spk_arr_size); set_csr(mstatus, MSTATUS_MIE); } @@ -412,13 +333,13 @@ void eos_i2s_spk_set_handler(eos_i2s_handler_t wm_handler) { void eos_i2s_spk_set_wm(uint16_t wm) { clear_csr(mstatus, MSTATUS_MIE); - _eos_i2s_drvr[I2S_SPK_WM] = wm; + _eos_i2s_spk_wm = wm; set_csr(mstatus, MSTATUS_MIE); } uint16_t eos_i2s_spk_len(void) { clear_csr(mstatus, MSTATUS_MIE); - uint16_t ret = _abuf_len(&i2s_spk_buf); + uint16_t ret = _abuf_len(&_eos_i2s_spk_buf); set_csr(mstatus, MSTATUS_MIE); return ret; } @@ -428,37 +349,31 @@ uint16_t eos_i2s_spk_write(uint8_t *sample, uint16_t ssize) { uint16_t _ssize = 0; clear_csr(mstatus, MSTATUS_MIE); - _ssize = MIN(ssize, i2s_spk_buf.size - _abuf_len(&i2s_spk_buf)); + _ssize = MIN(ssize, _eos_i2s_spk_buf.size - _abuf_len(&_eos_i2s_spk_buf)); set_csr(mstatus, MSTATUS_MIE); for (i=0; i<_ssize; i++) { - i2s_spk_buf.array[EOS_ABUF_IDX_MASK(i2s_spk_buf.idx_w + i, i2s_spk_buf.size)] = sample[i]; + _eos_i2s_spk_buf.array[EOS_ABUF_IDX_MASK(_eos_i2s_spk_buf.idx_w + i, _eos_i2s_spk_buf.size)] = sample[i]; } clear_csr(mstatus, MSTATUS_MIE); - i2s_spk_buf.idx_w += _ssize; + _eos_i2s_spk_buf.idx_w += _ssize; set_csr(mstatus, MSTATUS_MIE); return _ssize; } int eos_i2s_spk_push8(uint8_t sample) { - int ret; - clear_csr(mstatus, MSTATUS_MIE); - ret = _abuf_push8(&i2s_spk_buf, sample); + int 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); - ret = _abuf_push16(&i2s_spk_buf, sample); + int ret = _abuf_push16(&_eos_i2s_spk_buf, sample); set_csr(mstatus, MSTATUS_MIE); - return ret; } @@ -472,6 +387,6 @@ void eos_i2s_spk_vol_set(int vol) { i2s_spk_volume = vol; clear_csr(mstatus, MSTATUS_MIE); - i2s_cmp_set(); + _spk_vol_set(vol); set_csr(mstatus, MSTATUS_MIE); } |