summaryrefslogtreecommitdiff
path: root/code/fe310
diff options
context:
space:
mode:
authorUros Majstorovic <majstor@majstor.org>2019-12-13 03:35:30 +0100
committerUros Majstorovic <majstor@majstor.org>2019-12-13 03:35:30 +0100
commit6c891c9ffb491146e991e7936f6bb8408bcf2a9a (patch)
treebaef7ca657cb829af43f7d0fc7f8bffa07aca644 /code/fe310
parentfe0d3263d058808feb4355ac3aebba7196cb7bcc (diff)
fixed and verified audio driver
Diffstat (limited to 'code/fe310')
-rw-r--r--code/fe310/eos/i2s.c84
-rw-r--r--code/fe310/eos/i2s.h4
-rw-r--r--code/fe310/eos/i2s_def.h2
-rw-r--r--code/fe310/eos/trap_entry.S6
4 files changed, 73 insertions, 23 deletions
diff --git a/code/fe310/eos/i2s.c b/code/fe310/eos/i2s.c
index 8c3aebb..8b878b3 100644
--- a/code/fe310/eos/i2s.c
+++ b/code/fe310/eos/i2s.c
@@ -26,8 +26,6 @@
EOSABuf _eos_i2s_mic_buf;
EOSABuf _eos_i2s_spk_buf;
uint32_t _eos_i2s_fmt = 0;
-uint32_t _eos_i2s_mic_volume = 4; /* 1 - 8 */
-uint32_t _eos_i2s_spk_volume = 12; /* 1 - 16 */
uint32_t _eos_i2s_mic_wm = 0;
uint32_t _eos_i2s_spk_wm = 0;
uint32_t _eos_i2s_mic_evt_enable = 0;
@@ -35,6 +33,9 @@ uint32_t _eos_i2s_spk_evt_enable = 0;
static eos_i2s_fptr_t i2s_spk_handler = NULL;
static eos_i2s_fptr_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 */
static void _abuf_init(EOSABuf *buf, uint8_t *array, uint16_t size) {
buf->idx_r = 0;
@@ -111,6 +112,27 @@ static void i2s_handler_evt(unsigned char type, unsigned char *buffer, uint16_t
}
}
+static void _mic_vol_set(uint8_t vol) {
+ I2S_PWM_REG_WS_MIC(PWM_CMP2) = i2s_clk_period * (vol + 1);
+ I2S_PWM_REG_WS_MIC(PWM_CMP3) = I2S_PWM_REG_WS_MIC(PWM_CMP2) + i2s_clk_period * 16;
+}
+
+static void _spk_vol_set(uint8_t vol) {
+ int spk_cmp = vol + i2s_mic_volume - 16;
+
+ if (spk_cmp <= 0) {
+ I2S_PWM_REG_WS_SPK(PWM_CMP1) = i2s_clk_period * (32 + spk_cmp);
+ I2S_PWM_REG_WS_SPK(PWM_CMP2) = i2s_clk_period * (64 + spk_cmp);
+ I2S_PWM_REG_WS_SPK(PWM_CMP3) = i2s_clk_period * 33;
+ GPIO_REG(GPIO_OUTPUT_XOR) &= ~(1 << I2S_PIN_WS_SPK);
+ } else {
+ I2S_PWM_REG_WS_SPK(PWM_CMP1) = i2s_clk_period * spk_cmp;
+ I2S_PWM_REG_WS_SPK(PWM_CMP2) = i2s_clk_period * (32 + spk_cmp);
+ I2S_PWM_REG_WS_SPK(PWM_CMP3) = i2s_clk_period * (33 + spk_cmp);
+ GPIO_REG(GPIO_OUTPUT_XOR) |= (1 << I2S_PIN_WS_SPK);
+ }
+}
+
extern void _eos_i2s_start_pwm(void);
void eos_i2s_init(void) {
@@ -156,25 +178,23 @@ void eos_i2s_init(void) {
}
void eos_i2s_start(uint32_t sample_rate, unsigned char fmt) {
- uint32_t ck_period = (PRCI_get_cpu_freq() / (sample_rate * 64)) & ~I2S_PWM_SCALE_CK_MASK;;
+ i2s_clk_period = ((PRCI_get_cpu_freq() / (sample_rate * 64)) & ~I2S_PWM_SCALE_CK_MASK) + 1;
- I2S_PWM_REG_CK(PWM_CMP0) = ck_period >> I2S_PWM_SCALE_CK;
- I2S_PWM_REG_CK(PWM_CMP1) = I2S_PWM_REG_CK(PWM_CMP0) / 2;
- I2S_PWM_REG_CK(PWM_CMP2) = 0;
- I2S_PWM_REG_CK(PWM_CMP3) = 0;
+ I2S_PWM_REG_CK(PWM_CMP0) = i2s_clk_period >> I2S_PWM_SCALE_CK;
+ I2S_PWM_REG_CK(PWM_CMP1) = I2S_PWM_REG_CK(PWM_CMP0) / 2;
+ I2S_PWM_REG_CK(PWM_CMP2) = 0;
+ I2S_PWM_REG_CK(PWM_CMP3) = 0;
- I2S_PWM_REG_WS_MIC(PWM_CMP0) = (ck_period + 1) * 64 - 1;
- I2S_PWM_REG_WS_MIC(PWM_CMP1) = (ck_period + 1) * 32;
- I2S_PWM_REG_WS_MIC(PWM_CMP2) = (ck_period + 1) * _eos_i2s_mic_volume;
- I2S_PWM_REG_WS_MIC(PWM_CMP3) = I2S_PWM_REG_WS_MIC(PWM_CMP2) + (ck_period + 1) * 16;
+ I2S_PWM_REG_WS_MIC(PWM_CMP0) = i2s_clk_period * 64 - 1;
+ I2S_PWM_REG_WS_MIC(PWM_CMP1) = i2s_clk_period * 32;
+ _mic_vol_set(i2s_mic_volume);
- I2S_PWM_REG_WS_SPK(PWM_CMP0) = (ck_period + 1) * 64 - 1;
- I2S_PWM_REG_WS_SPK(PWM_CMP1) = (ck_period + 1) * 32;
- I2S_PWM_REG_WS_SPK(PWM_CMP2) = (ck_period + 1) * 33;
+ I2S_PWM_REG_WS_SPK(PWM_CMP0) = i2s_clk_period * 64 - 1;
+ _spk_vol_set(i2s_spk_volume);
- I2S_PWM_REG_CK(PWM_COUNT) = 0;
- I2S_PWM_REG_WS_MIC(PWM_COUNT) = (ck_period + 1) * 32;
- I2S_PWM_REG_WS_SPK(PWM_COUNT) = (ck_period + 1) * 32 + (ck_period + 1)/2 + (ck_period + 1) * (17 - _eos_i2s_spk_volume - _eos_i2s_mic_volume);
+ I2S_PWM_REG_CK(PWM_COUNT) = 0;
+ I2S_PWM_REG_WS_MIC(PWM_COUNT) = 0;
+ I2S_PWM_REG_WS_SPK(PWM_COUNT) = i2s_clk_period / 2;
_eos_i2s_fmt = fmt;
_eos_i2s_mic_evt_enable = 1;
@@ -189,7 +209,7 @@ void eos_i2s_start(uint32_t sample_rate, unsigned char fmt) {
/*
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;
+ I2S_PWM_REG_WS_SPK(PWM_CFG) = PWM_CFG_ENALWAYS | PWM_CFG_ZEROCMP | PWM_CFG_CMP1GANG;
*/
GPIO_REG(GPIO_INPUT_EN) |= (1 << I2S_PIN_SD_IN);
@@ -302,6 +322,21 @@ int eos_i2s_mic_pop16(uint16_t *sample) {
return ret;
}
+int eos_i2s_mic_vol_get(void) {
+ return i2s_mic_volume;
+}
+
+void eos_i2s_mic_vol_set(int vol) {
+ if ((vol < 0) || (vol > 8)) return;
+
+ i2s_mic_volume = vol;
+
+ clear_csr(mstatus, MSTATUS_MIE);
+ _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(&_eos_i2s_spk_buf, spk_arr, spk_arr_size);
@@ -362,3 +397,16 @@ int eos_i2s_spk_push16(uint16_t sample) {
return ret;
}
+int eos_i2s_spk_vol_get(void) {
+ return i2s_spk_volume;
+}
+
+void eos_i2s_spk_vol_set(int vol) {
+ if ((vol < 0) || (vol > 16)) return;
+
+ i2s_spk_volume = vol;
+
+ clear_csr(mstatus, MSTATUS_MIE);
+ _spk_vol_set(vol);
+ set_csr(mstatus, MSTATUS_MIE);
+}
diff --git a/code/fe310/eos/i2s.h b/code/fe310/eos/i2s.h
index af91dd3..83c39b3 100644
--- a/code/fe310/eos/i2s.h
+++ b/code/fe310/eos/i2s.h
@@ -22,6 +22,8 @@ uint16_t eos_i2s_mic_len(void);
uint16_t eos_i2s_mic_read(uint8_t *sample, uint16_t ssize);
int eos_i2s_mic_pop8(uint8_t *sample);
int eos_i2s_mic_pop16(uint16_t *sample);
+int eos_i2s_mic_vol_get(void);
+void eos_i2s_mic_vol_set(int vol);
void eos_i2s_spk_init(uint8_t *mic_arr, uint16_t mic_arr_size);
void eos_i2s_spk_set_handler(eos_i2s_fptr_t wm_handler, uint8_t flags);
void eos_i2s_spk_set_wm(uint16_t wm);
@@ -29,3 +31,5 @@ uint16_t eos_i2s_spk_len(void);
uint16_t eos_i2s_spk_write(uint8_t *sample, uint16_t ssize);
int eos_i2s_spk_push8(uint8_t sample);
int eos_i2s_spk_push16(uint16_t sample);
+int eos_i2s_spk_vol_get(void);
+void eos_i2s_spk_vol_set(int vol);
diff --git a/code/fe310/eos/i2s_def.h b/code/fe310/eos/i2s_def.h
index f2e8aa1..3a09982 100644
--- a/code/fe310/eos/i2s_def.h
+++ b/code/fe310/eos/i2s_def.h
@@ -10,7 +10,7 @@
#define I2S_PIN_SD_OUT 12
#define I2S_IRQ_WS_ID (INT_PWM2_BASE + 0)
-#define I2S_IRQ_SD_ID (INT_PWM2_BASE + 2)
+#define I2S_IRQ_SD_ID (INT_PWM2_BASE + 3)
#define I2S_IDLE_CYCLES 8
diff --git a/code/fe310/eos/trap_entry.S b/code/fe310/eos/trap_entry.S
index fc029fe..a55d6c1 100644
--- a/code/fe310/eos/trap_entry.S
+++ b/code/fe310/eos/trap_entry.S
@@ -101,7 +101,7 @@ i2s_handler_sd:
# exit if too early
li x18, I2S_PWM_CTRL_ADDR_WS_SPK
lw x8, PWM_COUNT(x18)
- lw x9, PWM_CMP2(x18)
+ lw x9, PWM_CMP3(x18)
bltu x8, x9, i2s_handler_sd_exit
# disable sd irq
@@ -199,8 +199,6 @@ i2s_decode:
mul x8, x8, x9
i2s_handler_sd_xchg:
- # 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)
@@ -394,7 +392,7 @@ _eos_i2s_start_pwm:
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
+ li x23, PWM_CFG_ENALWAYS | PWM_CFG_ZEROCMP | PWM_CFG_CMP1GANG
sw x21, PWM_CFG(x18)
sw x22, PWM_CFG(x19)
sw x23, PWM_CFG(x20)