summaryrefslogtreecommitdiff
path: root/fw/fe310/eos/soc
diff options
context:
space:
mode:
Diffstat (limited to 'fw/fe310/eos/soc')
-rw-r--r--fw/fe310/eos/soc/Makefile2
-rw-r--r--fw/fe310/eos/soc/aon.c46
-rw-r--r--fw/fe310/eos/soc/aon.h5
-rw-r--r--fw/fe310/eos/soc/gpio.c20
-rw-r--r--fw/fe310/eos/soc/gpio.h5
-rw-r--r--fw/fe310/eos/soc/i2c.c2
-rw-r--r--fw/fe310/eos/soc/i2c.h2
-rw-r--r--fw/fe310/eos/soc/i2s.c355
-rw-r--r--fw/fe310/eos/soc/i2s.h34
-rw-r--r--fw/fe310/eos/soc/i2s_def.h11
-rw-r--r--fw/fe310/eos/soc/i2s_priv.h5
-rw-r--r--fw/fe310/eos/soc/interrupt.c6
-rw-r--r--fw/fe310/eos/soc/interrupt.h2
-rw-r--r--fw/fe310/eos/soc/pwr.c14
-rw-r--r--fw/fe310/eos/soc/pwr.h4
-rw-r--r--fw/fe310/eos/soc/spi.c119
-rw-r--r--fw/fe310/eos/soc/spi.h14
-rw-r--r--fw/fe310/eos/soc/spi9bit.c20
-rw-r--r--fw/fe310/eos/soc/spi9bit.h2
-rw-r--r--fw/fe310/eos/soc/spi_priv.h3
-rw-r--r--fw/fe310/eos/soc/timer.c20
-rw-r--r--fw/fe310/eos/soc/timer.h10
-rw-r--r--fw/fe310/eos/soc/trap_entry.S205
-rw-r--r--fw/fe310/eos/soc/uart.c11
-rw-r--r--fw/fe310/eos/soc/uart.h3
25 files changed, 460 insertions, 460 deletions
diff --git a/fw/fe310/eos/soc/Makefile b/fw/fe310/eos/soc/Makefile
index f5f072a..39d8b8c 100644
--- a/fw/fe310/eos/soc/Makefile
+++ b/fw/fe310/eos/soc/Makefile
@@ -1,7 +1,7 @@
include ../../common.mk
CFLAGS += -I$(bsp_dir)/include -I$(bsp_dir)/drivers
-obj = trap_entry.o interrupt.o timer.o pwr.o i2s.o i2c.o uart.o spi.o spi9bit.o
+obj = trap_entry.o interrupt.o timer.o pwr.o aon.o gpio.o i2s.o i2c.o uart.o spi.o spi9bit.o
lib = ../../libeos-soc.a
diff --git a/fw/fe310/eos/soc/aon.c b/fw/fe310/eos/soc/aon.c
new file mode 100644
index 0000000..a11259e
--- /dev/null
+++ b/fw/fe310/eos/soc/aon.c
@@ -0,0 +1,46 @@
+#include <stdlib.h>
+#include <stdint.h>
+
+#include "encoding.h"
+#include "platform.h"
+
+#include "eos.h"
+#include "pwr.h"
+
+#include "aon.h"
+
+#define AON_MAX_BACKUP 16
+
+int eos_aon_init(void) {
+ uint8_t wakeup_cause;
+ int i, rst;
+
+ wakeup_cause = eos_pwr_wakeup_cause();
+ rst = (wakeup_cause == EOS_PWR_WAKE_RST);
+ if (rst) {
+ for (i=0; i<AON_MAX_BACKUP; i++) {
+ eos_aon_set_reg(i, 0);
+ }
+ }
+
+ return EOS_OK;
+}
+
+uint32_t eos_aon_get_reg(int idx) {
+ uint32_t addr;
+
+ if ((idx < 0) || (idx >= AON_MAX_BACKUP)) return -1;
+
+ addr = AON_BACKUP0 + sizeof(uint32_t) * idx;
+ return AON_REG(addr);
+}
+
+void eos_aon_set_reg(int idx, uint32_t reg) {
+ uint32_t addr;
+
+ if ((idx < 0) || (idx > 15)) return;
+
+ addr = AON_BACKUP0 + sizeof(uint32_t) * idx;
+ AON_REG(addr) = reg;
+}
+
diff --git a/fw/fe310/eos/soc/aon.h b/fw/fe310/eos/soc/aon.h
new file mode 100644
index 0000000..41bdfab
--- /dev/null
+++ b/fw/fe310/eos/soc/aon.h
@@ -0,0 +1,5 @@
+#include <stdint.h>
+
+int eos_aon_init(void);
+uint32_t eos_aon_get_reg(int idx);
+void eos_aon_set_reg(int idx, uint32_t reg); \ No newline at end of file
diff --git a/fw/fe310/eos/soc/gpio.c b/fw/fe310/eos/soc/gpio.c
new file mode 100644
index 0000000..4fa93dd
--- /dev/null
+++ b/fw/fe310/eos/soc/gpio.c
@@ -0,0 +1,20 @@
+#include <stdint.h>
+
+#include "encoding.h"
+#include "platform.h"
+
+int eos_gpio_get(uint32_t reg, int pin) {
+ return !!(GPIO_REG(reg) & (1 << pin));
+}
+
+void eos_gpio_set(uint32_t reg, int pin) {
+ if ((reg == GPIO_OUTPUT_VAL) || (reg == GPIO_LOW_IE)) clear_csr(mstatus, MSTATUS_MIE);
+ GPIO_REG(reg) |= (1 << pin);
+ if ((reg == GPIO_OUTPUT_VAL) || (reg == GPIO_LOW_IE)) set_csr(mstatus, MSTATUS_MIE);
+}
+
+void eos_gpio_clear(uint32_t reg, int pin) {
+ if ((reg == GPIO_OUTPUT_VAL) || (reg == GPIO_LOW_IE)) clear_csr(mstatus, MSTATUS_MIE);
+ GPIO_REG(reg) &= ~(1 << pin);
+ if ((reg == GPIO_OUTPUT_VAL) || (reg == GPIO_LOW_IE)) set_csr(mstatus, MSTATUS_MIE);
+}
diff --git a/fw/fe310/eos/soc/gpio.h b/fw/fe310/eos/soc/gpio.h
new file mode 100644
index 0000000..2ba5787
--- /dev/null
+++ b/fw/fe310/eos/soc/gpio.h
@@ -0,0 +1,5 @@
+#include <stdint.h>
+
+int eos_gpio_get(uint32_t reg, int pin);
+void eos_gpio_set(uint32_t reg, int pin);
+void eos_gpio_clear(uint32_t reg, int pin);
diff --git a/fw/fe310/eos/soc/i2c.c b/fw/fe310/eos/soc/i2c.c
index 553a9bf..feed936 100644
--- a/fw/fe310/eos/soc/i2c.c
+++ b/fw/fe310/eos/soc/i2c.c
@@ -9,7 +9,7 @@
#include "i2s.h"
#include "i2c.h"
-int eos_i2c_init(uint8_t wakeup_cause) {
+int eos_i2c_init(void) {
eos_i2c_speed(EOS_I2C_SPEED);
eos_i2c_enable();
diff --git a/fw/fe310/eos/soc/i2c.h b/fw/fe310/eos/soc/i2c.h
index 5032988..a99b8ee 100644
--- a/fw/fe310/eos/soc/i2c.h
+++ b/fw/fe310/eos/soc/i2c.h
@@ -2,7 +2,7 @@
#define EOS_I2C_SPEED 100000
-int eos_i2c_init(uint8_t wakeup_cause);
+int eos_i2c_init(void);
void eos_i2c_enable(void);
void eos_i2c_disable(void);
int eos_i2c_enabled(void);
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;
+ }
+ }
+}
diff --git a/fw/fe310/eos/soc/i2s.h b/fw/fe310/eos/soc/i2s.h
index c5e92b7..e2155a4 100644
--- a/fw/fe310/eos/soc/i2s.h
+++ b/fw/fe310/eos/soc/i2s.h
@@ -2,39 +2,41 @@
#include "i2s_def.h"
+#define EOS_I2S_MODE_STEREO 0
+#define EOS_I2S_MODE_MONO_L 1
+#define EOS_I2S_MODE_MONO_R 2
+
typedef struct EOSABuf {
uint16_t idx_r;
uint16_t idx_w;
uint16_t size;
- uint8_t *array;
+ uint16_t *array;
} EOSABuf;
typedef void (*eos_i2s_handler_t) (unsigned char);
-int eos_i2s_init(uint8_t wakeup_cause);
-void eos_i2s_init_mux(void);
-void eos_i2s_start(uint32_t sample_rate);
+int eos_i2s_init(void);
+int eos_i2s_start(uint32_t sample_rate, int mode);
void eos_i2s_stop(void);
int eos_i2s_running(void);
-void eos_i2s_set_fmt(unsigned char fmt);
-void eos_i2s_set_mode(unsigned char mode);
+int eos_i2s_set_lsgain(int gain);
void eos_i2s_mic_set_handler(eos_i2s_handler_t handler, uint16_t wm);
-void eos_i2s_mic_set_buf(uint8_t *mic_arr, uint16_t mic_arr_size);
-uint8_t *eos_i2s_mic_get_buf(void);
+void eos_i2s_mic_set_buf(uint16_t *mic_arr, uint16_t mic_arr_size);
+uint16_t *eos_i2s_mic_get_buf(void);
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);
+uint16_t eos_i2s_mic_read(uint16_t *smpl_buf, uint16_t buf_size);
+int eos_i2s_mic_pop(uint16_t *sample);
int eos_i2s_mic_get_vol(void);
void eos_i2s_mic_set_vol(int vol);
void eos_i2s_spk_set_handler(eos_i2s_handler_t handler, uint16_t wm);
-void eos_i2s_spk_set_buf(uint8_t *spk_arr, uint16_t spk_arr_size);
-uint8_t *eos_i2s_spk_get_buf(void);
+void eos_i2s_spk_set_buf(uint16_t *spk_arr, uint16_t spk_arr_size);
+uint16_t *eos_i2s_spk_get_buf(void);
uint16_t eos_i2s_spk_len(void);
-uint16_t eos_i2s_spk_write(uint8_t *sample, uint16_t ssize, uint8_t transform);
-int eos_i2s_spk_push8(uint8_t sample);
-int eos_i2s_spk_push16(uint16_t sample);
+uint16_t eos_i2s_spk_write(uint16_t *smpl_buf, uint16_t buf_len);
+int eos_i2s_spk_push(uint16_t sample);
int eos_i2s_spk_get_vol(void);
void eos_i2s_spk_set_vol(int vol);
+
+void eos_i2s_hp_change(int hp_det);
diff --git a/fw/fe310/eos/soc/i2s_def.h b/fw/fe310/eos/soc/i2s_def.h
index 44eed25..d8c4b4b 100644
--- a/fw/fe310/eos/soc/i2s_def.h
+++ b/fw/fe310/eos/soc/i2s_def.h
@@ -1,13 +1,2 @@
-#define EOS_I2S_FMT_PCM16 0
-#define EOS_I2S_FMT_ALAW 1
-
-#define EOS_I2S_MODE_STEREO 0
-#define EOS_I2S_MODE_MONO 1
-
#define EOS_I2S_ETYPE_MIC 1
#define EOS_I2S_ETYPE_SPK 2
-
-#define EOS_I2S_TRANS_NONE 0
-#define EOS_I2S_TRANS_MONO2D 1
-#define EOS_I2S_TRANS_MONO2L 2
-#define EOS_I2S_TRANS_MONO2R 3 \ No newline at end of file
diff --git a/fw/fe310/eos/soc/i2s_priv.h b/fw/fe310/eos/soc/i2s_priv.h
index 25014a5..6927c36 100644
--- a/fw/fe310/eos/soc/i2s_priv.h
+++ b/fw/fe310/eos/soc/i2s_priv.h
@@ -1,13 +1,10 @@
-#define I2S_PWM_SCALE_CK 2
-#define I2S_PWM_SCALE_CK_MASK 0x0003
-
/* asm */
#define I2S_ABUF_OFF_IDXR 0
#define I2S_ABUF_OFF_IDXW 2
#define I2S_ABUF_OFF_SIZE 4
#define I2S_ABUF_OFF_ARRAY 8
-#define I2S_IRQ_SD_ID INT_GPIO_BASE + I2S_PIN_INT
+#define I2S_IRQ_ID INT_GPIO_BASE + I2S_PIN_INT
#define I2S_CTRL_ADDR_CK PWM0_CTRL_ADDR
#define I2S_CTRL_ADDR_WS PWM1_CTRL_ADDR
diff --git a/fw/fe310/eos/soc/interrupt.c b/fw/fe310/eos/soc/interrupt.c
index dab6fab..2243f0a 100644
--- a/fw/fe310/eos/soc/interrupt.c
+++ b/fw/fe310/eos/soc/interrupt.c
@@ -1,13 +1,13 @@
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
-#include <stdio.h>
#include "encoding.h"
#include "platform.h"
#include "plic_driver.h"
#include "eos.h"
+#include "log.h"
#include "interrupt.h"
// Global Instance data for the PLIC
@@ -20,13 +20,13 @@ uintptr_t eos_intr_handle(uintptr_t int_num) {
if ((int_num >=1) && (int_num <= PLIC_NUM_INTERRUPTS) && (ext_interrupt_handler[int_num-1])) {
ext_interrupt_handler[int_num-1]();
} else {
- printf("INTR ERROR:%d\n", int_num);
+ EOS_LOG(EOS_LOG_ERR, "INTR ERROR:%d\n", int_num);
exit(int_num);
}
return int_num;
}
-int eos_intr_init(uint8_t wakeup_cause) {
+int eos_intr_init(void) {
for (int i = 0; i < PLIC_NUM_INTERRUPTS; i++){
ext_interrupt_handler[i] = NULL;
}
diff --git a/fw/fe310/eos/soc/interrupt.h b/fw/fe310/eos/soc/interrupt.h
index c6252b5..6cb446f 100644
--- a/fw/fe310/eos/soc/interrupt.h
+++ b/fw/fe310/eos/soc/interrupt.h
@@ -4,7 +4,7 @@
typedef void (*eos_intr_handler_t) (void);
-int eos_intr_init(uint8_t wakeup_cause);
+int eos_intr_init(void);
void eos_intr_set(uint8_t int_num, uint8_t priority, eos_intr_handler_t handler);
void eos_intr_set_handler(uint8_t int_num, eos_intr_handler_t handler);
void eos_intr_set_priority(uint8_t int_num, uint8_t priority);
diff --git a/fw/fe310/eos/soc/pwr.c b/fw/fe310/eos/soc/pwr.c
index db9f273..84915ef 100644
--- a/fw/fe310/eos/soc/pwr.c
+++ b/fw/fe310/eos/soc/pwr.c
@@ -12,8 +12,8 @@
#define PWR_RTC_SCALE 15
#define PWR_RTC_SFREQ (EOS_TIMER_RTC_FREQ >> PWR_RTC_SCALE)
-int eos_pwr_init(uint8_t wakeup_cause) {
- AON_REG(AON_PMUKEY) = 0x51F15E;
+int eos_pwr_init(void) {
+ AON_REG(AON_PMUKEY) = AON_WDOGKEY_VALUE;
AON_REG(AON_PMUIE) = 0x5;
AON_REG(AON_RTCCMP) = 0xFFFFFFFF;
@@ -33,7 +33,7 @@ uint8_t eos_pwr_reset_cause(void) {
}
void eos_pwr_sleep(void) {
- AON_REG(AON_PMUKEY) = 0x51F15E;
+ AON_REG(AON_PMUKEY) = AON_WDOGKEY_VALUE;
AON_REG(AON_PMUSLEEP) = 1;
}
@@ -43,8 +43,8 @@ void eos_pwr_wake_at(uint32_t msec) {
AON_REG(AON_RTCCFG) |= AON_RTCCFG_ENALWAYS;
AON_REG(AON_RTCCMP) = msec * PWR_RTC_SFREQ / 1000;
- pmuie = AON_REG(AON_PMUIE) | 0x2;
- AON_REG(AON_PMUKEY) = 0x51F15E;
+ pmuie = AON_REG(AON_PMUIE) | (1 << AON_WAKEUPCAUSE_RTC);
+ AON_REG(AON_PMUKEY) = AON_WDOGKEY_VALUE;
AON_REG(AON_PMUIE) = pmuie;
}
@@ -56,7 +56,7 @@ void eos_pwr_wake_disable(void) {
AON_REG(AON_RTCHI) = 0;
AON_REG(AON_RTCLO) = 0;
- pmuie = AON_REG(AON_PMUIE) & ~0x2;
- AON_REG(AON_PMUKEY) = 0x51F15E;
+ pmuie = AON_REG(AON_PMUIE) & ~(1 << AON_WAKEUPCAUSE_RTC);
+ AON_REG(AON_PMUKEY) = AON_WDOGKEY_VALUE;
AON_REG(AON_PMUIE) = pmuie;
}
diff --git a/fw/fe310/eos/soc/pwr.h b/fw/fe310/eos/soc/pwr.h
index 0af4c1b..8aeb0a8 100644
--- a/fw/fe310/eos/soc/pwr.h
+++ b/fw/fe310/eos/soc/pwr.h
@@ -2,13 +2,13 @@
#define EOS_PWR_WAKE_RST 0
#define EOS_PWR_WAKE_RTC 1
-#define EOS_PWR_WAKE_BTN 2
+#define EOS_PWR_WAKE_PIN 2
#define EOS_PWR_RST_PWRON 0
#define EOS_PWR_RST_EXT 1
#define EOS_PWR_RST_WDOG 2
-int eos_pwr_init(uint8_t wakeup_cause);
+int eos_pwr_init(void);
uint8_t eos_pwr_wakeup_cause(void);
uint8_t eos_pwr_reset_cause(void);
void eos_pwr_sleep(void);
diff --git a/fw/fe310/eos/soc/spi.c b/fw/fe310/eos/soc/spi.c
index 1806f50..64a057b 100644
--- a/fw/fe310/eos/soc/spi.c
+++ b/fw/fe310/eos/soc/spi.c
@@ -3,13 +3,16 @@
#include "encoding.h"
#include "platform.h"
+#include "board.h"
#include "eos.h"
+#include "log.h"
#include "msgq.h"
#include "interrupt.h"
#include "event.h"
-#include "board.h"
+#include "dev/egpio.h"
+#include "dev/egpio_priv.h"
#include "spi.h"
#include "spi_priv.h"
@@ -21,15 +24,12 @@
#define SPI_FLAG_XCHG 0x10
-#define SPI_CSID_NONE 1
-
#define MIN(X, Y) (((X) < (Y)) ? (X) : (Y))
#define MAX(X, Y) (((X) > (Y)) ? (X) : (Y))
static uint8_t spi_cspin;
static volatile uint8_t spi_state_flags;
static unsigned char spi_evt;
-static unsigned char spi_in_xchg;
static uint32_t spi_state_len = 0;
static uint32_t spi_state_idx_tx = 0;
@@ -40,6 +40,7 @@ static eos_evt_handler_t evt_handler[EOS_SPI_MAX_EVT];
static void spi_handle_evt(unsigned char type, unsigned char *buffer, uint16_t len) {
unsigned char idx = (type & ~EOS_EVT_MASK) - 1;
+
if (idx < EOS_SPI_MAX_EVT) {
evt_handler[idx](type, buffer, len);
} else {
@@ -47,7 +48,7 @@ static void spi_handle_evt(unsigned char type, unsigned char *buffer, uint16_t l
}
}
-int eos_spi_init(uint8_t wakeup_cause) {
+int eos_spi_init(void) {
int i;
for (i=0; i<EOS_SPI_MAX_EVT; i++) {
@@ -63,31 +64,31 @@ int eos_spi_init(uint8_t wakeup_cause) {
SPI_FMT_DIR(SPI_DIR_RX) |
SPI_FMT_LEN(8);
- /* for spi 9bit protocol */
- GPIO_REG(GPIO_OUTPUT_EN) |= (1 << IOF_SPI1_SCK);
- GPIO_REG(GPIO_OUTPUT_EN) |= (1 << IOF_SPI1_MOSI);
- GPIO_REG(GPIO_INPUT_EN) |= (1 << IOF_SPI1_MISO);
+ /* CS assert to SCK: 1 clock cycles
+ SCK to CS deassert: 0 clock cycles */
+ SPI1_REG(SPI_REG_DCSSCK) = 0x01;
+
+ GPIO_REG(GPIO_OUTPUT_XOR) |= SPI_IOF_CSXOR;
eos_spi_enable();
return EOS_OK;
}
-void eos_spi_configure(uint16_t div, int8_t csid, int8_t cspin, unsigned char evt) {
+void eos_spi_configure(uint16_t div, uint8_t csid, uint8_t cspin, unsigned char evt) {
spi_state_flags = 0;
spi_evt = evt;
SPI1_REG(SPI_REG_SCKDIV) = div;
- if (csid != -1) {
- SPI1_REG(SPI_REG_CSID) = csid;
+ SPI1_REG(SPI_REG_CSID) = csid;
+ if (csid != SPI_CSID_NONE) {
SPI1_REG(SPI_REG_CSMODE) = SPI_CSMODE_AUTO;
} else {
spi_cspin = cspin;
- SPI1_REG(SPI_REG_CSID) = SPI_CSID_NONE;
SPI1_REG(SPI_REG_CSMODE) = SPI_CSMODE_OFF;
}
}
-void eos_spi_start(uint16_t div, int8_t csid, int8_t cspin, unsigned char evt) {
+void eos_spi_start(uint16_t div, uint8_t csid, uint8_t cspin, unsigned char evt) {
eos_spi_configure(div, csid, cspin, evt);
eos_intr_set_handler(INT_SPI1_BASE, eos_spi_handle_xchg);
}
@@ -126,7 +127,7 @@ void _eos_spi_xchg_init(unsigned char *buffer, uint16_t len, uint8_t flags) {
}
static void spi_wait4xchg(void) {
- uint8_t done = 0;
+ int done = 0;
while (!done) {
clear_csr(mstatus, MSTATUS_MIE);
@@ -134,23 +135,25 @@ static void spi_wait4xchg(void) {
if (!done) asm volatile ("wfi");
set_csr(mstatus, MSTATUS_MIE);
}
- spi_in_xchg = 0;
}
-void eos_spi_xchg(unsigned char *buffer, uint16_t len, uint8_t flags) {
- if (spi_in_xchg) spi_wait4xchg();
+int eos_spi_xchg(unsigned char *buffer, uint16_t len, uint8_t flags) {
+ if (!spi_evt) return EOS_ERR;
+
+ spi_wait4xchg();
- spi_in_xchg = 1;
_eos_spi_xchg_init(buffer, len, flags);
- eos_spi_cs_set();
+ eos_spi_set_cs();
SPI1_REG(SPI_REG_TXCTRL) = SPI_TXWM(SPI_SIZE_WM);
SPI1_REG(SPI_REG_IE) = SPI_IP_TXWM;
+
+ return EOS_OK;
}
void eos_spi_handle_xchg(void) {
- int i;
uint16_t sz_chunk = MIN(spi_state_len - spi_state_idx_tx, SPI_SIZE_CHUNK);
+ int i;
for (i=0; i<sz_chunk; i++) {
volatile uint32_t x = SPI1_REG(SPI_REG_TXFIFO);
@@ -174,10 +177,18 @@ void eos_spi_handle_xchg(void) {
SPI1_REG(SPI_REG_TXCTRL) = SPI_TXWM(1);
return;
}
- spi_state_flags &= ~SPI_FLAG_XCHG;
- if (!(spi_state_flags & EOS_SPI_FLAG_MORE)) eos_spi_cs_clear();
- SPI1_REG(SPI_REG_IE) = 0x0;
- if (spi_evt) eos_evtq_push_isr(EOS_EVT_SPI | spi_evt, spi_state_buf, spi_state_len);
+ SPI1_REG(SPI_REG_IE) = 0;
+ if (!(spi_state_flags & EOS_SPI_FLAG_MORE)) eos_spi_clear_cs();
+
+ /* clear SPI_FLAG_XCHG flag and all of EOS_SPI_FLAG_* */
+ spi_state_flags &= (~SPI_FLAG_XCHG & 0xF0);
+
+ if (spi_evt) {
+ int rv;
+
+ rv = eos_evtq_push_isr(EOS_EVT_SPI | spi_evt, spi_state_buf, spi_state_len);
+ if (rv) EOS_LOG(EOS_LOG_ERR, "SPI XCHG EVTQ PUSH ERR:%d\n", rv);
+ }
} else {
SPI1_REG(SPI_REG_RXCTRL) = SPI_RXWM(MIN(spi_state_len - spi_state_idx_rx - 1, SPI_SIZE_WM - 1));
SPI1_REG(SPI_REG_IE) = SPI_IP_RXWM;
@@ -185,23 +196,40 @@ void eos_spi_handle_xchg(void) {
}
}
-void eos_spi_cs_set(void) {
- /* cs low */
+int eos_spi_get_cs(void) {
if (SPI1_REG(SPI_REG_CSMODE) == SPI_CSMODE_OFF) {
- clear_csr(mstatus, MSTATUS_MIE);
- GPIO_REG(GPIO_OUTPUT_VAL) &= ~(1 << spi_cspin);
- set_csr(mstatus, MSTATUS_MIE);
+ if (spi_cspin & SPI_CSFLAG_EGPIO) {
+ return !eos_egpio_get_val(spi_cspin & ~SPI_CSFLAG_EGPIO);
+ } else {
+ return !(GPIO_REG(GPIO_OUTPUT_VAL) & (1 << spi_cspin));
+ }
+ } else {
+ return (SPI1_REG(SPI_REG_CSMODE) == SPI_CSMODE_HOLD);
+ }
+}
+
+void eos_spi_set_cs(void) {
+ /* cs low */
+ if (SPI1_REG(SPI_REG_CSMODE) == SPI_CSMODE_OFF) {
+ if (spi_cspin & SPI_CSFLAG_EGPIO) {
+ eos_egpio_set_val(spi_cspin & ~SPI_CSFLAG_EGPIO, 0);
+ } else {
+ GPIO_REG(GPIO_OUTPUT_VAL) &= ~(1 << spi_cspin);
+ }
} else {
SPI1_REG(SPI_REG_CSMODE) = SPI_CSMODE_HOLD;
}
}
-void eos_spi_cs_clear(void) {
- /* cs high */
+/* can be called from interrupt handler */
+void eos_spi_clear_cs(void) {
+ /* cs high */
if (SPI1_REG(SPI_REG_CSMODE) == SPI_CSMODE_OFF) {
- clear_csr(mstatus, MSTATUS_MIE);
- GPIO_REG(GPIO_OUTPUT_VAL) |= (1 << spi_cspin);
- set_csr(mstatus, MSTATUS_MIE);
+ if (spi_cspin & SPI_CSFLAG_EGPIO) {
+ eos_egpio_set_val(spi_cspin & ~SPI_CSFLAG_EGPIO, 1);
+ } else {
+ GPIO_REG(GPIO_OUTPUT_VAL) |= (1 << spi_cspin);
+ }
} else {
SPI1_REG(SPI_REG_CSMODE) = SPI_CSMODE_AUTO;
}
@@ -360,11 +388,18 @@ uint32_t eos_spi_xchg32(uint32_t data, uint8_t flags) {
}
void eos_spi_flush(void) {
- if (spi_in_xchg) {
- spi_wait4xchg();
- } else {
- SPI1_REG(SPI_REG_TXCTRL) = SPI_TXWM(1);
- while (!(SPI1_REG(SPI_REG_IP) & SPI_IP_TXWM));
- while (!(SPI1_REG(SPI_REG_RXFIFO) & SPI_RXFIFO_EMPTY));
- }
+ uint32_t mcycle_start, mcycle_wait;
+
+ spi_wait4xchg();
+
+ SPI1_REG(SPI_REG_TXCTRL) = SPI_TXWM(1);
+ while (!(SPI1_REG(SPI_REG_IP) & SPI_IP_TXWM));
+
+ /* wait for last frame to be transmitted: 9 spi clock cycles */
+ mcycle_wait = 9*2*((SPI1_REG(SPI_REG_SCKDIV) & 0xFFF)+1);
+ mcycle_start = read_csr(mcycle);
+
+ while ((read_csr(mcycle) - mcycle_start) < mcycle_wait);
+
+ while (!(SPI1_REG(SPI_REG_RXFIFO) & SPI_RXFIFO_EMPTY));
}
diff --git a/fw/fe310/eos/soc/spi.h b/fw/fe310/eos/soc/spi.h
index 0c2de4b..20999b5 100644
--- a/fw/fe310/eos/soc/spi.h
+++ b/fw/fe310/eos/soc/spi.h
@@ -1,4 +1,5 @@
#include <stdint.h>
+
#include "../event.h"
#define EOS_SPI_FLAG_TX 0x01
@@ -10,9 +11,9 @@
#define EOS_SPI_MAX_EVT 2
-int eos_spi_init(uint8_t wakeup_cause);
-void eos_spi_configure(uint16_t div, int8_t csid, int8_t cspin, unsigned char evt);
-void eos_spi_start(uint16_t div, int8_t csid, int8_t cspin, unsigned char evt);
+int eos_spi_init(void);
+void eos_spi_configure(uint16_t div, uint8_t csid, uint8_t cspin, unsigned char evt);
+void eos_spi_start(uint16_t div, uint8_t csid, uint8_t cspin, unsigned char evt);
void eos_spi_stop(void);
void eos_spi_enable(void);
void eos_spi_disable(void);
@@ -20,11 +21,12 @@ void eos_spi_disable(void);
void eos_spi_set_handler(unsigned char evt, eos_evt_handler_t handler);
void _eos_spi_xchg_init(unsigned char *buffer, uint16_t len, uint8_t flags);
-void eos_spi_xchg(unsigned char *buffer, uint16_t len, uint8_t flags);
+int eos_spi_xchg(unsigned char *buffer, uint16_t len, uint8_t flags);
void eos_spi_handle_xchg(void);
-void eos_spi_cs_set(void);
-void eos_spi_cs_clear(void);
+int eos_spi_get_cs(void);
+void eos_spi_set_cs(void);
+void eos_spi_clear_cs(void);
uint8_t eos_spi_xchg8(uint8_t data, uint8_t flags);
uint16_t eos_spi_xchg16(uint16_t data, uint8_t flags);
uint32_t eos_spi_xchg24(uint32_t data, uint8_t flags);
diff --git a/fw/fe310/eos/soc/spi9bit.c b/fw/fe310/eos/soc/spi9bit.c
index e48e9e2..a536637 100644
--- a/fw/fe310/eos/soc/spi9bit.c
+++ b/fw/fe310/eos/soc/spi9bit.c
@@ -11,10 +11,10 @@
#include "spi9bit.h"
#define BIT_GET ((GPIO_REG(GPIO_INPUT_VAL) & (1 << IOF_SPI1_MISO)) >> IOF_SPI1_MISO)
-#define BIT_PUT(b) { clear_csr(mstatus, MSTATUS_MIE); if (b) GPIO_REG(GPIO_OUTPUT_VAL) |= (1 << IOF_SPI1_MOSI); else GPIO_REG(GPIO_OUTPUT_VAL) &= ~(1 << IOF_SPI1_MOSI); set_csr(mstatus, MSTATUS_MIE); }
+#define BIT_PUT(b) { if (b) GPIO_REG(GPIO_OUTPUT_VAL) |= (1 << IOF_SPI1_MOSI); else GPIO_REG(GPIO_OUTPUT_VAL) &= ~(1 << IOF_SPI1_MOSI); }
-#define SCK_UP { clear_csr(mstatus, MSTATUS_MIE); GPIO_REG(GPIO_OUTPUT_VAL) |= (1 << IOF_SPI1_SCK); set_csr(mstatus, MSTATUS_MIE); }
-#define SCK_DN { clear_csr(mstatus, MSTATUS_MIE); GPIO_REG(GPIO_OUTPUT_VAL) &= ~(1 << IOF_SPI1_SCK); set_csr(mstatus, MSTATUS_MIE); }
+#define SCK_UP { GPIO_REG(GPIO_OUTPUT_VAL) |= (1 << IOF_SPI1_SCK); }
+#define SCK_DN { GPIO_REG(GPIO_OUTPUT_VAL) &= ~(1 << IOF_SPI1_SCK); }
static inline void _sleep(int n) {
volatile int x = n;
@@ -22,7 +22,19 @@ static inline void _sleep(int n) {
while(x) x--;
}
-/* sck frequency for r/w operations is 0.8Mhz */
+void eos_spi9bit_start(void) {
+ GPIO_REG(GPIO_OUTPUT_EN) |= (1 << IOF_SPI1_SCK);
+ GPIO_REG(GPIO_OUTPUT_EN) |= (1 << IOF_SPI1_MOSI);
+ GPIO_REG(GPIO_INPUT_EN) |= (1 << IOF_SPI1_MISO);
+}
+
+void eos_spi9bit_stop(void) {
+ GPIO_REG(GPIO_OUTPUT_EN) &= ~(1 << IOF_SPI1_SCK);
+ GPIO_REG(GPIO_OUTPUT_EN) &= ~(1 << IOF_SPI1_MOSI);
+ GPIO_REG(GPIO_INPUT_EN) &= ~(1 << IOF_SPI1_MISO);
+}
+
+/* sck frequency for r/w operations is ~ 0.8Mhz */
void eos_spi9bit_read(uint8_t *data) {
int i;
diff --git a/fw/fe310/eos/soc/spi9bit.h b/fw/fe310/eos/soc/spi9bit.h
index dd3c254..fb89856 100644
--- a/fw/fe310/eos/soc/spi9bit.h
+++ b/fw/fe310/eos/soc/spi9bit.h
@@ -1,4 +1,6 @@
#include <stdint.h>
+void eos_spi9bit_start(void);
+void eos_spi9bit_stop(void);
void eos_spi9bit_read(uint8_t *data);
void eos_spi9bit_write(uint8_t dc, uint8_t data);
diff --git a/fw/fe310/eos/soc/spi_priv.h b/fw/fe310/eos/soc/spi_priv.h
index 17081a3..20e4088 100644
--- a/fw/fe310/eos/soc/spi_priv.h
+++ b/fw/fe310/eos/soc/spi_priv.h
@@ -3,3 +3,6 @@
/* DO NOT TOUCH THEESE */
#define SPI_SIZE_CHUNK 4
#define SPI_SIZE_WM 2
+
+#define SPI_CSFLAG_EGPIO 0x80
+#define SPI_CSID_NONE 1
diff --git a/fw/fe310/eos/soc/timer.c b/fw/fe310/eos/soc/timer.c
index 8d74c6d..0573e84 100644
--- a/fw/fe310/eos/soc/timer.c
+++ b/fw/fe310/eos/soc/timer.c
@@ -48,7 +48,7 @@ void _eos_timer_handle(void) {
if (*mtimecmp == 0) clear_csr(mie, MIP_MTIP);
}
-int eos_timer_init(uint8_t wakeup_cause) {
+int eos_timer_init(void) {
uint64_t *mtimecmp = (uint64_t *) (CLINT_CTRL_ADDR + CLINT_MTIMECMP);
int i;
@@ -75,18 +75,18 @@ uint32_t eos_timer_get(unsigned char evt) {
volatile uint64_t *mtime = (uint64_t *) (CLINT_CTRL_ADDR + CLINT_MTIME);
uint64_t *mtimecmp = (uint64_t *) (CLINT_CTRL_ADDR + CLINT_MTIMECMP);
uint64_t now;
- uint32_t ret;
+ uint32_t rv;
if (*mtimecmp != 0) clear_csr(mie, MIP_MTIP);
now = *mtime;
if (timer_next[evt]) {
- ret = (timer_next[evt] > now) ? (timer_next[evt] - now) * 1000 / EOS_TIMER_RTC_FREQ : 0;
+ rv = (timer_next[evt] > now) ? (timer_next[evt] - now) * 1000 / EOS_TIMER_RTC_FREQ : 0;
} else {
- ret = EOS_TIMER_NONE;
+ rv = EOS_TIMER_NONE;
}
if (*mtimecmp != 0) set_csr(mie, MIP_MTIP);
- return ret;
+ return rv;
}
void eos_timer_set(unsigned char evt, uint32_t msec) {
@@ -121,24 +121,24 @@ void eos_timer_clear(unsigned char evt) {
if (*mtimecmp != 0) set_csr(mie, MIP_MTIP);
}
-void eos_time_sleep(uint32_t msec) {
+void eos_sleep(uint32_t msec) {
volatile uint64_t *mtime = (uint64_t *) (CLINT_CTRL_ADDR + CLINT_MTIME);
uint32_t mtime0 = *mtime;
while ((*mtime - mtime0) < (msec * EOS_TIMER_RTC_FREQ / 1000 + 1));
}
-uint32_t eos_time_get_tick(void) {
+uint32_t eos_get_tick(void) {
volatile uint64_t *mtime = (uint64_t *) (CLINT_CTRL_ADDR + CLINT_MTIME);
return *mtime;
}
-uint64_t eos_time_get_tick64(void) {
+uint64_t eos_get_tick64(void) {
volatile uint64_t *mtime = (uint64_t *) (CLINT_CTRL_ADDR + CLINT_MTIME);
return *mtime;
}
-uint32_t eos_time_delta_ms(uint32_t tick) {
- return (eos_time_get_tick() - tick) * 1000 / EOS_TIMER_RTC_FREQ;
+uint32_t eos_tdelta_ms(uint32_t tick) {
+ return (eos_get_tick() - tick) * 1000 / EOS_TIMER_RTC_FREQ;
}
diff --git a/fw/fe310/eos/soc/timer.h b/fw/fe310/eos/soc/timer.h
index 227aeee..f5c7b4e 100644
--- a/fw/fe310/eos/soc/timer.h
+++ b/fw/fe310/eos/soc/timer.h
@@ -12,14 +12,14 @@
typedef void (*eos_timer_handler_t) (unsigned char);
-int eos_timer_init(uint8_t wakeup_cause);
+int eos_timer_init(void);
void eos_timer_set_handler(unsigned char evt, eos_timer_handler_t handler);
uint32_t eos_timer_get(unsigned char evt);
void eos_timer_set(unsigned char evt, uint32_t msec);
void eos_timer_clear(unsigned char evt);
-void eos_time_sleep(uint32_t msec);
-uint32_t eos_time_get_tick(void);
-uint64_t eos_time_get_tick64(void);
-uint32_t eos_time_delta_ms(uint32_t tick);
+void eos_sleep(uint32_t msec);
+uint32_t eos_get_tick(void);
+uint64_t eos_get_tick64(void);
+uint32_t eos_tdelta_ms(uint32_t tick);
diff --git a/fw/fe310/eos/soc/trap_entry.S b/fw/fe310/eos/soc/trap_entry.S
index 98f9267..19f4502 100644
--- a/fw/fe310/eos/soc/trap_entry.S
+++ b/fw/fe310/eos/soc/trap_entry.S
@@ -28,12 +28,10 @@
#define INT_PWM1_BASE 44
#define INT_PWM2_BASE 48
-#define I2S_FMT (0*4)
-#define I2S_MODE (1*4)
-#define I2S_MIC_WM (2*4)
-#define I2S_SPK_WM (3*4)
-#define I2S_MIC_EVT (4*4)
-#define I2S_SPK_EVT (5*4)
+#define I2S_MIC_WM (0*4)
+#define I2S_SPK_WM (1*4)
+#define I2S_MIC_EVT (2*4)
+#define I2S_SPK_EVT (3*4)
#include "board.h"
#include "irq_def.h"
@@ -57,8 +55,8 @@ eos_trap_vector:
STORE x22, 6*REGBYTES(sp)
STORE x23, 7*REGBYTES(sp)
STORE x24, 8*REGBYTES(sp)
- STORE x25, 9*REGBYTES(sp) # channel: 0 - left; 1 - right
- STORE x26, 10*REGBYTES(sp) # format: 0 - PCM16; 1 - ALAW
+ STORE x25, 9*REGBYTES(sp)
+ STORE x26, 10*REGBYTES(sp) # unused
STORE x27, 11*REGBYTES(sp) # _eos_i2s_drvr addr
csrr x8, mcause
@@ -66,7 +64,7 @@ eos_trap_vector:
bne x8, x18, handle_intr
li x18, PLIC_CLAIM
lw x9, 0(x18)
- li x18, I2S_IRQ_SD_ID
+ li x18, I2S_IRQ_ID
beq x9, x18, i2s_handle_sd
j handle_intr
@@ -82,30 +80,22 @@ evtq_push:
addi x20, x20, -1
and x20, x20, x19
+
+ addi x19, x19, 1
+ sb x19, MSGQ_OFF_IDXW(x9)
+
li x18, MSGQ_ITEM_SIZE
mul x20, x20, x18
lw x21, MSGQ_OFF_ARRAY(x9)
add x21, x21, x20
-
- addi x19, x19, 1
- sb x19, MSGQ_OFF_IDXW(x9)
jalr x0, x22
0:
- mv x20, x0
- jalr x0, x21
+ mv x21, x0
+ jalr x0, x22
i2s_handle_sd:
- # store channel bit to x25
- li x18, I2S_CTRL_ADDR_WS
- lw x18, PWM_CFG(x18)
- # 29th - pwmcmp1ip bit
- li x19, (1 << 29)
- and x25, x18, x19
- srli x25, x25, 29
-
la x27, _eos_i2s_drvr
- lw x26, I2S_FMT(x27)
i2s_abuf_pop:
# pop from spk buf -> x8
@@ -115,107 +105,55 @@ i2s_abuf_pop:
lhu x20, I2S_ABUF_OFF_SIZE(x9)
beqz x20, i2s_sd_xchg
- beq x18, x19, 2f
+ beq x18, x19, 0f
addi x20, x20, -1
and x20, x20, x18
- lw x21, I2S_ABUF_OFF_ARRAY(x9)
- add x21, x21, x20
- beqz x26, 0f
- mv x22, x18
- lbu x8, 0(x21)
+
addi x18, x18, 1
- j 1f
-0:
- srli x22, x18, 1
- lb x8, 0(x21)
- lbu x20, 1(x21)
- slli x8, x8, 8
- or x8, x8, x20
- addi x18, x18, 2
-1:
sh x18, I2S_ABUF_OFF_IDXR(x9)
- # check if buf data is for correct channel if mode is stereo
- lw x21, I2S_MODE(x27)
- bnez x21, 2f
- andi x22, x22, 1
- xor x22, x22, x25
- beqz x22, i2s_abuf_pop
+ # uint16_t array
+ slli x20, x20, 1
+ lw x21, I2S_ABUF_OFF_ARRAY(x9)
+ add x21, x21, x20
+ lh x8, 0(x21)
-2:
+0:
li x21, 0xffff
sub x18, x19, x18
and x18, x18, x21
# check for push to event queue
lw x9, I2S_SPK_WM(x27)
- bgtu x18, x9, i2s_decode
+ bgtu x18, x9, i2s_sd_xchg
lw x9, I2S_SPK_EVT(x27)
- beqz x9, i2s_decode
+ beqz x9, i2s_sd_xchg
sw x0, I2S_SPK_EVT(x27)
# push to event queue
jal x22, evtq_push
- beqz x21, i2s_decode
+ beqz x21, i2s_sd_xchg
li x18, (EOS_EVT_I2S | EOS_I2S_ETYPE_SPK)
sb x18, MSGQ_ITEM_OFF_TYPE(x21)
-i2s_decode:
- beqz x26, 3f
- # aLaw decode -> x8
- xori x8, x8, 0x55
- andi x9, x8, 0x80
- beqz x9, 0f
- li x9, (1 << 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:
-
i2s_sd_xchg:
# read/write shift reg: x8 -> sr -> x8
+ # values of GPIO_OUTPUT_EN, GPIO_INPUT_EN, GPIO_OUTPUT_VAL registers are NOT changed (no need for clear_csr / set_csr guards outside of interrupt)
li x18, GPIO_CTRL_ADDR
li x19, (1 << I2S_PIN_SD_IN)
li x20, (1 << I2S_PIN_SD_OUT)
li x21, (1 << I2S_PIN_SR_CK)
lw x22, GPIO_OUTPUT_VAL(x18)
- # disable intpu, enable output for I2S_PIN_SD_OUT (pin is low)
- lw x9, GPIO_OUTPUT_EN(x18)
- or x9, x9, x20
+ # disable intput, enable output for I2S_PIN_SD_OUT (pin is low)
+ lw x24, GPIO_OUTPUT_EN(x18)
+ or x9, x24, x20
sw x9, GPIO_OUTPUT_EN(x18)
not x20, x20
- lw x9, GPIO_INPUT_EN(x18)
- and x9, x9, x20
+ lw x25, GPIO_INPUT_EN(x18)
+ and x9, x25, x20
sw x9, GPIO_INPUT_EN(x18)
# I2S_PIN_SR_CK bit low (was high)
@@ -268,58 +206,19 @@ i2s_sd_xchg:
addi x23, x23, -1
bnez x23, 0b
- # I2S_PIN_SD_OUT pin low (has pull-dn)
+ # I2S_PIN_SD_OUT pin low (was low)
and x22, x22, x20
# I2S_PIN_SR_CK pin high (74HC595 ck low)
xor x22, x22, x21
sw x22, GPIO_OUTPUT_VAL(x18)
- # disable output, enable input for I2S_PIN_SD_OUT
- lw x9, GPIO_OUTPUT_EN(x18)
- xor x9, x9, x20
- sw x9, GPIO_OUTPUT_EN(x18)
- lw x9, GPIO_INPUT_EN(x18)
- xor x9, x9, x20
- sw x9, GPIO_INPUT_EN(x18)
+ # restore input/output for I2S_PIN_SD_OUT
+ sw x24, GPIO_OUTPUT_EN(x18)
+ sw x25, GPIO_INPUT_EN(x18)
slli x8, x8, 16
srai x8, x8, 16
- # skip right mic channel
- bnez x25, i2s_sd_complete
-
-i2s_encode:
- beqz x26, i2s_abuf_push
- # aLaw encode -> x8
- li x18, 0x800
- li x19, 7
- bgez x8, 0f
- neg x8, x8
- lui x9, 0x80000
- or x8, x8, x9
-0:
- and x9, x8, x18
- beq x9, x18, 1f
- beqz x19, 1f
- srli x18, x18, 1
- addi x19, x19, -1
- j 0b
-1:
- mv x9, x19
- bnez x9, 2f
- addi x9, x9, 1
-2:
- sra x8, x8, x9
- li x9, 0x8000000f
- and x8, x8, x9
- slli x19, x19, 4
- or x8, x8, x19
- bgez x8, 3f
- ori x8, x8, 0x80
-3:
- xori x8, x8, 0x55
- andi x8, x8, 0xff
-
i2s_abuf_push:
# push to mic buf
la x9, _eos_i2s_mic_buf
@@ -331,27 +230,22 @@ i2s_abuf_push:
sub x18, x19, x18
and x18, x18, x21
- beq x18, x20, 2f
+ beq x18, x20, 0f
addi x20, x20, -1
and x20, x20, x19
+
+ addi x19, x19, 1
+ sh x19, I2S_ABUF_OFF_IDXW(x9)
+
+ # uint16_t array
+ slli x20, x20, 1
lw x21, I2S_ABUF_OFF_ARRAY(x9)
add x21, x21, x20
- beqz x26, 0f
- sb x8, 0(x21)
- addi x19, x19, 1
+ sh x8, 0(x21)
addi x18, x18, 1
- j 1f
-0:
- sb x8, 1(x21)
- srli x8, x8, 8
- sb x8, 0(x21)
- addi x19, x19, 2
- addi x18, x18, 2
-1:
- sh x19, I2S_ABUF_OFF_IDXW(x9)
-2:
+0:
# check for push to event queue
lw x9, I2S_MIC_WM(x27)
bltu x18, x9, i2s_sd_complete
@@ -371,7 +265,7 @@ i2s_sd_complete:
li x19, (1 << I2S_PIN_INT)
sw x19, GPIO_FALL_IP(x18)
- li x18, I2S_IRQ_SD_ID
+ li x18, I2S_IRQ_ID
li x19, PLIC_CLAIM
sw x18, 0(x19)
@@ -393,7 +287,8 @@ _eos_i2s_start_pwm:
li x18, I2S_CTRL_ADDR_CK
li x19, I2S_CTRL_ADDR_WS
li x20, I2S_CTRL_ADDR_SR_SEL
- li x21, PWM_CFG_ENALWAYS | PWM_CFG_ZEROCMP | I2S_PWM_SCALE_CK
+ li x21, PWM_CFG_ENALWAYS | PWM_CFG_ZEROCMP
+ or x21, x21, a0
li x22, PWM_CFG_ENALWAYS | PWM_CFG_ZEROCMP | PWM_CFG_CMP2GANG
li x23, PWM_CFG_ENALWAYS | PWM_CFG_ZEROCMP | PWM_CFG_CMP1GANG
sw x21, PWM_CFG(x18)
@@ -414,8 +309,8 @@ _eos_i2s_start_pwm:
trap_exit_data:
# Remain in M-mode after mret
- li x18, MSTATUS_MPP
- csrs mstatus, x18
+ # li x18, MSTATUS_MPP
+ # csrs mstatus, x18
LOAD x8, 0*REGBYTES(sp)
LOAD x9, 1*REGBYTES(sp)
@@ -483,8 +378,8 @@ handle_ext:
trap_exit_text:
# Remain in M-mode after mret
- li t0, MSTATUS_MPP
- csrs mstatus, t0
+ # li t0, MSTATUS_MPP
+ # csrs mstatus, t0
LOAD x1, 0*REGBYTES(sp)
LOAD x2, 1*REGBYTES(sp)
diff --git a/fw/fe310/eos/soc/uart.c b/fw/fe310/eos/soc/uart.c
index 1cff781..44c9a52 100644
--- a/fw/fe310/eos/soc/uart.c
+++ b/fw/fe310/eos/soc/uart.c
@@ -36,7 +36,12 @@ static void uart_handle_intr(void) {
}
}
-int eos_uart_init(uint8_t wakeup_cause) {
+void eos_uart_preinit(void) {
+ eos_uart_speed(EOS_UART_SPEED);
+ eos_uart_enable();
+}
+
+int eos_uart_init(void) {
int i;
for (i=0; i<EOS_UART_MAX_ETYPE; i++) {
@@ -45,10 +50,6 @@ int eos_uart_init(uint8_t wakeup_cause) {
eos_evtq_set_handler(EOS_EVT_UART, uart_handle_evt);
eos_intr_set(INT_UART0_BASE, IRQ_PRIORITY_UART, uart_handle_intr);
- eos_uart_speed(EOS_UART_SPEED);
-
- eos_uart_enable();
-
return EOS_OK;
}
diff --git a/fw/fe310/eos/soc/uart.h b/fw/fe310/eos/soc/uart.h
index 41329fb..474942d 100644
--- a/fw/fe310/eos/soc/uart.h
+++ b/fw/fe310/eos/soc/uart.h
@@ -9,7 +9,8 @@
typedef void (*eos_uart_handler_t) (unsigned char);
-int eos_uart_init(uint8_t wakeup_cause);
+void eos_uart_preinit(void);
+int eos_uart_init(void);
void eos_uart_enable(void);
void eos_uart_disable(void);
int eos_uart_enabled(void);