summaryrefslogtreecommitdiff
path: root/fw/fe310/phone/phone.c
diff options
context:
space:
mode:
Diffstat (limited to 'fw/fe310/phone/phone.c')
-rw-r--r--fw/fe310/phone/phone.c215
1 files changed, 215 insertions, 0 deletions
diff --git a/fw/fe310/phone/phone.c b/fw/fe310/phone/phone.c
new file mode 100644
index 0000000..53d36ae
--- /dev/null
+++ b/fw/fe310/phone/phone.c
@@ -0,0 +1,215 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+#include <eos.h>
+#include <soc/i2s.h>
+#include <dev/net.h>
+#include <net/cell.h>
+
+#include <eve/eve.h>
+#include <eve/eve_kbd.h>
+#include <eve/eve_font.h>
+
+#include <eve/screen/window.h>
+#include <eve/screen/page.h>
+#include <eve/screen/form.h>
+
+#include "app/app.h"
+#include "app/status.h"
+
+#include "phone.h"
+
+#define ABUF_SIZE 256
+#define MIC_WM 128
+
+static uint8_t mic_arr[ABUF_SIZE];
+static uint8_t spk_arr[ABUF_SIZE];
+
+static unsigned char phone_state = 0;
+
+__attribute__ ((section (".itim")))
+static void handle_mic(unsigned char type) {
+ uint16_t offset, size;
+ unsigned char *buf;
+
+ buf = eos_cell_voice_pcm_buffer(&offset);
+ size = eos_i2s_mic_read(buf, MIC_WM);
+ eos_cell_send_buffer(buf, size, offset, 0);
+}
+
+__attribute__ ((section (".itim")))
+static void handle_cell_voice(unsigned char type, unsigned char *buffer, uint16_t len) {
+ switch (type) {
+ case EOS_CELL_MTYPE_VOICE_RING: {
+ app_status_set_msg("RING");
+ APP_LOG(APP_LOG_DEBUG, "RING:%s\n", buffer+1);
+ phone_state = PHONE_STATE_RING;
+ break;
+ }
+
+ case EOS_CELL_MTYPE_VOICE_MISS: {
+ app_status_set_msg("MISS");
+ APP_LOG(APP_LOG_DEBUG, "MISS\n");
+ phone_state = PHONE_STATE_IDLE;
+ break;
+ }
+
+ case EOS_CELL_MTYPE_VOICE_BEGIN: {
+ app_status_set_msg("CALL BEGIN");
+ APP_LOG(APP_LOG_DEBUG, "CALL BEGIN\n");
+ phone_state = PHONE_STATE_CIP;
+ 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_mic_set_vol(4);
+ eos_i2s_start(8000);
+ break;
+ }
+
+ case EOS_CELL_MTYPE_VOICE_END: {
+ app_status_set_msg("HUP");
+ APP_LOG(APP_LOG_DEBUG, "HUP\n");
+ phone_state = PHONE_STATE_IDLE;
+ eos_net_acquire_for_evt(EOS_EVT_I2S | EOS_I2S_ETYPE_MIC, 0);
+ eos_i2s_stop();
+ break;
+ }
+
+ case EOS_CELL_MTYPE_VOICE_PCM: {
+ if (phone_state == PHONE_STATE_CIP) {
+ eos_i2s_spk_write(buffer+1, len-1);
+ }
+ break;
+ }
+ }
+ eos_net_free(buffer, 0);
+}
+
+static void widget_btn_draw(EVEFreeWidget *widget) {
+ EVEWidget *_widget = &widget->w;
+ EVEPage *page = _widget->page;
+ uint8_t tag_up, tag_dn;
+
+ 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(COLOR_RGB(0x0, 0x255, 0x0));
+ eve_cmd_dl(VERTEX2F(APP_SCREEN_W / 3, _widget->g.y + _widget->g.h / 2));
+
+ tag_dn = 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(COLOR_RGBC(page->v.color_fg));
+ eve_cmd_dl(END());
+}
+
+static int widget_btn_touch(EVEFreeWidget *widget, EVETouch *touch, uint16_t evt) {
+ if (evt & EVE_TOUCH_ETYPE_TAG_UP) {
+ uint8_t tagi;
+ int rv;
+
+ tagi = eve_widget_tag_index(widget, touch->tag_up);
+ if (tagi == 0) {
+ switch (phone_state) {
+ case PHONE_STATE_RING: {
+ app_status_set_msg("ANSWER");
+ rv = eos_cell_voice_answer(NULL, 0);
+ if (rv) APP_LOG(APP_LOG_ERR, "ANSWER ERR:%d\n", rv);
+ break;
+ }
+
+ case PHONE_STATE_IDLE: {
+ EVEPage *page = widget->w.page;
+ EVEStrWidget *strw = (EVEStrWidget *)eve_page_widget(page, 0);
+ char *num = strw->str;
+
+ if (strlen(num)) {
+ app_status_set_msg("DIAL");
+ rv = eos_cell_voice_dial(num, NULL, 0);
+ if (rv) APP_LOG(APP_LOG_ERR, "DIAL ERR:%d\n", rv);
+ }
+ break;
+ }
+ }
+ } else if (tagi == 1) {
+ rv = eos_cell_voice_hangup(NULL, 0);
+ if (rv) APP_LOG(APP_LOG_ERR, "HANGUP ERR:%d\n", rv);
+ }
+ return 1;
+ }
+
+ return 0;
+}
+
+int phone_app(EVEWindow *window, EVEViewStack *stack) {
+ EVEFormSpec spec[] = {
+ {
+ .label.title = "Phone:",
+
+ .widget.type = EVE_WIDGET_TYPE_STR,
+ .widget.tspec.str.str_size = EOS_CELL_MAX_DIAL_STR,
+ },
+ APP_SPACERW(APP_SCREEN_W, 50),
+ {
+ .widget.type = EVE_WIDGET_TYPE_FREE,
+ .widget.g.w = APP_SCREEN_W,
+ .widget.g.h = 100,
+ .widget.tspec.free.draw = widget_btn_draw,
+ .widget.tspec.free.touch = widget_btn_touch,
+ },
+ };
+
+ EVEPage *page = eve_form_create(window, stack, spec, APP_SPEC_SIZE(spec), NULL, phone_close);
+ if (page == NULL) return EVE_ERR_NOMEM;
+
+ return EVE_OK;
+}
+
+int phone_uievt(EVEPage *page, uint16_t evt, void *param) {
+ int ret = 0;
+
+ switch (evt) {
+ case EVE_UIEVT_WIDGET_FOCUS_OUT: {
+ if (param == eve_page_widget(page, 0)) {
+ EVEStrWidget *strw = param;
+ int rv;
+
+ rv = eos_cell_voice_dial((char *)strw->str, NULL, 0);
+ if (rv) {
+ APP_LOG(APP_LOG_ERR, "DIAL ERR:%d\n", rv);
+ return ret;
+ }
+ app_status_set_msg("DIAL");
+ APP_LOG(APP_LOG_DEBUG, "DIAL:%s\n", strw->str);
+ eos_cell_voice_dial(strw->str, NULL, 0);
+ phone_state = PHONE_STATE_DIAL;
+ }
+ break;
+ }
+
+ default: {
+ ret = eve_form_uievt(page, evt, param);
+ break;
+ }
+ }
+
+ return ret;
+}
+
+void phone_close(EVEPage *page) {
+ eve_form_destroy(page);
+}
+
+void phone_init(void) {
+ eos_cell_set_handler(EOS_CELL_MTYPE_VOICE, handle_cell_voice);
+}
+
+unsigned char app_phone_state_get(void) {
+ return phone_state;
+}