diff options
author | Uros Majstorovic <majstor@majstor.org> | 2019-01-09 17:51:35 +0100 |
---|---|---|
committer | Uros Majstorovic <majstor@majstor.org> | 2019-01-09 17:51:35 +0100 |
commit | 4a49ee4a0dd2b75a81511519a190eaada9664930 (patch) | |
tree | 8f09ccb2d4a96515441d6c81790273058671ca78 /code/fe310 | |
parent | a67f35abdb7ef55c062c26251b7354d9968d385b (diff) |
i2s speaker driver added
Diffstat (limited to 'code/fe310')
-rw-r--r-- | code/fe310/eos/i2s.c | 144 | ||||
-rw-r--r-- | code/fe310/eos/i2s_def.h | 19 | ||||
-rw-r--r-- | code/fe310/eos/trap_entry.S | 318 |
3 files changed, 278 insertions, 203 deletions
diff --git a/code/fe310/eos/i2s.c b/code/fe310/eos/i2s.c index 9ec5a71..42e185b 100644 --- a/code/fe310/eos/i2s.c +++ b/code/fe310/eos/i2s.c @@ -1,4 +1,5 @@ #include <unistd.h> +#include <stdio.h> #include "encoding.h" #include "platform.h" @@ -10,16 +11,17 @@ #include "i2s.h" #include "i2s_def.h" -#define I2S_PWM_REG_CK PWM0_REG -#define I2S_PWM_REG_WS PWM2_REG +#define I2S_PWM_REG_CK PWM0_REG +#define I2S_PWM_REG_WS_SPK PWM1_REG +#define I2S_PWM_REG_WS_MIC PWM2_REG #define EOS_ABUF_IDX_MASK(IDX, SIZE) ((IDX) & ((SIZE) - 1)) EOSABuf _eos_i2s_mic_buf; EOSABuf _eos_i2s_spk_buf; uint32_t _eos_i2s_ck_period = 0; -uint32_t _eos_i2s_mic_volume = 3; -uint32_t _eos_i2s_spk_volume = 3; +uint32_t _eos_i2s_mic_volume = 0; +uint32_t _eos_i2s_spk_volume = 4; static eos_evt_fptr_t evt_handler[I2S_MAX_HANDLER]; uint32_t _eos_i2s_evt_enable[I2S_MAX_HANDLER]; uint32_t _eos_i2s_wm[I2S_MAX_HANDLER]; @@ -92,31 +94,35 @@ void eos_i2s_init(uint32_t sample_rate) { _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); - GPIO_REG(GPIO_OUTPUT_XOR) &= ~(1 << I2S_PIN_LR); GPIO_REG(GPIO_INPUT_EN) &= ~(1 << I2S_PIN_CK); GPIO_REG(GPIO_OUTPUT_EN) |= (1 << I2S_PIN_CK); GPIO_REG(GPIO_OUTPUT_XOR) &= ~(1 << I2S_PIN_CK); - GPIO_REG(GPIO_INPUT_EN) &= ~(1 << I2S_PIN_WS); - GPIO_REG(GPIO_OUTPUT_EN) |= (1 << I2S_PIN_WS); - GPIO_REG(GPIO_OUTPUT_XOR) &= ~(1 << I2S_PIN_WS); + GPIO_REG(GPIO_INPUT_EN) &= ~(1 << I2S_PIN_CK_SW); + GPIO_REG(GPIO_OUTPUT_EN) |= (1 << I2S_PIN_CK_SW); + GPIO_REG(GPIO_OUTPUT_XOR) &= ~(1 << I2S_PIN_CK_SW); - GPIO_REG(GPIO_INPUT_EN) &= ~(1 << I2S_PIN_CKE); - GPIO_REG(GPIO_OUTPUT_EN) |= (1 << I2S_PIN_CKE); - GPIO_REG(GPIO_OUTPUT_XOR) &= ~(1 << I2S_PIN_CKE); + GPIO_REG(GPIO_INPUT_EN) &= ~(1 << I2S_PIN_CK_SR); + GPIO_REG(GPIO_OUTPUT_EN) |= (1 << I2S_PIN_CK_SR); + GPIO_REG(GPIO_OUTPUT_XOR) &= ~(1 << I2S_PIN_CK_SR); - GPIO_REG(GPIO_INPUT_EN) &= ~(1 << I2S_PIN_CKF); - GPIO_REG(GPIO_OUTPUT_EN) |= (1 << I2S_PIN_CKF); - GPIO_REG(GPIO_OUTPUT_XOR) &= ~(1 << I2S_PIN_CKF); + GPIO_REG(GPIO_INPUT_EN) &= ~(1 << I2S_PIN_WS_MIC); + GPIO_REG(GPIO_OUTPUT_EN) |= (1 << I2S_PIN_WS_MIC); + GPIO_REG(GPIO_OUTPUT_XOR) &= ~(1 << I2S_PIN_WS_MIC); - GPIO_REG(GPIO_INPUT_EN) |= (1 << I2S_PIN_SD); - GPIO_REG(GPIO_OUTPUT_EN) &= ~(1 << I2S_PIN_SD); - GPIO_REG(GPIO_PULLUP_EN) &= ~(1 << I2S_PIN_SD); + GPIO_REG(GPIO_INPUT_EN) &= ~(1 << I2S_PIN_WS_SPK); + GPIO_REG(GPIO_OUTPUT_EN) |= (1 << I2S_PIN_WS_SPK); + GPIO_REG(GPIO_OUTPUT_XOR) &= ~(1 << I2S_PIN_WS_SPK); - GPIO_REG(GPIO_OUTPUT_VAL) &= ~(1 << I2S_PIN_LR); + GPIO_REG(GPIO_INPUT_EN) |= (1 << I2S_PIN_SD_IN); + GPIO_REG(GPIO_OUTPUT_EN) &= ~(1 << I2S_PIN_SD_IN); + GPIO_REG(GPIO_PULLUP_EN) &= ~(1 << I2S_PIN_SD_IN); + + GPIO_REG(GPIO_INPUT_EN) &= ~(1 << I2S_PIN_SD_OUT); + GPIO_REG(GPIO_OUTPUT_EN) &= ~(1 << I2S_PIN_SD_OUT); + GPIO_REG(GPIO_PULLUP_EN) &= ~(1 << I2S_PIN_SD_OUT); + GPIO_REG(GPIO_OUTPUT_XOR) &= ~(1 << I2S_PIN_SD_OUT); I2S_PWM_REG_CK(PWM_CFG) = 0; I2S_PWM_REG_CK(PWM_COUNT) = 0; @@ -125,12 +131,18 @@ void eos_i2s_init(uint32_t sample_rate) { I2S_PWM_REG_CK(PWM_CMP2) = 0; I2S_PWM_REG_CK(PWM_CMP3) = 0; - 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) * _eos_i2s_mic_volume; - I2S_PWM_REG_WS(PWM_CMP3) = I2S_PWM_REG_WS(PWM_CMP2) + (_eos_i2s_ck_period + 1) * 16; + I2S_PWM_REG_WS_MIC(PWM_CFG) = 0; + I2S_PWM_REG_WS_MIC(PWM_COUNT) = 0; + I2S_PWM_REG_WS_MIC(PWM_CMP0) = (_eos_i2s_ck_period + 1) * 64 - 1; + I2S_PWM_REG_WS_MIC(PWM_CMP1) = (_eos_i2s_ck_period + 1) * 32; + I2S_PWM_REG_WS_MIC(PWM_CMP2) = (_eos_i2s_ck_period + 1) * _eos_i2s_mic_volume; + I2S_PWM_REG_WS_MIC(PWM_CMP3) = I2S_PWM_REG_WS_MIC(PWM_CMP2) + (_eos_i2s_ck_period + 1) * 17; + + I2S_PWM_REG_WS_SPK(PWM_CFG) = 0; + I2S_PWM_REG_WS_SPK(PWM_COUNT) = 0; + I2S_PWM_REG_WS_SPK(PWM_CMP0) = (_eos_i2s_ck_period + 1) * 64 - 1; + I2S_PWM_REG_WS_SPK(PWM_CMP1) = (_eos_i2s_ck_period + 1) * 32; + I2S_PWM_REG_WS_SPK(PWM_CMP2) = (_eos_i2s_ck_period + 1) * 33; _eos_i2s_evt_enable[I2S_EVT_MIC] = 0; _eos_i2s_evt_enable[I2S_EVT_SPK] = 0; @@ -145,35 +157,47 @@ void eos_i2s_init(uint32_t sample_rate) { eos_evtq_set_handler(EOS_EVT_AUDIO, audio_handler, EOS_EVT_FLAG_WRAP); } +extern void _eos_set_pwm(void); + void eos_i2s_start(void) { _eos_i2s_evt_enable[I2S_EVT_MIC] = 1; _eos_i2s_evt_enable[I2S_EVT_SPK] = 1; eos_intr_set_priority(I2S_IRQ_WS_ID, I2S_IRQ_WS_PRIORITY); - I2S_PWM_REG_CK(PWM_COUNT) = 0; - I2S_PWM_REG_WS(PWM_COUNT) = 0; + I2S_PWM_REG_CK(PWM_COUNT) = 0; + I2S_PWM_REG_WS_MIC(PWM_COUNT) = (_eos_i2s_ck_period + 1) * 32; + I2S_PWM_REG_WS_SPK(PWM_COUNT) = (_eos_i2s_ck_period + 1) * 32 + (_eos_i2s_ck_period + 1) * (_eos_i2s_spk_volume + 1 - _eos_i2s_mic_volume) + (_eos_i2s_ck_period + 1) / 2; - I2S_PWM_REG_CK(PWM_CFG) = PWM_CFG_ENALWAYS | PWM_CFG_ZEROCMP | I2S_PWM_SCALE_CK; - I2S_PWM_REG_WS(PWM_CFG) = PWM_CFG_ENALWAYS | PWM_CFG_ZEROCMP | PWM_CFG_CMP2GANG; + _eos_set_pwm(); + /* + I2S_PWM_REG_CK(PWM_CFG) = PWM_CFG_ENALWAYS | PWM_CFG_ZEROCMP | I2S_PWM_SCALE_CK; + I2S_PWM_REG_WS_MIC(PWM_CFG) = PWM_CFG_ENALWAYS | PWM_CFG_ZEROCMP | PWM_CFG_CMP2GANG; + I2S_PWM_REG_WS_SPK(PWM_CFG) = PWM_CFG_ENALWAYS | PWM_CFG_ZEROCMP; + */ - GPIO_REG(GPIO_IOF_SEL) |= (1 << I2S_PIN_CK); - GPIO_REG(GPIO_IOF_EN) |= (1 << I2S_PIN_CK); + GPIO_REG(GPIO_IOF_SEL) |= (1 << I2S_PIN_CK); + GPIO_REG(GPIO_IOF_EN) |= (1 << I2S_PIN_CK); - GPIO_REG(GPIO_IOF_SEL) |= (1 << I2S_PIN_WS); - GPIO_REG(GPIO_IOF_EN) |= (1 << I2S_PIN_WS); + GPIO_REG(GPIO_IOF_SEL) |= (1 << I2S_PIN_CK_SW); + GPIO_REG(GPIO_IOF_EN) |= (1 << I2S_PIN_CK_SW); + + GPIO_REG(GPIO_IOF_SEL) |= (1 << I2S_PIN_WS_MIC); + GPIO_REG(GPIO_IOF_EN) |= (1 << I2S_PIN_WS_MIC); - GPIO_REG(GPIO_IOF_SEL) |= (1 << I2S_PIN_CKE); - GPIO_REG(GPIO_IOF_EN) |= (1 << I2S_PIN_CKE); + GPIO_REG(GPIO_IOF_SEL) |= (1 << I2S_PIN_WS_SPK); + GPIO_REG(GPIO_IOF_EN) |= (1 << I2S_PIN_WS_SPK); - GPIO_REG(GPIO_OUTPUT_VAL) |= (1 << I2S_PIN_CKF); + GPIO_REG(GPIO_OUTPUT_VAL) |= (1 << I2S_PIN_CK_SR); } void eos_i2s_stop(void) { - I2S_PWM_REG_CK(PWM_CFG) = 0; - I2S_PWM_REG_WS(PWM_CFG) = 0; - I2S_PWM_REG_CK(PWM_COUNT) = 0; - I2S_PWM_REG_WS(PWM_COUNT) = 0; + I2S_PWM_REG_CK(PWM_CFG) = 0; + I2S_PWM_REG_WS_MIC(PWM_CFG) = 0; + I2S_PWM_REG_WS_SPK(PWM_CFG) = 0; + I2S_PWM_REG_CK(PWM_COUNT) = 0; + I2S_PWM_REG_WS_MIC(PWM_COUNT) = 0; + I2S_PWM_REG_WS_SPK(PWM_COUNT) = 0; eos_intr_set_priority(I2S_IRQ_WS_ID, 0); eos_intr_set_priority(I2S_IRQ_SD_ID, 0); @@ -181,17 +205,20 @@ void eos_i2s_stop(void) { eos_i2s_mic_init(NULL, 0); eos_i2s_spk_init(NULL, 0); - GPIO_REG(GPIO_IOF_EN) &= ~(1 << I2S_PIN_CK); - GPIO_REG(GPIO_IOF_SEL) &= ~(1 << I2S_PIN_CK); - - GPIO_REG(GPIO_IOF_EN) &= ~(1 << I2S_PIN_WS); - GPIO_REG(GPIO_IOF_SEL) &= ~(1 << I2S_PIN_WS); + GPIO_REG(GPIO_IOF_EN) &= ~(1 << I2S_PIN_CK); + GPIO_REG(GPIO_IOF_SEL) &= ~(1 << I2S_PIN_CK); - GPIO_REG(GPIO_IOF_EN) &= ~(1 << I2S_PIN_CKE); - GPIO_REG(GPIO_IOF_SEL) &= ~(1 << I2S_PIN_CKE); + GPIO_REG(GPIO_IOF_EN) &= ~(1 << I2S_PIN_CK_SW); + GPIO_REG(GPIO_IOF_SEL) &= ~(1 << I2S_PIN_CK_SW); + + GPIO_REG(GPIO_IOF_EN) &= ~(1 << I2S_PIN_WS_MIC); + GPIO_REG(GPIO_IOF_SEL) &= ~(1 << I2S_PIN_WS_MIC); - GPIO_REG(GPIO_OUTPUT_VAL) &= ~((1 << I2S_PIN_CK) | (1 << I2S_PIN_WS) | (1 << I2S_PIN_CKE)); - GPIO_REG(GPIO_OUTPUT_VAL) |= (1 << I2S_PIN_CKF); + GPIO_REG(GPIO_IOF_EN) &= ~(1 << I2S_PIN_WS_SPK); + GPIO_REG(GPIO_IOF_SEL) &= ~(1 << I2S_PIN_WS_SPK); + + GPIO_REG(GPIO_OUTPUT_VAL) &= ~((1 << I2S_PIN_CK) | (1 << I2S_PIN_CK_SR) | (1 << I2S_PIN_WS_MIC) | (1 << I2S_PIN_WS_SPK)); + GPIO_REG(GPIO_OUTPUT_VAL) |= (1 << I2S_PIN_CK_SW); } void eos_i2s_mic_init(uint8_t *mic_arr, uint16_t mic_arr_size) { @@ -224,12 +251,14 @@ uint16_t eos_i2s_mic_read(uint8_t *sample, uint16_t ssize) { int i; uint16_t _ssize = 0; - for (i=0; i<ssize/I2S_ABUF_SIZE_CHUNK && _ssize == i*I2S_ABUF_SIZE_CHUNK; i++) { + for (i=0; i<ssize/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); + uint16_t rv = _abuf_read(&_eos_i2s_mic_buf, sample+i*I2S_ABUF_SIZE_CHUNK, I2S_ABUF_SIZE_CHUNK); set_csr(mstatus, MSTATUS_MIE); + if (rv != I2S_ABUF_SIZE_CHUNK) return _ssize + rv; + _ssize += rv; } - if ((ssize > _ssize) && (_ssize == i*I2S_ABUF_SIZE_CHUNK)) { + if (ssize > _ssize) { clear_csr(mstatus, MSTATUS_MIE); _ssize += _abuf_read(&_eos_i2s_mic_buf, sample+i*I2S_ABUF_SIZE_CHUNK, ssize - _ssize); set_csr(mstatus, MSTATUS_MIE); @@ -272,12 +301,15 @@ uint16_t eos_i2s_spk_len(void) { uint16_t eos_i2s_spk_write(uint8_t *sample, uint16_t ssize) { int i; uint16_t _ssize = 0; - for (i=0; i<ssize/I2S_ABUF_SIZE_CHUNK && _ssize == i*I2S_ABUF_SIZE_CHUNK; i++) { + + for (i=0; i<ssize/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); + uint16_t rv = _abuf_write(&_eos_i2s_spk_buf, sample+i*I2S_ABUF_SIZE_CHUNK, I2S_ABUF_SIZE_CHUNK); set_csr(mstatus, MSTATUS_MIE); + if (rv != I2S_ABUF_SIZE_CHUNK) return _ssize + rv; + _ssize += rv; } - if ((ssize > _ssize) && (_ssize == i*I2S_ABUF_SIZE_CHUNK)) { + if (ssize > _ssize) { clear_csr(mstatus, MSTATUS_MIE); _ssize += _abuf_write(&_eos_i2s_spk_buf, sample+i*I2S_ABUF_SIZE_CHUNK, ssize - _ssize); set_csr(mstatus, MSTATUS_MIE); diff --git a/code/fe310/eos/i2s_def.h b/code/fe310/eos/i2s_def.h index e924776..fc22b49 100644 --- a/code/fe310/eos/i2s_def.h +++ b/code/fe310/eos/i2s_def.h @@ -2,21 +2,20 @@ #define I2S_EVT_SPK 0x1 #define I2S_MAX_HANDLER 2 -#define I2S_PIN_CK 1 // pin 9 -#define I2S_PIN_CKE 12 // pin 18 -#define I2S_PIN_CKF 18 // pin 2 -#define I2S_PIN_SD 13 // pin 19 -#define I2S_PIN_WS 11 // pin 17 +#define I2S_PIN_CK 1 +#define I2S_PIN_CK_SW 12 +#define I2S_PIN_CK_SR 18 +#define I2S_PIN_WS_MIC 11 +#define I2S_PIN_WS_SPK 19 +#define I2S_PIN_SD_IN 13 +#define I2S_PIN_SD_OUT 20 -#define I2S_PIN_LR 13 // pin 19 - -#define I2S_IRQ_WS_ID (INT_PWM2_BASE + 0) -#define I2S_IRQ_SD_ID (INT_PWM2_BASE + 3) +#define I2S_IRQ_WS_ID (INT_PWM1_BASE + 0) +#define I2S_IRQ_SD_ID (INT_PWM1_BASE + 2) #define I2S_IRQ_WS_PRIORITY 6 #define I2S_IRQ_SD_PRIORITY 7 -#define I2S_SMPL_BITS 13 #define I2S_IDLE_CYCLES 8 #define I2S_PWM_SCALE_CK 2 diff --git a/code/fe310/eos/trap_entry.S b/code/fe310/eos/trap_entry.S index 82a553a..bed2524 100644 --- a/code/fe310/eos/trap_entry.S +++ b/code/fe310/eos/trap_entry.S @@ -29,8 +29,9 @@ #define INT_PWM1_BASE 44 #define INT_PWM2_BASE 48 -#define I2S_PWM_CTRL_ADDR_CK PWM0_CTRL_ADDR -#define I2S_PWM_CTRL_ADDR_WS PWM2_CTRL_ADDR +#define I2S_PWM_CTRL_ADDR_CK PWM0_CTRL_ADDR +#define I2S_PWM_CTRL_ADDR_WS_SPK PWM1_CTRL_ADDR +#define I2S_PWM_CTRL_ADDR_WS_MIC PWM2_CTRL_ADDR #define IOF_SPI1_SS0 2 #define IOF_SPI1_SS1 8 @@ -104,59 +105,140 @@ evtq_push: i2s_handler_sd: # exit if too early - li x18, I2S_PWM_CTRL_ADDR_WS + li x18, I2S_PWM_CTRL_ADDR_WS_SPK lw x8, PWM_COUNT(x18) - lw x9, PWM_CMP3(x18) + lw x9, PWM_CMP2(x18) bltu x8, x9, i2s_handler_sd_exit - # read shift reg value -> x8 + # disable sd irq + li x18, PLIC_PRIORITY + sw x0, 4*I2S_IRQ_SD_ID(x18) + + # pop from spk buf -> x8 mv x8, x0 - li x23, GPIO_CTRL_ADDR - lw x22, GPIO_OUTPUT_VAL(x23) - li x9, (0x1 << I2S_PIN_CKF) - or x22, x22, x9 + la x9, _eos_i2s_spk_buf + lhu x18, I2S_ABUF_OFF_IDXR(x9) + lhu x19, I2S_ABUF_OFF_IDXW(x9) + beq x18, x19, i2s_handler_sd_xchg + lhu x19, I2S_ABUF_OFF_SIZE(x9) + + addi x19, x19, -1 + and x19, x19, x18 + lw x8, I2S_ABUF_OFF_ARRAY(x9) + add x19, x19, x8 + lbu x8, 0(x19) + + addi x18, x18, 1 + sh x18, I2S_ABUF_OFF_IDXR(x9) + + # aLaw decode -> x8 + xori x8, x8, 0x55 + andi x9, x8, 0x80 + beqz x9, 0f + li x9, 1 + slli x9, x9, 7 not x9, x9 - and x21, x22, x9 - li x20, (0x1 << I2S_PIN_SD) - li x19, (32 - I2S_SMPL_BITS) - li x18, 32 - + and x8, x8, x9 + li x9, -1 0: - addi x18, x18, -1 - # ck high - sw x21, GPIO_OUTPUT_VAL(x23) + andi x18, x8, 0xf0 + srli x18, x18, 4 + addi x18, x18, 4 + + li x19, 4 + beq x18, x19, 1f + + andi x8, x8, 0x0f + addi x19, x18, -4 + sll x8, x8, x19 + li x19, 1 + sll x19, x19, x18 + or x8, x8, x19 + + li x19, 1 + addi x18, x18, -5 + sll x19, x19, x18 + or x8, x8, x19 + j 2f +1: + slli x8, x8, 1 + ori x8, x8, 1 +2: + beqz x9, i2s_handler_sd_xchg + mul x8, x8, x9 + +i2s_handler_sd_xchg: + # slli x8, x8, 4 + # li x8, 0xAf0A + # li x8, 0x50f5 + # read/write shift reg: x8 -> sr -> x8 + li x18, GPIO_CTRL_ADDR + li x19, (0x1 << I2S_PIN_SD_IN) + li x20, (0x1 << I2S_PIN_SD_OUT) + li x21, (0x1 << I2S_PIN_CK_SR) + lw x22, GPIO_OUTPUT_VAL(x18) + + lw x9, GPIO_OUTPUT_EN(x18) + or x9, x9, x20 + sw x9, GPIO_OUTPUT_EN(x18) + + not x20, x20 + or x22, x22, x21 + + li x23, 17 +0: + addi x23, x23, -1 + beqz x23, 1f + lw x9, GPIO_INPUT_VAL(x18) + and x9, x9, x19 + srli x9, x9, I2S_PIN_SD_IN + slli x8, x8, 1 + or x8, x8, x9 + +1: # idle li x9, I2S_IDLE_CYCLES -1: +2: addi x9, x9, -1 - bnez x9, 1b - - lw x9, GPIO_INPUT_VAL(x23) - # ck low - sw x22, GPIO_OUTPUT_VAL(x23) + bnez x9, 2b - and x9, x9, x20 - srli x9, x9, I2S_PIN_SD - sll x9, x9, x18 - or x8, x8, x9 - beq x19, x18, 3f + # ck high + xor x22, x22, x21 + sw x22, GPIO_OUTPUT_VAL(x18) + + li x9, 0x1 + slli x9, x9, 16 + and x9, x9, x8 +#if I2S_PIN_SD_OUT > 16 + slli x9, x9, (I2S_PIN_SD_OUT - 16) +#else + srli x9, x9, (16 - I2S_PIN_SD_OUT) +#endif + and x22, x22, x20 + or x22, x22, x9 # idle li x9, I2S_IDLE_CYCLES 2: addi x9, x9, -1 bnez x9, 2b - + + # ck low + xor x22, x22, x21 + sw x22, GPIO_OUTPUT_VAL(x18) + + beqz x23, 3f j 0b 3: - srai x8, x8, (32 - I2S_SMPL_BITS) - - # disable sd irq - li x18, PLIC_PRIORITY - sw x0, 4*I2S_IRQ_SD_ID(x18) - + slli x8, x8, 16 + srai x8, x8, 16 + + lw x9, GPIO_OUTPUT_EN(x18) + and x9, x9, x20 + sw x9, GPIO_OUTPUT_EN(x18) + # aLaw encode -> x8 li x18, 0x800 li x19, 7 @@ -182,7 +264,7 @@ i2s_handler_sd: slli x19, x19, 4 or x8, x8, x19 bgez x8, 3f - ori x8, x8, 0x80 + ori x8, x8, 0x80 3: xori x8, x8, 0x55 andi x8, x8, 0xff @@ -206,97 +288,25 @@ i2s_handler_sd: sb x8, 0(x20) addi x18, x18, 1 - + 0: # check for push to event queue la x9, _eos_i2s_wm lw x20, 0(x9) - beqz x20, i2s_handler_sd_out - bltu x18, x20, i2s_handler_sd_out + beqz x20, i2s_handler_sd_exit + bltu x18, x20, i2s_handler_sd_exit la x9, _eos_i2s_evt_enable lw x18, 0(x9) - beqz x18, i2s_handler_sd_out + beqz x18, i2s_handler_sd_exit sw x0, 0(x9) # push to event queue jal x20, evtq_push - beqz x8, i2s_handler_sd_out + beqz x8, i2s_handler_sd_exit li x18, (EOS_EVT_AUDIO | I2S_EVT_MIC) sb x18, MSGQ_ITEM_OFF_CMD(x8) -i2s_handler_sd_out: - # pop from spk buf -> x8 - la x9, _eos_i2s_spk_buf - lhu x18, I2S_ABUF_OFF_IDXR(x9) - lhu x19, I2S_ABUF_OFF_IDXW(x9) - beq x18, x19, i2s_handler_sd_exit - lhu x19, I2S_ABUF_OFF_SIZE(x9) - - addi x19, x19, -1 - and x19, x19, x18 - lw x8, I2S_ABUF_OFF_ARRAY(x9) - add x19, x19, x8 - lbu x8, 0(x19) - - addi x18, x18, 1 - sh x18, I2S_ABUF_OFF_IDXR(x9) - -#define UART0_CTRL_ADDR 0x10013000 -#define UART_REG_TXFIFO 0x00 - # END - # li x18, UART0_CTRL_ADDR - # sw x8, UART_REG_TXFIFO(x18) - - # aLaw decode -> x8 - xori x8, x8, 0x55 - andi x9, x8, 0x80 - beqz x9, 0f - li x9, 1 - slli x9, x9, 7 - not x9, x9 - and x8, x8, x9 - li x9, -1 -0: - andi x18, x8, 0xf0 - srli x18, x18, 4 - addi x18, x18, 4 - - li x19, 4 - beq x18, x19, 1f - - andi x8, x8, 0x0f - addi x19, x18, -4 - sll x8, x8, x19 - - li x19, 1 - sll x19, x19, x18 - or x8, x8, x19 - - li x19, 1 - addi x18, x18, -5 - sll x19, x19, x18 - or x8, x8, x19 - j 2f -1: - slli x8, x8, 1 - ori x8, x8, 1 -2: - beqz x9, 3f - mul x8, x8, x9 -3: -#define UART0_CTRL_ADDR 0x10013000 -#define UART_REG_TXFIFO 0x00 - # END - li x18, UART0_CTRL_ADDR - mv x9, x8 - srai x9, x9, 8 - andi x9, x9, 0xff - sw x9, UART_REG_TXFIFO(x18) - mv x9, x8 - andi x9, x9, 0xff - sw x9, UART_REG_TXFIFO(x18) - i2s_handler_sd_exit: # complete li x18, I2S_IRQ_SD_ID @@ -305,7 +315,7 @@ i2s_handler_sd_exit: # exit j trap_exit_data - + i2s_handler_ws: # enable sd irq li x18, PLIC_PRIORITY @@ -320,6 +330,40 @@ i2s_handler_ws: # exit j trap_exit_data +.global _eos_set_pwm +_eos_set_pwm: + addi sp, sp, -8*REGBYTES + STORE x8, 0*REGBYTES(sp) + STORE x9, 1*REGBYTES(sp) + STORE x18, 2*REGBYTES(sp) + STORE x19, 3*REGBYTES(sp) + STORE x20, 4*REGBYTES(sp) + STORE x21, 5*REGBYTES(sp) + STORE x22, 6*REGBYTES(sp) + STORE x23, 7*REGBYTES(sp) + + li x18, I2S_PWM_CTRL_ADDR_CK + li x19, I2S_PWM_CTRL_ADDR_WS_MIC + li x20, I2S_PWM_CTRL_ADDR_WS_SPK + li x21, PWM_CFG_ENALWAYS | PWM_CFG_ZEROCMP | I2S_PWM_SCALE_CK + li x22, PWM_CFG_ENALWAYS | PWM_CFG_ZEROCMP | PWM_CFG_CMP2GANG + li x23, PWM_CFG_ENALWAYS | PWM_CFG_ZEROCMP + sw x21, PWM_CFG(x18) + sw x22, PWM_CFG(x19) + sw x23, PWM_CFG(x20) + + LOAD x8, 0*REGBYTES(sp) + LOAD x9, 1*REGBYTES(sp) + LOAD x18, 2*REGBYTES(sp) + LOAD x19, 3*REGBYTES(sp) + LOAD x20, 4*REGBYTES(sp) + LOAD x21, 5*REGBYTES(sp) + LOAD x22, 6*REGBYTES(sp) + LOAD x23, 7*REGBYTES(sp) + addi sp, sp, 8*REGBYTES + + ret + .global eos_flash_set eos_flash_set: li a3, SPI0_CTRL_ADDR @@ -329,7 +373,7 @@ eos_flash_set: li a0, 1 sw a0, SPI_REG_FCTRL(a3) ret - + #ifdef EOS_WITH_SPI_ASM # x9 - cmd, x18 - buffer, x19 - len, x20 - &flags, x21 - flags @@ -343,7 +387,7 @@ spi_xchg_start: lw x23, 0(x22) bnez x23, 1f ori x9, x9, EOS_NET_CMD_FLAG_ONEW - + 1: andi x22, x9, EOS_NET_CMD_FLAG_ONEW beqz x22, 2f @@ -381,8 +425,8 @@ spi_xchg_start: sw x21, SPI_REG_RXCTRL(x20) li x21, SPI_IP_RXWM sw x21, SPI_REG_IE(x20) - jalr x0, x8 - + jalr x0, x8 + spi_handler_xchg: li x19, SPI1_CTRL_ADDR la x18, _eos_spi_state_flags @@ -452,9 +496,9 @@ spi_handler_xchg: li x8, SPI_CSMODE_AUTO sw x8, SPI_REG_CSMODE(x19) sw x0, SPI_REG_IE(x19) - + j spi_handler_xchg_exit - + 5: la x18, _eos_spi_state_len sw x21, 0(x18) @@ -469,7 +513,7 @@ spi_handler_xchg: lw x22, 0(x18) la x18, _eos_spi_state_buf lw x23, 0(x18) - + sub x9, x20, x21 li x8, SPI_SIZE_CHUNK bltu x8, x9, 7f @@ -478,7 +522,7 @@ spi_handler_xchg: addi x8, x8, -1 add x9, x23, x21 -8: +8: bltz x8, 9f lw x18, SPI_REG_TXFIFO(x19) bltz x18, 9f @@ -488,13 +532,13 @@ spi_handler_xchg: addi x9, x9, 1 addi x21, x21, 1 j 8b - + 9: sub x8, x21, x22 addi x8, x8, -1 add x9, x23, x22 - -10: + +10: bltz x8, 11f lw x18, SPI_REG_RXFIFO(x19) bltz x18, 11f @@ -509,7 +553,7 @@ spi_handler_xchg: sw x21, 0(x18) la x18, _eos_spi_state_idx_rx sw x22, 0(x18) - + bne x22, x20, 15f li x8, SPI_CSMODE_AUTO sw x8, SPI_REG_CSMODE(x19) @@ -544,9 +588,9 @@ spi_handler_xchg: andi x8, x8, ~SPI_FLAG_ONEW sb x8, 0(x18) sw x23, 0(x19) - + j spi_handler_xchg_exit - + 14: # push to spi buf queue la x19, _eos_spi_buf_q @@ -562,7 +606,7 @@ spi_handler_xchg: j spi_handler_xchg_exit -15: +15: bne x21, x20, spi_handler_xchg_exit sub x8, x20, x22 addi x8, x8, -1 @@ -573,7 +617,7 @@ spi_handler_xchg: sw x8, SPI_REG_RXCTRL(x19) li x9, SPI_IP_RXWM sw x9, SPI_REG_IE(x19) - + spi_handler_xchg_exit: # complete li x18, INT_SPI1_BASE @@ -595,7 +639,7 @@ spi_handler_cts: sb x21, 0(x20) andi x9, x21, SPI_FLAG_RDY beqz x9, 2f - + # pop from send q la x9, _eos_spi_send_q lbu x18, MSGQ_OFF_IDXR(x9) @@ -617,13 +661,13 @@ spi_handler_cts: lhu x19, MSGQ_ITEM_OFF_SIZE(x8) beqz x18, 1f jal x8, spi_xchg_start - + 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) @@ -691,7 +735,7 @@ spi_handler_rts: sw x0, SPI_REG_RXCTRL(x19) li x8, SPI_IP_RXWM sw x8, SPI_REG_IE(x19) - + j spi_handler_rts_exit 1: @@ -739,7 +783,7 @@ handler: .section .text.entry .align 2 - + trap_entry_text: addi sp, sp, -24*REGBYTES @@ -784,7 +828,7 @@ handle_ext: li x18, PLIC_CLAIM sw a0, 0(x18) j trap_exit_text - + trap_exit_text: # Remain in M-mode after mret li t0, MSTATUS_MPP |