From a0059ab4365f41c84bb8bdf914477f5d4feeb985 Mon Sep 17 00:00:00 2001 From: Uros Majstorovic Date: Fri, 21 Apr 2023 21:13:50 +0200 Subject: improved i2s driver --- fw/fe310/eos/soc/i2s.c | 109 +++++++++++++++++++++++--------------- fw/fe310/eos/soc/i2s.h | 16 +++--- fw/fe310/eos/soc/i2s_def.h | 5 ++ fw/fe310/eos/soc/trap_entry.S | 25 ++++++--- fw/fe310/phone/ecp.c | 2 +- fw/fe310/phone/phone.c | 120 ++++++++++++++++++++++++++++++++++++------ 6 files changed, 202 insertions(+), 75 deletions(-) (limited to 'fw/fe310') diff --git a/fw/fe310/eos/soc/i2s.c b/fw/fe310/eos/soc/i2s.c index 8416ec1..052efa2 100644 --- a/fw/fe310/eos/soc/i2s.c +++ b/fw/fe310/eos/soc/i2s.c @@ -192,9 +192,6 @@ void eos_i2s_start(uint32_t sample_rate) { I2S_REG_WS(PWM_COUNT) = 0; I2S_REG_SR_SEL(PWM_COUNT) = 0; - if (i2s_mic_handler) _eos_i2s_drvr[I2S_MIC_EVT] = 1; - if (i2s_spk_handler) _eos_i2s_drvr[I2S_SPK_EVT] = 1; - eos_eve_intr_disable(); eos_uart_disable(); eos_intr_set_priority(I2S_IRQ_SD_ID, IRQ_PRIORITY_I2S_SD); @@ -207,20 +204,11 @@ void eos_i2s_start(uint32_t sample_rate) { iof_mask = I2S_PIN_PWM; if (_eos_i2s_mic_buf.size == 0) { iof_mask &= ~(1 << I2S_PIN_WS_MIC); - GPIO_REG(GPIO_OUTPUT_VAL) &= ~(1 << I2S_PIN_WS_MIC); - GPIO_REG(GPIO_OUTPUT_EN) |= (1 << I2S_PIN_WS_MIC); - } else if (_eos_i2s_drvr[I2S_MIC_WM] == 0) { - _eos_i2s_drvr[I2S_MIC_WM] = _eos_i2s_mic_buf.size / 2; } if (_eos_i2s_spk_buf.size == 0) { iof_mask &= ~(1 << I2S_PIN_WS_SPK); - GPIO_REG(GPIO_OUTPUT_VAL) &= ~(1 << I2S_PIN_SD_OUT); - GPIO_REG(GPIO_OUTPUT_VAL) &= ~(1 << I2S_PIN_WS_SPK); - GPIO_REG(GPIO_OUTPUT_EN) |= (1 << I2S_PIN_WS_SPK); - } else if (_eos_i2s_drvr[I2S_SPK_WM] == 0) { - _eos_i2s_drvr[I2S_SPK_WM] = _eos_i2s_spk_buf.size / 2; } - GPIO_REG(GPIO_IOF_SEL) |= iof_mask; + GPIO_REG(GPIO_IOF_SEL) |= I2S_PIN_PWM; GPIO_REG(GPIO_IOF_EN) |= iof_mask; _eos_i2s_start_pwm(); @@ -241,12 +229,6 @@ void eos_i2s_stop(void) { eos_intr_disable(I2S_IRQ_SD_ID); - if (!(GPIO_REG(GPIO_IOF_EN) & I2S_PIN_WS_MIC)) { - GPIO_REG(GPIO_OUTPUT_EN) &= ~(1 << I2S_PIN_WS_MIC); - } - if (!(GPIO_REG(GPIO_IOF_EN) & I2S_PIN_WS_SPK)) { - GPIO_REG(GPIO_OUTPUT_EN) &= ~(1 << I2S_PIN_WS_SPK); - } 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); @@ -279,22 +261,32 @@ void eos_i2s_set_mode(unsigned char mode) { _eos_i2s_drvr[I2S_MODE] = mode; } -void eos_i2s_mic_init(uint8_t *mic_arr, uint16_t mic_arr_size) { +void eos_i2s_mic_set_handler(eos_i2s_handler_t handler, uint16_t wm) { clear_csr(mstatus, MSTATUS_MIE); - _abuf_init(&_eos_i2s_mic_buf, mic_arr, mic_arr_size); + if ((i2s_mic_handler == NULL) && handler) _eos_i2s_drvr[I2S_MIC_EVT] = 1; + if (i2s_mic_handler && (handler == NULL)) _eos_i2s_drvr[I2S_MIC_EVT] = 0; + _eos_i2s_drvr[I2S_MIC_WM] = wm; + i2s_mic_handler = handler; set_csr(mstatus, MSTATUS_MIE); } -void eos_i2s_mic_set_handler(eos_i2s_handler_t wm_handler) { +void eos_i2s_mic_set_buf(uint8_t *mic_arr, uint16_t mic_arr_size) { + int run = eos_i2s_running(); + clear_csr(mstatus, MSTATUS_MIE); - i2s_mic_handler = wm_handler; + _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); } -void eos_i2s_mic_set_wm(uint16_t wm) { - clear_csr(mstatus, MSTATUS_MIE); - _eos_i2s_drvr[I2S_MIC_WM] = wm; - set_csr(mstatus, MSTATUS_MIE); +uint8_t *eos_i2s_mic_get_buf(void) { + return _eos_i2s_mic_buf.array; } uint16_t eos_i2s_mic_len(void) { @@ -360,22 +352,32 @@ void eos_i2s_mic_set_vol(int vol) { set_csr(mstatus, MSTATUS_MIE); } -void eos_i2s_spk_init(uint8_t *spk_arr, uint16_t spk_arr_size) { +void eos_i2s_spk_set_handler(eos_i2s_handler_t handler, uint16_t wm) { clear_csr(mstatus, MSTATUS_MIE); - _abuf_init(&_eos_i2s_spk_buf, spk_arr, spk_arr_size); + if ((i2s_spk_handler == NULL) && handler) _eos_i2s_drvr[I2S_SPK_EVT] = 1; + if (i2s_spk_handler && (handler == NULL)) _eos_i2s_drvr[I2S_SPK_EVT] = 0; + _eos_i2s_drvr[I2S_SPK_WM] = wm; + i2s_spk_handler = handler; set_csr(mstatus, MSTATUS_MIE); } -void eos_i2s_spk_set_handler(eos_i2s_handler_t wm_handler) { +void eos_i2s_spk_set_buf(uint8_t *spk_arr, uint16_t spk_arr_size) { + int run = eos_i2s_running(); + clear_csr(mstatus, MSTATUS_MIE); - i2s_spk_handler = wm_handler; + _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); } -void eos_i2s_spk_set_wm(uint16_t wm) { - clear_csr(mstatus, MSTATUS_MIE); - _eos_i2s_drvr[I2S_SPK_WM] = wm; - set_csr(mstatus, MSTATUS_MIE); +uint8_t *eos_i2s_spk_get_buf(void) { + return _eos_i2s_spk_buf.array; } uint16_t eos_i2s_spk_len(void) { @@ -388,23 +390,46 @@ uint16_t eos_i2s_spk_len(void) { return ret; } -uint16_t eos_i2s_spk_write(uint8_t *sample, uint16_t ssize) { +uint16_t eos_i2s_spk_write(uint8_t *sample, uint16_t ssize, uint8_t transform) { uint16_t i; - uint16_t _ssize = 0; + uint16_t abuf_free; + uint8_t transform_l, transform_r; clear_csr(mstatus, MSTATUS_MIE); - _ssize = MIN(ssize, _eos_i2s_spk_buf.size - _abuf_len(&_eos_i2s_spk_buf)); + 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); - 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]; + 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 sr -> x8 li x18, GPIO_CTRL_ADDR - li x19, (0x1 << I2S_PIN_SD_IN) - li x20, (0x1 << I2S_PIN_SD_OUT) - li x21, (0x1 << I2S_PIN_SR_CK) + 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) lw x9, GPIO_OUTPUT_EN(x18) @@ -272,6 +278,9 @@ i2s_sd_xchg: slli x8, x8, 16 srai x8, x8, 16 + # skip right channel + bnez x25, i2s_sd_complete + i2s_encode: beqz x26, i2s_abuf_push # aLaw encode -> x8 @@ -352,7 +361,7 @@ i2s_abuf_push: i2s_sd_complete: li x18, GPIO_CTRL_ADDR - li x19, (0x1 << I2S_PIN_INT) + li x19, (1 << I2S_PIN_INT) sw x19, GPIO_FALL_IP(x18) li x18, I2S_IRQ_SD_ID diff --git a/fw/fe310/phone/ecp.c b/fw/fe310/phone/ecp.c index 6ce9c8f..32c15ea 100644 --- a/fw/fe310/phone/ecp.c +++ b/fw/fe310/phone/ecp.c @@ -58,7 +58,7 @@ static int handle_open(ECPConnection *conn, ECP2Buffer *b) { static ssize_t handle_msg(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, size_t msg_size, ECP2Buffer *b) { switch (mtype) { case MTYPE_VOIP: { - eos_i2s_spk_write(msg, msg_size); + eos_i2s_spk_write(msg, msg_size, EOS_I2S_TRANS_MONO2D); break; } diff --git a/fw/fe310/phone/phone.c b/fw/fe310/phone/phone.c index ca877e4..3af31b6 100644 --- a/fw/fe310/phone/phone.c +++ b/fw/fe310/phone/phone.c @@ -83,10 +83,9 @@ static void handle_cell_voice(unsigned char type, unsigned char *buffer, uint16_ phone_state = PHONE_STATE_CIP; app_status_set_msg("CALL BEGIN"); eos_net_acquire_for_evt(EOS_EVT_I2S | EOS_I2S_ETYPE_MIC, 1); - eos_i2s_spk_init(spk_arr, ABUF_SIZE); - eos_i2s_mic_init(mic_arr, ABUF_SIZE); - eos_i2s_mic_set_wm(MIC_WM); - eos_i2s_mic_set_handler(handle_mic); + eos_i2s_spk_set_buf(spk_arr, ABUF_SIZE); + eos_i2s_mic_set_buf(mic_arr, ABUF_SIZE); + eos_i2s_mic_set_handler(handle_mic, MIC_WM); eos_i2s_mic_set_vol(4); eos_i2s_start(8000); } @@ -106,7 +105,7 @@ static void handle_cell_voice(unsigned char type, unsigned char *buffer, uint16_ case EOS_CELL_MTYPE_VOICE_PCM: { if (phone_state == PHONE_STATE_CIP) { - eos_i2s_spk_write(buffer+1, len-1); + eos_i2s_spk_write(buffer+1, len-1, EOS_I2S_TRANS_MONO2D); } break; } @@ -114,27 +113,89 @@ static void handle_cell_voice(unsigned char type, unsigned char *buffer, uint16_ eos_net_free(buffer, 0); } +#define BTN_R 50 +#define BTN_SP ((APP_SCREEN_W - 6 * BTN_R) / 4) +#define BTN_C1 (BTN_SP + BTN_R) +#define BTN_C2 (2 * BTN_SP + 3 * BTN_R) +#define BTN_C3 (3 * BTN_SP + 5 * BTN_R) +#define BTN_C4 (4 * BTN_SP + 7 * BTN_R) +#define BTN_C5 (5 * BTN_SP + 9 * BTN_R) + static void widget_btn_draw(EVEFreeWidget *widget) { EVEWidget *_widget = &widget->w; EVEPage *page = _widget->page; - uint8_t tag_up, tag_dn; + uint8_t tag0; eve_cmd_dl(BEGIN(EVE_POINTS)); - eve_cmd_dl(POINT_SIZE((_widget->g.h / 2) * 16)); - - tag_up = eve_freew_tag(widget); + eve_cmd_dl(POINT_SIZE(BTN_R * 16)); + + eve_cmd_dl(COLOR_RGB(0x20, 0x20, 0x20)); + tag0 = eve_freew_tag(widget); + eve_cmd_dl(VERTEX2F(BTN_C1, _widget->g.y + BTN_C2)); + eve_freew_tag(widget); + eve_cmd_dl(VERTEX2F(BTN_C2, _widget->g.y + BTN_C2)); + eve_freew_tag(widget); + eve_cmd_dl(VERTEX2F(BTN_C3, _widget->g.y + BTN_C2)); + + eve_freew_tag(widget); + eve_cmd_dl(VERTEX2F(BTN_C1, _widget->g.y + BTN_C3)); + eve_freew_tag(widget); + eve_cmd_dl(VERTEX2F(BTN_C2, _widget->g.y + BTN_C3)); + eve_freew_tag(widget); + eve_cmd_dl(VERTEX2F(BTN_C3, _widget->g.y + BTN_C3)); + + eve_freew_tag(widget); + eve_cmd_dl(VERTEX2F(BTN_C1, _widget->g.y + BTN_C4)); + eve_freew_tag(widget); + eve_cmd_dl(VERTEX2F(BTN_C2, _widget->g.y + BTN_C4)); + eve_freew_tag(widget); + eve_cmd_dl(VERTEX2F(BTN_C3, _widget->g.y + BTN_C4)); + + eve_freew_tag(widget); + eve_cmd_dl(VERTEX2F(BTN_C1, _widget->g.y + BTN_C5)); + eve_freew_tag(widget); + eve_cmd_dl(VERTEX2F(BTN_C2, _widget->g.y + BTN_C5)); + eve_freew_tag(widget); + eve_cmd_dl(VERTEX2F(BTN_C3, _widget->g.y + BTN_C5)); + + eve_freew_tag(widget); eve_cmd_dl(COLOR_RGB(0x0, 0x255, 0x0)); - eve_cmd_dl(VERTEX2F(APP_SCREEN_W / 3, _widget->g.y + _widget->g.h / 2)); + eve_cmd_dl(VERTEX2F(BTN_C1, _widget->g.y + BTN_C1)); - tag_dn = eve_freew_tag(widget); + eve_freew_tag(widget); eve_cmd_dl(COLOR_RGB(0x255, 0x0, 0x0)); - eve_cmd_dl(VERTEX2F(APP_SCREEN_W - APP_SCREEN_W / 3, _widget->g.y + _widget->g.h / 2)); + eve_cmd_dl(VERTEX2F(BTN_C3, _widget->g.y + BTN_C1)); eve_cmd_dl(COLOR_RGBC(page->v.color_fg)); eve_cmd_dl(END()); + + eve_cmd_dl(TAG(tag0)); + eve_cmd(CMD_TEXT, "hhhhs", BTN_C1, _widget->g.y + BTN_C2, app_font()->id, EVE_OPT_CENTER, "1"); + eve_cmd_dl(TAG(tag0 + 1)); + eve_cmd(CMD_TEXT, "hhhhs", BTN_C2, _widget->g.y + BTN_C2, app_font()->id, EVE_OPT_CENTER, "2"); + eve_cmd_dl(TAG(tag0 + 2)); + eve_cmd(CMD_TEXT, "hhhhs", BTN_C3, _widget->g.y + BTN_C2, app_font()->id, EVE_OPT_CENTER, "3"); + eve_cmd_dl(TAG(tag0 + 3)); + eve_cmd(CMD_TEXT, "hhhhs", BTN_C1, _widget->g.y + BTN_C3, app_font()->id, EVE_OPT_CENTER, "4"); + eve_cmd_dl(TAG(tag0 + 4)); + eve_cmd(CMD_TEXT, "hhhhs", BTN_C2, _widget->g.y + BTN_C3, app_font()->id, EVE_OPT_CENTER, "5"); + eve_cmd_dl(TAG(tag0 + 5)); + eve_cmd(CMD_TEXT, "hhhhs", BTN_C3, _widget->g.y + BTN_C3, app_font()->id, EVE_OPT_CENTER, "6"); + eve_cmd_dl(TAG(tag0 + 6)); + eve_cmd(CMD_TEXT, "hhhhs", BTN_C1, _widget->g.y + BTN_C4, app_font()->id, EVE_OPT_CENTER, "7"); + eve_cmd_dl(TAG(tag0 + 7)); + eve_cmd(CMD_TEXT, "hhhhs", BTN_C2, _widget->g.y + BTN_C4, app_font()->id, EVE_OPT_CENTER, "8"); + eve_cmd_dl(TAG(tag0 + 8)); + eve_cmd(CMD_TEXT, "hhhhs", BTN_C3, _widget->g.y + BTN_C4, app_font()->id, EVE_OPT_CENTER, "9"); + eve_cmd_dl(TAG(tag0 + 9)); + eve_cmd(CMD_TEXT, "hhhhs", BTN_C1, _widget->g.y + BTN_C5, app_font()->id, EVE_OPT_CENTER, "*"); + eve_cmd_dl(TAG(tag0 + 10)); + eve_cmd(CMD_TEXT, "hhhhs", BTN_C2, _widget->g.y + BTN_C5, app_font()->id, EVE_OPT_CENTER, "0"); + eve_cmd_dl(TAG(tag0 + 11)); + eve_cmd(CMD_TEXT, "hhhhs", BTN_C3, _widget->g.y + BTN_C5, app_font()->id, EVE_OPT_CENTER, "#"); } -static void call(char * num) { +static void call(char *num) { int rv; if (strlen(num)) { @@ -151,7 +212,29 @@ static int widget_btn_touch(EVEFreeWidget *widget, EVETouch *touch, uint16_t evt int rv; tagi = eve_widget_tag_index(widget, touch->tag_up); - if (tagi == 0) { + if (tagi < 12) { + EVEPage *page = widget->w.page; + EVEStrWidget *strw = (EVEStrWidget *)eve_page_widget(page, 0); + int ch; + + if (tagi < 9) { + ch = '0' + tagi + 1; + } else { + switch (tagi) { + case 9: + ch = '*'; + break; + case 10: + ch = '0'; + break; + case 11: + ch = '#'; + break; + } + } + printf("PUTC CH:%d\n", ch); + eve_strw_putc(strw, ch); + } else if (tagi == 12) { switch (phone_state) { case PHONE_STATE_RING: { app_status_set_msg("ANSWER"); @@ -168,7 +251,7 @@ static int widget_btn_touch(EVEFreeWidget *widget, EVETouch *touch, uint16_t evt break; } } - } else if (tagi == 1) { + } else if (tagi == 13) { if (phone_state != PHONE_STATE_IDLE) { if (phone_state != PHONE_STATE_CIP) { phone_state = PHONE_STATE_IDLE; @@ -195,11 +278,11 @@ int phone_app(EVEWindow *window, EVEViewStack *stack) { .widget.type = EVE_WIDGET_TYPE_STR, .widget.tspec.str.str_size = EOS_CELL_MAX_DIAL_STR + 1, }, - APP_SPACERW(APP_SCREEN_W, 50), + APP_SPACERW(APP_SCREEN_W, 10), { .widget.type = EVE_WIDGET_TYPE_FREE, .widget.g.w = APP_SCREEN_W, - .widget.g.h = 100, + .widget.g.h = APP_SCREEN_H, .widget.tspec.free.draw = widget_btn_draw, .widget.tspec.free.touch = widget_btn_touch, }, @@ -210,6 +293,9 @@ int phone_app(EVEWindow *window, EVEViewStack *stack) { APP_LOG(APP_LOG_ERR, "OUT OF MEMORY\n"); return EVE_ERR_NOMEM; } + EVEStrWidget *strw = (EVEStrWidget *)eve_page_widget(page, 0); + strw->w.putc = NULL; + eve_widget_set_focus(&strw->w); return EVE_OK; } -- cgit v1.2.3