diff options
Diffstat (limited to 'fw/fe310/eos/soc')
-rw-r--r-- | fw/fe310/eos/soc/Makefile | 2 | ||||
-rw-r--r-- | fw/fe310/eos/soc/aon.c | 46 | ||||
-rw-r--r-- | fw/fe310/eos/soc/aon.h | 5 | ||||
-rw-r--r-- | fw/fe310/eos/soc/gpio.c | 20 | ||||
-rw-r--r-- | fw/fe310/eos/soc/gpio.h | 5 | ||||
-rw-r--r-- | fw/fe310/eos/soc/i2c.c | 2 | ||||
-rw-r--r-- | fw/fe310/eos/soc/i2c.h | 2 | ||||
-rw-r--r-- | fw/fe310/eos/soc/i2s.c | 355 | ||||
-rw-r--r-- | fw/fe310/eos/soc/i2s.h | 34 | ||||
-rw-r--r-- | fw/fe310/eos/soc/i2s_def.h | 11 | ||||
-rw-r--r-- | fw/fe310/eos/soc/i2s_priv.h | 5 | ||||
-rw-r--r-- | fw/fe310/eos/soc/interrupt.c | 6 | ||||
-rw-r--r-- | fw/fe310/eos/soc/interrupt.h | 2 | ||||
-rw-r--r-- | fw/fe310/eos/soc/pwr.c | 14 | ||||
-rw-r--r-- | fw/fe310/eos/soc/pwr.h | 4 | ||||
-rw-r--r-- | fw/fe310/eos/soc/spi.c | 119 | ||||
-rw-r--r-- | fw/fe310/eos/soc/spi.h | 14 | ||||
-rw-r--r-- | fw/fe310/eos/soc/spi9bit.c | 20 | ||||
-rw-r--r-- | fw/fe310/eos/soc/spi9bit.h | 2 | ||||
-rw-r--r-- | fw/fe310/eos/soc/spi_priv.h | 3 | ||||
-rw-r--r-- | fw/fe310/eos/soc/timer.c | 20 | ||||
-rw-r--r-- | fw/fe310/eos/soc/timer.h | 10 | ||||
-rw-r--r-- | fw/fe310/eos/soc/trap_entry.S | 205 | ||||
-rw-r--r-- | fw/fe310/eos/soc/uart.c | 11 | ||||
-rw-r--r-- | fw/fe310/eos/soc/uart.h | 3 |
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); |