summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ecp/src/ecp/core.c2
-rw-r--r--ecp/src/ecp/dir/dir_client.c4
-rw-r--r--ecp/src/ecp/dir/dir_client.h4
-rw-r--r--ecp/src/platform/fe310/time.c6
-rw-r--r--ecp/src/platform/fe310/transport.c50
-rw-r--r--ext/fsfat/diskio.c24
-rw-r--r--fw/esp32/CMakeLists.txt4
-rw-r--r--fw/esp32/components/eos/CMakeLists.txt3
-rw-r--r--fw/esp32/components/eos/app.c243
-rw-r--r--fw/esp32/components/eos/app_main.c (renamed from fw/esp32/main/app_main.c)32
-rw-r--r--fw/esp32/components/eos/at_cmd.c1
-rw-r--r--fw/esp32/components/eos/cell.c84
-rw-r--r--fw/esp32/components/eos/cell_modem.c348
-rw-r--r--fw/esp32/components/eos/cell_pcm.c358
-rw-r--r--fw/esp32/components/eos/cell_sms.c13
-rw-r--r--fw/esp32/components/eos/cell_ussd.c13
-rw-r--r--fw/esp32/components/eos/cell_voice.c49
-rw-r--r--fw/esp32/components/eos/i2c.c82
-rw-r--r--fw/esp32/components/eos/include/_net.h1
-rw-r--r--fw/esp32/components/eos/include/app.h15
-rw-r--r--fw/esp32/components/eos/include/cell.h16
-rw-r--r--fw/esp32/components/eos/include/eos.h16
-rw-r--r--fw/esp32/components/eos/include/i2c.h9
-rw-r--r--fw/esp32/components/eos/include/msgq.h4
-rw-r--r--fw/esp32/components/eos/include/net.h32
-rw-r--r--fw/esp32/components/eos/include/net_priv.h33
-rw-r--r--fw/esp32/components/eos/include/power.h33
-rw-r--r--fw/esp32/components/eos/include/sock.h4
-rw-r--r--fw/esp32/components/eos/include/wifi.h3
-rw-r--r--fw/esp32/components/eos/msgq.c16
-rw-r--r--fw/esp32/components/eos/net.c497
-rw-r--r--fw/esp32/components/eos/power.c448
-rw-r--r--fw/esp32/components/eos/rng.c3
-rw-r--r--fw/esp32/components/eos/sock.c344
-rw-r--r--fw/esp32/components/eos/tun.c13
-rwxr-xr-xfw/esp32/components/eos/wifi.c66
-rw-r--r--fw/esp32/main/component.mk8
-rw-r--r--fw/fe310/eos/board.h40
-rw-r--r--fw/fe310/eos/dev/Makefile11
-rw-r--r--fw/fe310/eos/dev/aon.c42
-rw-r--r--fw/fe310/eos/dev/aon.h7
-rw-r--r--fw/fe310/eos/dev/app.c9
-rw-r--r--fw/fe310/eos/dev/batt.c52
-rw-r--r--fw/fe310/eos/dev/batt.h4
-rw-r--r--fw/fe310/eos/dev/cam.h20
-rw-r--r--fw/fe310/eos/dev/cam_def.h65
-rw-r--r--fw/fe310/eos/dev/ctp.c42
-rw-r--r--fw/fe310/eos/dev/drv/arducam.c28
-rw-r--r--fw/fe310/eos/dev/drv/gt911.c14
-rw-r--r--fw/fe310/eos/dev/drv/gt911.h1
-rw-r--r--fw/fe310/eos/dev/drv/ili9806e.c22
-rw-r--r--fw/fe310/eos/dev/drv/pcm1770.c4
-rw-r--r--fw/fe310/eos/dev/drv/platform.h23
-rw-r--r--fw/fe310/eos/dev/drv/sdc_platform.h16
-rw-r--r--fw/fe310/eos/dev/drv/sdcard.c33
-rw-r--r--fw/fe310/eos/dev/drv/sdcard.h4
-rw-r--r--fw/fe310/eos/dev/egpio.c273
-rw-r--r--fw/fe310/eos/dev/egpio.h97
-rw-r--r--fw/fe310/eos/dev/egpio_priv.h81
-rw-r--r--fw/fe310/eos/dev/eve.c90
-rw-r--r--fw/fe310/eos/dev/eve.h12
-rw-r--r--fw/fe310/eos/dev/eve_priv.h10
-rw-r--r--fw/fe310/eos/dev/flash.c37
-rw-r--r--fw/fe310/eos/dev/flash.h15
-rw-r--r--fw/fe310/eos/dev/lcd.c13
-rw-r--r--fw/fe310/eos/dev/net.c399
-rw-r--r--fw/fe310/eos/dev/net.h33
-rw-r--r--fw/fe310/eos/dev/pwr.c49
-rw-r--r--fw/fe310/eos/dev/pwr.h1
-rw-r--r--fw/fe310/eos/dev/sdc_crypto.c8
-rw-r--r--fw/fe310/eos/dev/sdc_crypto.h18
-rw-r--r--fw/fe310/eos/dev/sdcard.c48
-rw-r--r--fw/fe310/eos/dev/sdcard.h4
-rw-r--r--fw/fe310/eos/dev/spi.c68
-rw-r--r--fw/fe310/eos/dev/spi_cfg.h4
-rw-r--r--fw/fe310/eos/eos.c111
-rw-r--r--fw/fe310/eos/eos.h4
-rw-r--r--fw/fe310/eos/eve/eve.c176
-rw-r--r--fw/fe310/eos/eve/eve.h26
-rw-r--r--fw/fe310/eos/eve/eve_font.c52
-rw-r--r--fw/fe310/eos/eve/eve_font.h2
-rw-r--r--fw/fe310/eos/eve/eve_kbd.c12
-rw-r--r--fw/fe310/eos/eve/eve_kbd.h2
-rw-r--r--fw/fe310/eos/eve/eve_phy.c40
-rw-r--r--fw/fe310/eos/eve/eve_phy.h14
-rw-r--r--fw/fe310/eos/eve/eve_platform.c33
-rw-r--r--fw/fe310/eos/eve/eve_platform.h48
-rw-r--r--fw/fe310/eos/eve/eve_text.c17
-rw-r--r--fw/fe310/eos/eve/eve_text.h2
-rw-r--r--fw/fe310/eos/eve/eve_touch.c160
-rw-r--r--fw/fe310/eos/eve/eve_touch.h57
-rw-r--r--fw/fe310/eos/eve/eve_touch_engine.c48
-rw-r--r--fw/fe310/eos/eve/eve_touch_engine.h13
-rw-r--r--fw/fe310/eos/eve/eve_vtrack.c72
-rw-r--r--fw/fe310/eos/eve/eve_vtrack.h23
-rw-r--r--fw/fe310/eos/eve/screen/form.c70
-rw-r--r--fw/fe310/eos/eve/screen/form.h6
-rw-r--r--fw/fe310/eos/eve/screen/page.c421
-rw-r--r--fw/fe310/eos/eve/screen/page.h22
-rw-r--r--fw/fe310/eos/eve/screen/uievt.h8
-rw-r--r--fw/fe310/eos/eve/screen/view.c137
-rw-r--r--fw/fe310/eos/eve/screen/view.h38
-rw-r--r--fw/fe310/eos/eve/screen/window.c125
-rw-r--r--fw/fe310/eos/eve/screen/window.h20
-rw-r--r--fw/fe310/eos/eve/widget/freew.c60
-rw-r--r--fw/fe310/eos/eve/widget/freew.h11
-rw-r--r--fw/fe310/eos/eve/widget/label.c19
-rw-r--r--fw/fe310/eos/eve/widget/label.h4
-rw-r--r--fw/fe310/eos/eve/widget/pagew.c18
-rw-r--r--fw/fe310/eos/eve/widget/pagew.h2
-rw-r--r--fw/fe310/eos/eve/widget/selectw.c78
-rw-r--r--fw/fe310/eos/eve/widget/selectw.h3
-rw-r--r--fw/fe310/eos/eve/widget/spacerw.c9
-rw-r--r--fw/fe310/eos/eve/widget/spacerw.h2
-rw-r--r--fw/fe310/eos/eve/widget/strw.c104
-rw-r--r--fw/fe310/eos/eve/widget/strw.h2
-rw-r--r--fw/fe310/eos/eve/widget/textw.c90
-rw-r--r--fw/fe310/eos/eve/widget/textw.h2
-rw-r--r--fw/fe310/eos/eve/widget/togglew.c27
-rw-r--r--fw/fe310/eos/eve/widget/togglew.h6
-rw-r--r--fw/fe310/eos/eve/widget/widget.c8
-rw-r--r--fw/fe310/eos/eve/widget/widget.h3
-rw-r--r--fw/fe310/eos/event.c107
-rw-r--r--fw/fe310/eos/event.h19
-rw-r--r--fw/fe310/eos/evt_def.h8
-rw-r--r--fw/fe310/eos/irq_def.h7
-rw-r--r--fw/fe310/eos/log.h15
-rw-r--r--fw/fe310/eos/msgq.c34
-rw-r--r--fw/fe310/eos/msgq.h6
-rw-r--r--fw/fe310/eos/net/Makefile2
-rw-r--r--fw/fe310/eos/net/cell.c84
-rw-r--r--fw/fe310/eos/net/cell.h12
-rw-r--r--fw/fe310/eos/net/pwr.c80
-rw-r--r--fw/fe310/eos/net/pwr.h10
-rw-r--r--fw/fe310/eos/net/sock.c117
-rw-r--r--fw/fe310/eos/net/sock.h13
-rw-r--r--fw/fe310/eos/net/wifi.c36
-rw-r--r--fw/fe310/eos/net/wifi.h5
-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
-rw-r--r--fw/fe310/eos/unicode.c1
-rw-r--r--hw/library/haptic.dcm (renamed from hw/library/usb.dcm)0
-rw-r--r--hw/library/haptic.lib26
-rw-r--r--hw/library/usb.lib44
-rw-r--r--util/prog.c5
-rw-r--r--util/switch.c2
-rw-r--r--yocto/README111
-rw-r--r--yocto/esp32d/Makefile15
-rw-r--r--yocto/esp32d/msgq.c43
-rw-r--r--yocto/esp32d/msgq.h22
-rw-r--r--yocto/esp32d/spi.c411
-rw-r--r--yocto/esp32d/spi.h31
-rw-r--r--yocto/esp32d/tun.c84
-rw-r--r--yocto/esp32d/tun.h5
-rw-r--r--yocto/meta-mikrophone/conf/distro/mikrophone.conf20
-rw-r--r--yocto/meta-mikrophone/conf/layer.conf13
-rw-r--r--yocto/meta-mikrophone/conf/machine/._verdin-imx8mp-mikrophone.confbin0 -> 4096 bytes
-rw-r--r--yocto/meta-mikrophone/conf/machine/include/verdin-imx8mp.inc14
-rw-r--r--yocto/meta-mikrophone/recipes-bsp/u-boot/u-boot-toradex/imx8mp-verdin-mikrophone.dtsi111
-rw-r--r--yocto/meta-mikrophone/recipes-bsp/u-boot/u-boot-toradex/imx8mp-verdin-nonwifi-mikrophone.dts18
-rw-r--r--yocto/meta-mikrophone/recipes-bsp/u-boot/u-boot-toradex/imx8mp-verdin-wifi-mikrophone.dts18
-rw-r--r--yocto/meta-mikrophone/recipes-bsp/u-boot/u-boot-toradex_%.bbappend19
-rw-r--r--yocto/meta-mikrophone/recipes-images/images/mikrophone-image.bb74
-rw-r--r--yocto/meta-mikrophone/recipes-kernel/linux/device-tree-overlays/mikroPhone-panel_overlay.dts110
-rw-r--r--yocto/meta-mikrophone/recipes-kernel/linux/device-tree-overlays_git.bbappend15
-rw-r--r--yocto/meta-mikrophone/recipes-kernel/linux/linux-toradex%.bbappend20
-rw-r--r--yocto/meta-mikrophone/recipes-kernel/linux/linux-toradex/imx8mp-verdin-mikrophone.dtsi169
-rw-r--r--yocto/meta-mikrophone/recipes-kernel/linux/linux-toradex/imx8mp-verdin-nonwifi-mikrophone.dts18
-rw-r--r--yocto/meta-mikrophone/recipes-kernel/linux/linux-toradex/imx8mp-verdin-wifi-mikrophone.dts18
-rw-r--r--yocto/meta-mikrophone/recipes-kernel/linux/linux-toradex/kernel_lvds_freq.patch62
-rw-r--r--yocto/overlays/mikroPhone-panel_overlay.dts29
194 files changed, 6073 insertions, 3715 deletions
diff --git a/ecp/src/ecp/core.c b/ecp/src/ecp/core.c
index 2cef860..b5610c8 100644
--- a/ecp/src/ecp/core.c
+++ b/ecp/src/ecp/core.c
@@ -3167,8 +3167,6 @@ int ecp_pld_set_pts(unsigned char *pld, size_t pld_size, ecp_pts_t pts) {
}
unsigned char *ecp_pld_get_msg(unsigned char *pld, size_t pld_size) {
- size_t offset;
-
if (pld_size < ECP_SIZE_MTYPE) return NULL;
if (pld_size < (ECP_SIZE_MTYPE + ECP_SIZE_MT_FLAG(pld[0]))) return NULL;
diff --git a/ecp/src/ecp/dir/dir_client.c b/ecp/src/ecp/dir/dir_client.c
index cf82754..a9bc9e3 100644
--- a/ecp/src/ecp/dir/dir_client.c
+++ b/ecp/src/ecp/dir/dir_client.c
@@ -185,7 +185,7 @@ void ecp_dir_set_unavailable(ECPDirList *dir_list, ecp_ecdh_public_t *public) {
}
}
-int ecp_dir_sel_dir(ECPDirList *dir_list, ecp_ecdh_public_t *public, struct ECPNetAddr *addr) {
+int ecp_dir_sel_dir(ECPDirList *dir_list, ecp_ecdh_public_t *public, ecp_tr_addr_t *addr) {
ECPDHPub *key;
uint16_t dir_cnt;
uint32_t rnd_sel;
@@ -215,7 +215,7 @@ int ecp_dir_sel_dir(ECPDirList *dir_list, ecp_ecdh_public_t *public, struct ECPN
#ifdef ECP_WITH_VCONN
-ssize_t ecp_dir_sel_vconn(ECPDirList *dir_list, ecp_ecdh_public_t *srv_pub, ecp_ecdh_public_t vconn_keys[], size_t vconn_size, struct ECPNetAddr *addr) {
+ssize_t ecp_dir_sel_vconn(ECPDirList *dir_list, ecp_ecdh_public_t *srv_pub, ecp_ecdh_public_t vconn_keys[], size_t vconn_size, ecp_tr_addr_t *addr) {
unsigned char tmp_hash[ECP_SIZE_HASH_DIGEST];
unsigned char hrw_hash[ECP_SIZE_HASH_DIGEST];
ecp_ecdh_public_t public[2];
diff --git a/ecp/src/ecp/dir/dir_client.h b/ecp/src/ecp/dir/dir_client.h
index 8efed1c..a76915e 100644
--- a/ecp/src/ecp/dir/dir_client.h
+++ b/ecp/src/ecp/dir/dir_client.h
@@ -15,8 +15,8 @@ int ecp_dir_set_handler(ECPContext *ctx, ECPConnHandler *handler, ecp_dir_handle
int ecp_dir_get(ECPConnection *conn, ECPSocket *sock, ecp_ecdh_public_t *public, ecp_tr_addr_t *addr, unsigned char region);
void ecp_dir_set_unavailable(ECPDirList *dir_list, ecp_ecdh_public_t *public);
-int ecp_dir_sel_dir(ECPDirList *dir_list, ecp_ecdh_public_t *public, struct ECPNetAddr *addr);
+int ecp_dir_sel_dir(ECPDirList *dir_list, ecp_ecdh_public_t *public, ecp_tr_addr_t *addr);
#ifdef ECP_WITH_VCONN
-ssize_t ecp_dir_sel_vconn(ECPDirList *dir_list, ecp_ecdh_public_t *srv_pub, ecp_ecdh_public_t vconn_keys[], size_t vconn_size, struct ECPNetAddr *addr);
+ssize_t ecp_dir_sel_vconn(ECPDirList *dir_list, ecp_ecdh_public_t *srv_pub, ecp_ecdh_public_t vconn_keys[], size_t vconn_size, ecp_tr_addr_t *addr);
#endif
diff --git a/ecp/src/platform/fe310/time.c b/ecp/src/platform/fe310/time.c
index 4bf530c..5f92d7f 100644
--- a/ecp/src/platform/fe310/time.c
+++ b/ecp/src/platform/fe310/time.c
@@ -24,15 +24,15 @@ int ecp_tm_init(ECPContext *ctx) {
}
ecp_sts_t ecp_tm_get_s(void) {
- return eos_time_get_tick() / EOS_TIMER_RTC_FREQ;
+ return eos_get_tick() / EOS_TIMER_RTC_FREQ;
}
ecp_sts_t ecp_tm_get_ms(void) {
- return eos_time_get_tick() * 1000 / EOS_TIMER_RTC_FREQ;
+ return eos_get_tick() * 1000 / EOS_TIMER_RTC_FREQ;
}
void ecp_tm_sleep(ecp_sts_t msec) {
- eos_time_sleep(msec);
+ eos_sleep(msec);
}
void ecp_tm_timer_set(ecp_sts_t next) {
diff --git a/ecp/src/platform/fe310/transport.c b/ecp/src/platform/fe310/transport.c
index 1ae0f56..2180e2e 100644
--- a/ecp/src/platform/fe310/transport.c
+++ b/ecp/src/platform/fe310/transport.c
@@ -10,31 +10,34 @@
ECPSocket *_ecp_tr_sock = NULL;
unsigned char pld_buf[ECP_MAX_PLD];
-static void packet_handler(unsigned char type, unsigned char *buffer, uint16_t len) {
- ECPContext *ctx;
+static void packet_handler(unsigned char type, unsigned char *buffer, uint16_t buf_len) {
ECP2Buffer bufs;
ECPBuffer packet;
ECPBuffer payload;
ecp_tr_addr_t addr;
+ size_t hdr_size;
ssize_t rv;
+ unsigned char *_packet;
+ int _rv;
+
+ _rv = eos_sock_recvfrom(buffer, buf_len, &addr, NULL, 0);
+ if (!_rv) _packet = eos_sock_buf2pkt(buffer, buf_len);
+ if (_rv || _packet == NULL) {
+ if (_rv == EOS_SOCK_ERR_CLOSED) _ecp_tr_sock->sock = 0;
+ eos_net_free(buffer, 0);
+ return;
+ }
bufs.packet = &packet;
bufs.payload = &payload;
- packet.buffer = buffer+EOS_SOCK_SIZE_UDP_HDR;
- packet.size = EOS_NET_MTU-EOS_SOCK_SIZE_UDP_HDR;
+ hdr_size = _packet - buffer;
+ packet.buffer = _packet;
+ packet.size = EOS_NET_MTU - hdr_size;
payload.buffer = pld_buf;
payload.size = ECP_MAX_PLD;
- if (len < EOS_SOCK_SIZE_UDP_HDR) {
- eos_net_free(buffer, 0);
- return;
- }
-
- eos_sock_recvfrom(buffer, len, NULL, 0, &addr);
-
- ctx = _ecp_tr_sock->ctx;
- rv = ecp_pkt_handle(_ecp_tr_sock, NULL, &addr, &bufs, len-EOS_SOCK_SIZE_UDP_HDR);
+ rv = ecp_pkt_handle(_ecp_tr_sock, NULL, &addr, &bufs, buf_len - hdr_size);
if (rv < 0) ECP_LOG_ERR(_ecp_tr_sock, "packet_handler: err:%d\n", (int)rv);
if (bufs.packet->buffer) {
@@ -81,24 +84,25 @@ void ecp_tr_close(ECPSocket *sock) {
}
ssize_t ecp_tr_send(ECPSocket *sock, ECPBuffer *packet, size_t pkt_size, ecp_tr_addr_t *addr, unsigned char flags) {
- unsigned char *buf = NULL;
+ unsigned char *buffer = NULL;
int reply;
int rv;
+ if (sock->sock == 0) return ECP_ERR_CLOSED;
+
reply = 0;
if (flags & ECP_SEND_FLAG_REPLY) {
if (flags & ECP_SEND_FLAG_MORE) return ECP_ERR;
- if (packet->buffer) {
- buf = packet->buffer-EOS_SOCK_SIZE_UDP_HDR;
- packet->buffer = NULL;
- reply = 1;
- }
+ if (packet->buffer == NULL) return ECP_ERR;
+ buffer = packet->buffer;
+ packet->buffer = NULL;
+ reply = 1;
} else {
- buf = eos_net_alloc();
+ rv = eos_sock_pkt_alloc(&buffer, packet->buffer, pkt_size);
+ if (rv) return ECP_ERR;
}
- if (buf == NULL) return ECP_ERR_ALLOC;
- rv = eos_sock_sendto_async(sock->sock, reply ? NULL : packet->buffer, pkt_size, addr, buf, !!(flags & ECP_SEND_FLAG_MORE));
+ rv = eos_sock_sendto(sock->sock, addr, buffer, pkt_size, !!(flags & ECP_SEND_FLAG_MORE));
if (rv) return ECP_ERR_SEND;
return pkt_size;
@@ -110,7 +114,7 @@ ssize_t ecp_tr_recv(ECPSocket *sock, ECPBuffer *packet, ecp_tr_addr_t *addr, int
void ecp_tr_release(ECPBuffer *packet, unsigned char more) {
if (packet->buffer) {
- eos_net_free(packet->buffer-EOS_SOCK_SIZE_UDP_HDR, more);
+ eos_net_free(eos_sock_pkt2buf(packet->buffer), more);
packet->buffer = NULL;
} else if (!more) {
eos_net_release();
diff --git a/ext/fsfat/diskio.c b/ext/fsfat/diskio.c
index 90a12e6..1c93466 100644
--- a/ext/fsfat/diskio.c
+++ b/ext/fsfat/diskio.c
@@ -10,7 +10,7 @@
#include "ff.h" /* Obtains integer types */
#include "diskio.h" /* Declarations of disk functions */
-#include <eos/dev/sdcard.h>
+#include <eos/dev/drv/sdcard.h>
#define TIMEOUT 1000
#define TIMEOUT_TRIM 60000
@@ -23,7 +23,7 @@ DSTATUS disk_status (
BYTE pdrv /* Physical drive nmuber to identify the drive */
)
{
- if (pdrv || (eos_sdc_type() == 0)) return STA_NOINIT;
+ if (pdrv || (sdc_get_type() == 0)) return STA_NOINIT;
return 0;
}
@@ -37,7 +37,7 @@ DSTATUS disk_initialize (
BYTE pdrv /* Physical drive nmuber to identify the drive */
)
{
- if (pdrv || (eos_sdc_type() == 0)) return STA_NOINIT;
+ if (pdrv || (sdc_get_type() == 0)) return STA_NOINIT;
return 0;
}
@@ -57,9 +57,9 @@ DRESULT disk_read (
int rv;
if (pdrv) return RES_PARERR;
- if (eos_sdc_type() == 0) return RES_NOTRDY;
+ if (sdc_get_type() == 0) return RES_NOTRDY;
- rv = eos_sdc_sect_read(sector, count, (uint8_t *)buff);
+ rv = sdc_sect_read(sector, count, (uint8_t *)buff);
return rv ? RES_ERROR : RES_OK;
}
@@ -81,9 +81,9 @@ DRESULT disk_write (
int rv;
if (pdrv) return RES_PARERR;
- if (eos_sdc_type() == 0) return RES_NOTRDY;
+ if (sdc_get_type() == 0) return RES_NOTRDY;
- rv = eos_sdc_sect_write(sector, count, (uint8_t *)buff);
+ rv = sdc_sect_write(sector, count, (uint8_t *)buff);
return rv ? RES_ERROR : RES_OK;
}
@@ -105,18 +105,18 @@ DRESULT disk_ioctl (
int rv;
if (pdrv) return RES_PARERR;
- if (eos_sdc_type() == 0) return RES_NOTRDY;
+ if (sdc_get_type() == 0) return RES_NOTRDY;
res = RES_ERROR;
switch (cmd) {
case CTRL_SYNC:
- rv = eos_sdc_sync(TIMEOUT);
+ rv = sdc_sync(TIMEOUT);
if (!rv) res = RES_OK;
break;
case GET_SECTOR_COUNT:
- rv = eos_sdc_get_sect_count(TIMEOUT, &ret);
+ rv = sdc_get_sect_count(&ret, TIMEOUT);
if (!rv) {
*(LBA_t*)buff = ret;
res = RES_OK;
@@ -124,7 +124,7 @@ DRESULT disk_ioctl (
break;
case GET_BLOCK_SIZE:
- rv = eos_sdc_get_blk_size(TIMEOUT, &ret);
+ rv = sdc_get_blk_size(&ret, TIMEOUT);
if (!rv) {
*(DWORD*)buff = ret;
res = RES_OK;
@@ -132,7 +132,7 @@ DRESULT disk_ioctl (
break;
case CTRL_TRIM:
- rv = eos_sdc_erase(((LBA_t*)buff)[0], ((LBA_t*)buff)[1], TIMEOUT_TRIM);
+ rv = sdc_erase(((LBA_t*)buff)[0], ((LBA_t*)buff)[1], TIMEOUT_TRIM);
if (!rv) res = RES_OK;
break;
}
diff --git a/fw/esp32/CMakeLists.txt b/fw/esp32/CMakeLists.txt
new file mode 100644
index 0000000..c81db52
--- /dev/null
+++ b/fw/esp32/CMakeLists.txt
@@ -0,0 +1,4 @@
+cmake_minimum_required(VERSION 3.16)
+
+include($ENV{IDF_PATH}/tools/cmake/project.cmake)
+project(eos_app)
diff --git a/fw/esp32/components/eos/CMakeLists.txt b/fw/esp32/components/eos/CMakeLists.txt
new file mode 100644
index 0000000..404b855
--- /dev/null
+++ b/fw/esp32/components/eos/CMakeLists.txt
@@ -0,0 +1,3 @@
+idf_component_register(SRCS "app_main.c" "msgq.c" "unicode.c" "gsm.c" "gsm_cp.c" "at_cmd.c" "cell.c" "cell_modem.c" "cell_pcm.c" "cell_voice.c" "cell_ussd.c" "cell_sms.c" "cell_pdp.c" "wifi.c" "net.c" "power.c" "rng.c" "sock.c" "app.c" "tun.c"
+ INCLUDE_DIRS "include"
+ REQUIRES esp_driver_gpio esp_driver_spi esp_driver_uart esp_driver_i2s esp_event esp_netif esp_wifi esp_timer vfs)
diff --git a/fw/esp32/components/eos/app.c b/fw/esp32/components/eos/app.c
index 8396376..662da17 100644
--- a/fw/esp32/components/eos/app.c
+++ b/fw/esp32/components/eos/app.c
@@ -15,209 +15,142 @@
#include "eos.h"
#include "msgq.h"
+#include "power.h"
#include "app.h"
+#include "net_priv.h"
-#define SPI_GPIO_CTS 26
-#define SPI_GPIO_RTS 27
-#define SPI_GPIO_MOSI 13
-#define SPI_GPIO_MISO 12
-#define SPI_GPIO_SCLK 14
-#define SPI_GPIO_CS 15
+#define SPI_GPIO_CTS 9
+#define SPI_GPIO_RTS 47
+#define SPI_GPIO_MOSI 11
+#define SPI_GPIO_MISO 13
+#define SPI_GPIO_SCLK 12
+#define SPI_GPIO_CS 10
-#define SPI_SIZE_BUF (EOS_APP_SIZE_BUF + 8)
+#define SPI_SIZE_BUF (EOS_APP_SIZE_BUF + 4)
#define SPI_SIZE_HDR 3
+#define SPI_HOST SPI2_HOST
+
static EOSBufQ app_buf_q;
static unsigned char *app_bufq_array[EOS_APP_SIZE_BUFQ];
static EOSMsgQ app_send_q;
static EOSMsgItem app_sndq_array[EOS_APP_SIZE_SNDQ];
-static SemaphoreHandle_t mutex;
-static SemaphoreHandle_t semaph;
-static TaskHandle_t app_xchg_task_handle;
-static const char *TAG = "EOS APP";
+static NETConfig app_config;
+static eos_net_handler_t app_handler[EOS_APP_MAX_MTYPE];
+
+static spi_bus_config_t app_spi_bus_cfg;
+static spi_slave_interface_config_t app_spi_iface_cfg;
+static spi_slave_transaction_t app_spi_tr_cfg;
-static eos_app_fptr_t app_handler[EOS_APP_MAX_MTYPE];
+static const char *TAG = "EOS APP";
static void bad_handler(unsigned char mtype, unsigned char *buffer, uint16_t len) {
- ESP_LOGE(TAG, "bad handler: %d len: %d", mtype, len);
+ ESP_LOGE(TAG, "bad handler: 0x%.2X len: %d", mtype, len);
}
-// Called after a transaction is queued and ready for pickup by master. We use this to set the handshake line high.
-static void _post_setup_cb(spi_slave_transaction_t *trans) {
- gpio_set_level(SPI_GPIO_CTS, 1);
-}
+static void app_msg_handler(unsigned char mtype, unsigned char *buffer, uint16_t buf_len) {
+ uint8_t idx;
-// Called after transaction is sent/received. We use this to set the handshake line low.
-static void _post_trans_cb(spi_slave_transaction_t *trans) {
- gpio_set_level(SPI_GPIO_CTS, 0);
-}
-
-static void app_xchg_task(void *pvParameters) {
- unsigned char mtype = 0;
- unsigned char *buffer;
- uint16_t len;
- unsigned char *buf_send = heap_caps_malloc(SPI_SIZE_BUF, MALLOC_CAP_DMA);
- unsigned char *buf_recv = heap_caps_malloc(SPI_SIZE_BUF, MALLOC_CAP_DMA);
- esp_err_t ret;
- size_t trans_len;
-
- static spi_slave_transaction_t spi_tr;
-
- //Configuration for the SPI bus
- static spi_bus_config_t spi_bus_cfg = {
- .mosi_io_num = SPI_GPIO_MOSI,
- .miso_io_num = SPI_GPIO_MISO,
- .sclk_io_num = SPI_GPIO_SCLK
- };
-
- //Configuration for the SPI slave interface
- static spi_slave_interface_config_t spi_slave_cfg = {
- .mode = 0,
- .spics_io_num = SPI_GPIO_CS,
- .queue_size = 2,
- .flags = 0,
- .post_setup_cb = _post_setup_cb,
- .post_trans_cb = _post_trans_cb
- };
-
- //Initialize SPI slave interface
- ret = spi_slave_initialize(HSPI_HOST, &spi_bus_cfg, &spi_slave_cfg, 1);
- assert(ret == ESP_OK);
-
- memset(&spi_tr, 0, sizeof(spi_tr));
- spi_tr.tx_buffer = buf_send;
- spi_tr.rx_buffer = buf_recv;
- spi_tr.length = SPI_SIZE_BUF * 8;
-
- while (1) {
- xSemaphoreTake(mutex, portMAX_DELAY);
-
- eos_msgq_pop(&app_send_q, &mtype, &buffer, &len);
- if (mtype) {
- buf_send[0] = mtype;
- buf_send[1] = len >> 8;
- buf_send[2] = len & 0xFF;
- if (buffer) {
- memcpy(buf_send + SPI_SIZE_HDR, buffer, len);
- eos_bufq_push(&app_buf_q, buffer);
- xSemaphoreGive(semaph);
- }
- } else {
- gpio_set_level(SPI_GPIO_RTS, 0);
- buf_send[0] = 0;
- buf_send[1] = 0;
- buf_send[2] = 0;
- len = 0;
- }
-
- xSemaphoreGive(mutex);
-
- buf_recv[0] = 0;
- buf_recv[1] = 0;
- buf_recv[2] = 0;
- spi_slave_transmit(HSPI_HOST, &spi_tr, portMAX_DELAY);
-
- trans_len = spi_tr.trans_len / 8;
- if (trans_len < SPI_SIZE_HDR) continue;
-
- if (len + SPI_SIZE_HDR > trans_len) {
- spi_tr.tx_buffer = buf_send + trans_len;
- spi_tr.rx_buffer = buf_recv + trans_len;
- spi_tr.length = (SPI_SIZE_BUF - trans_len) * 8;
- spi_slave_transmit(HSPI_HOST, &spi_tr, portMAX_DELAY);
- spi_tr.tx_buffer = buf_send;
- spi_tr.rx_buffer = buf_recv;
- spi_tr.length = SPI_SIZE_BUF * 8;
- }
- mtype = buf_recv[0] & ~EOS_APP_MTYPE_FLAG_MASK;
- len = (uint16_t)buf_recv[1] << 8;
- len |= (uint16_t)buf_recv[2] & 0xFF;
- buffer = buf_recv + 3;
-
- if (mtype == 0x00) continue;
-
- if ((mtype <= EOS_APP_MAX_MTYPE) && (len <= EOS_APP_MTU)) {
- app_handler[mtype - 1](mtype, buffer, len);
- } else {
- bad_handler(mtype, buffer, len);
- }
+ idx = mtype & EOS_NET_MTYPE_MASK;
+ if (idx && (idx <= EOS_APP_MAX_MTYPE) && (buf_len <= EOS_APP_MTU)) {
+ app_handler[idx - 1](mtype, buffer, buf_len);
+ } else {
+ bad_handler(mtype, buffer, buf_len);
}
- vTaskDelete(NULL);
}
void eos_app_init(void) {
+ SemaphoreHandle_t mutex;
+ SemaphoreHandle_t bufq_mutex;
+ SemaphoreHandle_t bufq_semaph;
int i;
- // Configuration for the handshake lines
- gpio_config_t io_conf = {};
-
- io_conf.intr_type = GPIO_INTR_DISABLE;
- io_conf.mode = GPIO_MODE_OUTPUT;
- io_conf.pull_up_en = 0;
- io_conf.pull_down_en = 0;
- io_conf.pin_bit_mask = ((uint64_t)1 << SPI_GPIO_CTS);
- gpio_config(&io_conf);
- gpio_set_level(SPI_GPIO_CTS, 0);
-
- io_conf.intr_type = GPIO_INTR_DISABLE;
- io_conf.mode = GPIO_MODE_OUTPUT;
- io_conf.pull_up_en = 0;
- io_conf.pull_down_en = 0;
- io_conf.pin_bit_mask = ((uint64_t)1 << SPI_GPIO_RTS);
- gpio_config(&io_conf);
- gpio_set_level(SPI_GPIO_RTS, 0);
-
eos_msgq_init(&app_send_q, app_sndq_array, EOS_APP_SIZE_SNDQ);
eos_bufq_init(&app_buf_q, app_bufq_array, EOS_APP_SIZE_BUFQ);
for (i=0; i<EOS_APP_SIZE_BUFQ; i++) {
- eos_bufq_push(&app_buf_q, malloc(EOS_APP_SIZE_BUF));
+ unsigned char *buffer;
+
+ buffer = malloc(EOS_APP_SIZE_BUF);
+ assert(buffer != NULL);
+ eos_bufq_push(&app_buf_q, buffer);
}
for (i=0; i<EOS_APP_MAX_MTYPE; i++) {
app_handler[i] = bad_handler;
}
- semaph = xSemaphoreCreateCounting(EOS_APP_SIZE_BUFQ, EOS_APP_SIZE_BUFQ);
mutex = xSemaphoreCreateBinary();
+ assert(mutex != NULL);
+ bufq_mutex = xSemaphoreCreateBinary();
+ assert(bufq_mutex != NULL);
+ bufq_semaph = xSemaphoreCreateCounting(EOS_APP_SIZE_BUFQ, EOS_APP_SIZE_BUFQ);
+ assert(bufq_semaph != NULL);
+
xSemaphoreGive(mutex);
- xTaskCreate(&app_xchg_task, "app_xchg", EOS_TASK_SSIZE_APP_XCHG, NULL, EOS_TASK_PRIORITY_APP_XCHG, &app_xchg_task_handle);
+ xSemaphoreGive(bufq_mutex);
+
+ app_config.sleep = 0;
+ app_config.sleep_req = 0;
+ app_config.present = 0;
+ app_config.dev = NET_DEV_APP;
+ app_config.gpio_mosi = SPI_GPIO_MOSI;
+ app_config.gpio_miso = SPI_GPIO_MISO;
+ app_config.gpio_sclk = SPI_GPIO_SCLK;
+ app_config.gpio_cs = SPI_GPIO_CS;
+ app_config.gpio_rts = SPI_GPIO_RTS;
+ app_config.gpio_cts = SPI_GPIO_CTS;
+ app_config.spi_host = SPI_HOST;
+ app_config.spi_bus_cfg = &app_spi_bus_cfg;
+ app_config.spi_iface_cfg = &app_spi_iface_cfg;
+ app_config.spi_tr_cfg = &app_spi_tr_cfg;
+ app_config.mutex = mutex;
+ app_config.bufq_mutex = bufq_mutex;
+ app_config.bufq_semaph = bufq_semaph;
+ app_config.buf_q = &app_buf_q;
+ app_config.send_q = &app_send_q;
+ app_config.msg_handler = app_msg_handler;
+
+ _eos_net_init_gpio(&app_config);
+
+ if (esp_reset_reason() == ESP_RST_DEEPSLEEP) {
+ gpio_hold_dis(app_config.gpio_cts);
+ }
+
ESP_LOGI(TAG, "INIT");
}
-unsigned char *eos_app_alloc(void) {
- unsigned char *ret;
+void eos_app_run(void) {
+ BaseType_t rv;
- xSemaphoreTake(semaph, portMAX_DELAY);
- xSemaphoreTake(mutex, portMAX_DELAY);
- ret = eos_bufq_pop(&app_buf_q);
- xSemaphoreGive(mutex);
+ rv = xTaskCreate(&eos_net_xchg_task, "app_xchg", EOS_TASK_SSIZE_APP, &app_config, EOS_TASK_PRIORITY_APP, &app_config.xchg_task_handle);
+ assert(rv == pdPASS);
- return ret;
+ ESP_LOGI(TAG, "RUN");
}
-void eos_app_free(unsigned char *buf) {
- xSemaphoreTake(mutex, portMAX_DELAY);
- eos_bufq_push(&app_buf_q, buf);
- xSemaphoreGive(semaph);
- xSemaphoreGive(mutex);
+unsigned char *eos_app_alloc(void) {
+ return _eos_net_alloc(&app_config);
}
-int eos_app_send(unsigned char mtype, unsigned char *buffer, uint16_t len) {
- int rv = EOS_OK;
+void eos_app_free(unsigned char *buf) {
+ _eos_net_free(&app_config, buf);
+}
- xSemaphoreTake(mutex, portMAX_DELAY);
- gpio_set_level(SPI_GPIO_RTS, 1);
- rv = eos_msgq_push(&app_send_q, mtype, buffer, len);
- xSemaphoreGive(mutex);
+int eos_app_send(unsigned char mtype, unsigned char *buffer, uint16_t buf_len) {
+ return _eos_net_send(&app_config, mtype, buffer, buf_len);
+}
- if (rv) eos_app_free(buffer);
+void eos_app_sleep_req(void) {
+ _eos_net_sleep_req(&app_config);
+}
- return rv;
+void eos_app_wake(void) {
+ _eos_net_wake(&app_config);
}
-void eos_app_set_handler(unsigned char mtype, eos_app_fptr_t handler) {
+void eos_app_set_handler(unsigned char mtype, eos_net_handler_t handler) {
if (handler == NULL) handler = bad_handler;
if (mtype && (mtype <= EOS_APP_MAX_MTYPE)) app_handler[mtype - 1] = handler;
}
diff --git a/fw/esp32/main/app_main.c b/fw/esp32/components/eos/app_main.c
index 79f76ab..941e01c 100644
--- a/fw/esp32/main/app_main.c
+++ b/fw/esp32/components/eos/app_main.c
@@ -2,26 +2,25 @@
#include <freertos/task.h>
#include <driver/gpio.h>
+#include <esp_system.h>
+
#include <esp_event.h>
#include <esp_netif.h>
#include <esp_err.h>
#include <esp_log.h>
-#include "i2c.h"
#include "cell.h"
-#include "_net.h"
+#include "net.h"
#include "wifi.h"
#include "sock.h"
#include "rng.h"
-#ifdef EOS_WITH_APP
#include "app.h"
#include "tun.h"
-#endif
#include "power.h"
#define ESP_INTR_FLAG_DEFAULT 0
-// Main application
+/* main application */
void app_main() {
esp_err_t ret;
@@ -31,21 +30,28 @@ void app_main() {
ret = esp_event_loop_create_default();
assert(ret == ESP_OK);
- eos_net_init();
+ ret = gpio_install_isr_service(ESP_INTR_FLAG_DEFAULT);
+ assert(ret == ESP_OK);
- eos_cell_pcm_init();
- gpio_install_isr_service(ESP_INTR_FLAG_DEFAULT);
+ eos_power_init();
+
+ eos_net_init();
+ eos_app_init();
+ eos_tun_init();
eos_modem_init();
eos_cell_init();
+ eos_cell_pcm_init();
eos_wifi_init();
eos_sock_init();
eos_rng_init();
-#ifdef EOS_WITH_APP
- eos_app_init();
- eos_tun_init();
-#endif
- eos_power_init();
+ eos_power_run();
+ eos_net_run();
+ eos_app_run();
+ eos_modem_run();
+ eos_cell_run();
+ eos_wifi_run();
+ eos_sock_run();
}
diff --git a/fw/esp32/components/eos/at_cmd.c b/fw/esp32/components/eos/at_cmd.c
index a1c329e..d9ec228 100644
--- a/fw/esp32/components/eos/at_cmd.c
+++ b/fw/esp32/components/eos/at_cmd.c
@@ -36,6 +36,7 @@ void at_init(void) {
memset(&urc_list, 0, sizeof(ATURCList));
mutex = xSemaphoreCreateBinary();
+ assert(mutex != NULL);
xSemaphoreGive(mutex);
}
diff --git a/fw/esp32/components/eos/cell.c b/fw/esp32/components/eos/cell.c
index d34172e..8665616 100644
--- a/fw/esp32/components/eos/cell.c
+++ b/fw/esp32/components/eos/cell.c
@@ -17,8 +17,6 @@
static const char *TAG = "EOS CELL";
-static uint8_t cell_mode;
-
static EOSBufQ cell_buf_q;
static unsigned char *cell_bufq_array[CELL_SIZE_QUEUE];
@@ -28,8 +26,6 @@ static QueueHandle_t cell_queue;
static void _cell_handler(unsigned char _mtype, unsigned char *buffer, uint16_t buf_len) {
uint8_t mtype;
- if (buf_len < 1) return;
-
mtype = buffer[0];
switch (mtype & EOS_CELL_MTYPE_MASK) {
case EOS_CELL_MTYPE_DEV: {
@@ -43,29 +39,47 @@ static void _cell_handler(unsigned char _mtype, unsigned char *buffer, uint16_t
}
case EOS_CELL_MTYPE_RESET: {
+ int rv;
+
+ rv = eos_modem_take(1000);
+ if (rv) {
+ ESP_LOGE(TAG, "Reset modem failed: %d", rv);
+ break;
+ }
eos_modem_reset();
+ eos_modem_give();
break;
}
case EOS_CELL_MTYPE_UART_TAKE: {
- uint8_t mode;
-
- mode = eos_modem_get_mode();
- if (mode == EOS_CELL_UART_MODE_NONE) break;
+ int rv;
- eos_modem_set_mode(EOS_CELL_UART_MODE_RELAY);
- cell_mode = mode;
+ if (eos_modem_get_mode() == EOS_CELL_UART_MODE_ATCMD) {
+ rv = eos_modem_set_mode(EOS_CELL_UART_MODE_RELAY);
+ if (rv) ESP_LOGE(TAG, "Set RELAY mode failed: %d", rv);
+ }
break;
}
case EOS_CELL_MTYPE_UART_GIVE: {
- eos_modem_atinit();
- eos_modem_set_mode(cell_mode);
+ int rv;
+
+ if (eos_modem_get_mode() == EOS_CELL_UART_MODE_RELAY) {
+ rv = eos_modem_take(1000);
+ if (!rv) {
+ eos_modem_atinit();
+ eos_modem_give();
+ }
+ rv = eos_modem_set_mode(EOS_CELL_UART_MODE_ATCMD);
+ if (rv) ESP_LOGE(TAG, "Set ATCMD mode failed: %d", rv);
+ }
break;
}
case EOS_CELL_MTYPE_UART_DATA: {
- if (eos_modem_get_mode() == EOS_CELL_UART_MODE_RELAY) eos_modem_write(buffer + 1, buf_len - 1);
+ if (eos_modem_get_mode() == EOS_CELL_UART_MODE_RELAY) {
+ eos_modem_write(buffer + 1, buf_len - 1);
+ }
break;
}
}
@@ -108,23 +122,30 @@ static void cell_handler_task(void *pvParameters) {
vTaskDelete(NULL);
}
-static void cell_handler(unsigned char type, unsigned char *buffer, uint16_t len) {
+static void cell_handler(unsigned char type, unsigned char *buffer, uint16_t buf_len) {
EOSMsgItem mi;
- unsigned char *buf;
+ unsigned char *_buffer;
+
+ if (buf_len < 1) return;
+
+ if (type & EOS_NET_MTYPE_FLAG_REPL) {
+ _cell_handler(type, buffer, buf_len);
+ return;
+ }
xSemaphoreTake(mutex, portMAX_DELAY);
- buf = eos_bufq_pop(&cell_buf_q);
+ _buffer = eos_bufq_pop(&cell_buf_q);
xSemaphoreGive(mutex);
- if (buf == NULL) {
- if (len) ESP_LOGE(TAG, "Cell message NOT handled: %2x", buffer[0]);
+ if (_buffer == NULL) {
+ ESP_LOGE(TAG, "Cell message NOT handled: %2x", buffer[0]);
return;
}
- memcpy(buf, buffer, len);
+ memcpy(_buffer, buffer, buf_len);
mi.type = type;
- mi.buffer = buf;
- mi.len = len;
+ mi.buffer = _buffer;
+ mi.len = buf_len;
xQueueSend(cell_queue, &mi, portMAX_DELAY);
}
@@ -133,13 +154,30 @@ void eos_cell_init(void) {
eos_bufq_init(&cell_buf_q, cell_bufq_array, CELL_SIZE_QUEUE);
for (i=0; i<CELL_SIZE_QUEUE; i++) {
- eos_bufq_push(&cell_buf_q, malloc(EOS_NET_SIZE_BUF));
+ unsigned char *buffer;
+
+ buffer = malloc(EOS_NET_SIZE_BUF);
+ assert(buffer != NULL);
+ eos_bufq_push(&cell_buf_q, buffer);
}
mutex = xSemaphoreCreateBinary();
+ assert(mutex != NULL);
xSemaphoreGive(mutex);
+
cell_queue = xQueueCreate(CELL_SIZE_QUEUE, sizeof(EOSMsgItem));
- xTaskCreate(cell_handler_task, "cell_handler", EOS_TASK_SSIZE_CELL, NULL, EOS_TASK_PRIORITY_CELL, NULL);
+ assert(cell_queue != NULL);
eos_net_set_handler(EOS_NET_MTYPE_CELL, cell_handler);
+
+ ESP_LOGI(TAG, "INIT");
+}
+
+void eos_cell_run(void) {
+ BaseType_t rv;
+
+ rv = xTaskCreate(cell_handler_task, "cell_handler", EOS_TASK_SSIZE_CELL, NULL, EOS_TASK_PRIORITY_CELL, NULL);
+ assert(rv == pdPASS);
+
+ ESP_LOGI(TAG, "RUN");
}
diff --git a/fw/esp32/components/eos/cell_modem.c b/fw/esp32/components/eos/cell_modem.c
index b279db1..4f8efd1 100644
--- a/fw/esp32/components/eos/cell_modem.c
+++ b/fw/esp32/components/eos/cell_modem.c
@@ -5,12 +5,15 @@
#include <freertos/semphr.h>
#include <freertos/task.h>
#include <freertos/queue.h>
+
#include <netif/ppp/pppos.h>
#include <netif/ppp/pppapi.h>
+
#include <driver/uart.h>
#include <driver/gpio.h>
+
+#include <esp_system.h>
#include <esp_timer.h>
-#include <esp_sleep.h>
#include <esp_log.h>
#include "eos.h"
@@ -24,30 +27,37 @@
#define UART_SIZE_IO_BUF 8192
-#define UART_GPIO_TXD 16
+// XXX: TXD and RXD switched for Quectel, fixed in new revision
+#define UART_GPIO_TXD 18
#define UART_GPIO_RXD 17
-#define UART_GPIO_DTR 32
-#define UART_GPIO_RI 35
+#define UART_GPIO_DTR 15
+#define UART_GPIO_RI 16
+#define MODEM_GPIO_RST 6
+#define MODEM_GPIO_USB_EN 7
+#define MODEM_GPIO_USB_S 14
+
+#define UART_PORT UART_NUM_1
#define MODEM_ETYPE_ATINIT 1
#define MODEM_ETYPE_STATUS 2
#define MODEM_ETYPE_RING 3
-#define AT_CMD_INIT_SIZE 5
-
#define MIN(X, Y) (((X) < (Y)) ? (X) : (Y))
#define MAX(X, Y) (((X) > (Y)) ? (X) : (Y))
-static const char *TAG = "EOS MODEM";
-
-static char *at_cmd_init[AT_CMD_INIT_SIZE] = {
- "AT+CFGRI=1\r",
- "AT+CSCLK=1\r",
+static char *at_cmd_init[] = {
+ // "AT+CFGRI=1\r",
+ // "AT+CSCLK=1\r",
+ "AT+QSCLK=1\r",
+ "AT+QCFG=\"risignaltype\",\"physical\"\r",
+ "AT+QURCCFG=\"urcport\",\"uart1\"\r",
"AT+CLIP=1\r",
"AT+CMGF=0\r",
"AT+CPMS=\"ME\",\"ME\",\"ME\"\r"
};
+static const char *TAG = "EOS CELL MODEM";
+
static SemaphoreHandle_t mutex;
static QueueHandle_t modem_queue;
@@ -84,8 +94,6 @@ typedef struct {
size_t param_len;
} modem_event_t;
-static void modem_send_status(void);
-
static void atcmd_read(size_t bsize) {
char *ln_end;
int rd = 0;
@@ -94,6 +102,9 @@ static void atcmd_read(size_t bsize) {
char *uart_curr = uart_buf + uart_buf_len;
int _rd = eos_modem_read(uart_curr, MIN(bsize - rd, sizeof(uart_buf) - uart_buf_len - 1), 100);
+ /* after sleep one 0xff character is emitted */
+ if ((_rd == 1) && (*uart_curr == 0xff)) return;
+
rd += _rd;
uart_buf_len += _rd;
uart_buf[uart_buf_len] = '\0';
@@ -123,7 +134,7 @@ static void uart_data_read(uint8_t mode) {
int rd;
size_t bsize;
- uart_get_buffered_data_len(UART_NUM_2, &bsize);
+ uart_get_buffered_data_len(UART_PORT, &bsize);
switch (mode) {
case EOS_CELL_UART_MODE_ATCMD: {
atcmd_read(bsize);
@@ -132,7 +143,6 @@ static void uart_data_read(uint8_t mode) {
case EOS_CELL_UART_MODE_PPP: {
rd = 0;
-
do {
int _rd = eos_modem_read(uart_buf, MIN(bsize - rd, sizeof(uart_buf)), 100);
if (ppp_handle) pppos_input_tcpip(ppp_handle, (uint8_t *)uart_buf, _rd);
@@ -143,15 +153,17 @@ static void uart_data_read(uint8_t mode) {
case EOS_CELL_UART_MODE_RELAY: {
unsigned char *buf;
- rd = 0;
+ int rv;
+ rd = 0;
do {
int _rd;
buf = eos_net_alloc();
buf[0] = EOS_CELL_MTYPE_DEV | EOS_CELL_MTYPE_UART_DATA;
_rd = eos_modem_read(buf + 1, MIN(bsize - rd, EOS_NET_SIZE_BUF - 1), 100);
- eos_net_send(EOS_NET_MTYPE_CELL, buf, _rd + 1);
+ rv = eos_net_send(EOS_NET_MTYPE_CELL, buf, _rd + 1);
+ if (rv) ESP_LOGE(TAG, "NET SEND ERR:%d", rv);
rd += _rd;
} while (rd != bsize);
break;
@@ -160,36 +172,20 @@ static void uart_data_read(uint8_t mode) {
}
static void uart_event_task(void *pvParameters) {
- char mode;
- char _mode;
+ uint8_t mode, _mode;
uart_event_t event;
- eos_power_wait4wake();
-
xSemaphoreTake(mutex, portMAX_DELAY);
- _mode = uart_mode;
- xSemaphoreTake(uart_mutex, portMAX_DELAY);
-
if (!modem_initialized) {
- int r;
-
- at_cmd("\r\rAT\r");
- r = at_expect("^OK", NULL, 500);
- if (!r) {
- r = eos_modem_atinit();
- if (!r) {
- modem_present = 1;
- } else {
- _mode = EOS_CELL_UART_MODE_NONE;
- ESP_LOGE(TAG, "Modem init failed");
- }
- }
+ eos_modem_reset();
}
-
- if (_mode == EOS_CELL_UART_MODE_NONE) xSemaphoreGive(uart_mutex);
- mode = _mode;
+ mode = _mode = uart_mode;
xSemaphoreGive(mutex);
+ if (mode != EOS_CELL_UART_MODE_NONE) {
+ xSemaphoreTake(uart_mutex, portMAX_DELAY);
+ }
+
while (1) {
/* Waiting for UART event.
*/
@@ -198,6 +194,8 @@ static void uart_event_task(void *pvParameters) {
case UART_DATA: {
/* Event of UART receiving data
*/
+
+ ESP_LOGI(TAG, "UART DATA READ");
if (mode != EOS_CELL_UART_MODE_NONE) uart_data_read(mode);
if ((mode != _mode) && (uart_buf_len == 0)) {
if (_mode == EOS_CELL_UART_MODE_NONE) xSemaphoreGive(uart_mutex);
@@ -244,27 +242,6 @@ static void IRAM_ATTR uart_ring_handler(void *arg) {
xQueueSendFromISR(modem_queue, &evt, NULL);
}
-static void modem_init_gpio(void) {
- // Configuration for the DTR/RI lines
- gpio_config_t io_conf = {};
-
- io_conf.intr_type = GPIO_INTR_DISABLE;
- io_conf.mode = GPIO_MODE_OUTPUT;
- io_conf.pin_bit_mask = ((uint64_t)1 << UART_GPIO_DTR);
- io_conf.pull_up_en = 0;
- io_conf.pull_down_en = 0;
- gpio_config(&io_conf);
- gpio_set_level(UART_GPIO_DTR, 0);
-
- io_conf.intr_type = GPIO_INTR_NEGEDGE;
- io_conf.mode = GPIO_MODE_INPUT;
- io_conf.pin_bit_mask = ((uint64_t)1 << UART_GPIO_RI);
- io_conf.pull_up_en = 0;
- io_conf.pull_down_en = 0;
- gpio_config(&io_conf);
- gpio_isr_handler_add(UART_GPIO_RI, uart_ring_handler, NULL);
-}
-
static size_t modem_get_status(unsigned char *buffer) {
size_t len;
@@ -310,12 +287,14 @@ static void modem_atinit_handler(char *urc, regmatch_t m[]) {
xQueueSend(modem_queue, &evt, portMAX_DELAY);
}
-static int modem_atinit(void) {
+static int modem_atinit_evt(void) {
int r;
+ vTaskDelay(500 / portTICK_PERIOD_MS);
+
xSemaphoreTake(mutex, portMAX_DELAY);
uart_change_mode(EOS_CELL_UART_MODE_NONE);
- r = xSemaphoreTake(uart_mutex, 1000);
+ r = xSemaphoreTake(uart_mutex, 1000 / portTICK_PERIOD_MS);
if (r == pdFALSE) {
uart_change_mode(uart_mode);
xSemaphoreGive(mutex);
@@ -323,6 +302,8 @@ static int modem_atinit(void) {
}
r = eos_modem_atinit();
+ modem_send_status();
+
uart_change_mode(uart_mode);
xSemaphoreGive(uart_mutex);
xSemaphoreGive(mutex);
@@ -337,10 +318,10 @@ static void modem_event_task(void *pvParameters) {
if (xQueueReceive(modem_queue, &evt, portMAX_DELAY)) {
switch (evt.type) {
case MODEM_ETYPE_ATINIT: {
- int r;
+ int rv;
- r = modem_atinit();
- if (!r) {
+ rv = modem_atinit_evt();
+ if (!rv) {
modem_present = 1;
} else {
ESP_LOGE(TAG, "Modem init failed");
@@ -350,11 +331,13 @@ static void modem_event_task(void *pvParameters) {
case MODEM_ETYPE_STATUS: {
unsigned char *buf;
+ int rv;
buf = eos_net_alloc();
buf[0] = EOS_CELL_MTYPE_DEV | EOS_CELL_MTYPE_STATUS;
memcpy(buf + 1, evt.param, evt.param_len);
- eos_net_send(EOS_NET_MTYPE_CELL, buf, evt.param_len + 1);
+ rv = eos_net_send(EOS_NET_MTYPE_CELL, buf, evt.param_len + 1);
+ if (rv) ESP_LOGE(TAG, "NET SEND ERR:%d", rv);
break;
}
@@ -365,7 +348,7 @@ static void modem_event_task(void *pvParameters) {
}
/* Obsolete
uint64_t t_start = esp_timer_get_time();
- if (xQueueReceive(modem_queue, &level, 200 / portTICK_RATE_MS) && (level == 1)) {
+ if (xQueueReceive(modem_queue, &level, 200 / portTICK_PERIOD_MS) && (level == 1)) {
uint64_t t_end = esp_timer_get_time();
ESP_LOGI(TAG, "URC:%u", (uint32_t)(t_end - t_start));
} else {
@@ -399,11 +382,11 @@ static char *memstr(char *mem, size_t size, char *str) {
return NULL;
}
-static uint32_t ppp_output_cb(ppp_pcb *pcb, uint8_t *data, uint32_t len, void *ctx) {
+static uint32_t ppp_output_cb(ppp_pcb *pcb, const void *data, uint32_t len, void *ctx) {
size_t rv;
xSemaphoreTake(ppp_mutex, portMAX_DELAY);
- rv = eos_modem_write(data, len);
+ rv = eos_modem_write((uint8_t *)data, len);
xSemaphoreGive(ppp_mutex);
return rv;
@@ -412,15 +395,16 @@ static uint32_t ppp_output_cb(ppp_pcb *pcb, uint8_t *data, uint32_t len, void *c
/* PPP status callback */
static void ppp_status_cb(ppp_pcb *pcb, int err_code, void *ctx) {
struct netif *pppif = ppp_netif(pcb);
+ int r;
LWIP_UNUSED_ARG(ctx);
switch (err_code) {
case PPPERR_NONE: {
ESP_LOGI(TAG, "status_cb: Connect");
- ESP_LOGI(TAG," our_ipaddr = %s\n", ipaddr_ntoa(&pppif->ip_addr));
- ESP_LOGI(TAG," his_ipaddr = %s\n", ipaddr_ntoa(&pppif->gw));
- ESP_LOGI(TAG," netmask = %s\n", ipaddr_ntoa(&pppif->netmask));
+ ESP_LOGI(TAG," local ipaddr = %s\n", ipaddr_ntoa(&pppif->ip_addr));
+ ESP_LOGI(TAG," remote ipaddr = %s\n", ipaddr_ntoa(&pppif->gw));
+ ESP_LOGI(TAG," netmask = %s\n", ipaddr_ntoa(&pppif->netmask));
xSemaphoreTake(mutex, portMAX_DELAY);
ppp_connected = 1;
@@ -485,18 +469,26 @@ static void ppp_status_cb(ppp_pcb *pcb, int err_code, void *ctx) {
}
xSemaphoreTake(mutex, portMAX_DELAY);
+ ppp_connected = 0;
+ ip_addr_set_zero(&ppp_ipaddr);
+ modem_send_status();
+ uart_change_mode(EOS_CELL_UART_MODE_NONE);
+ r = xSemaphoreTake(uart_mutex, 1000 / portTICK_PERIOD_MS);
+ if (r == pdFALSE) {
+ uart_mode = EOS_CELL_UART_MODE_NONE;
+ uart_mode_next = EOS_CELL_UART_MODE_NONE;
+ xSemaphoreGive(mutex);
+ ESP_LOGE(TAG, "status_cb: Obtaining UART mutex failed");
+
+ return;
+ }
+
if (uart_mode_next != EOS_CELL_UART_MODE_NONE) {
uart_mode = uart_mode_next;
uart_mode_next = EOS_CELL_UART_MODE_NONE;
} else {
uart_mode = EOS_CELL_UART_MODE_ATCMD;
}
- ppp_connected = 0;
- ip_addr_set_zero(&ppp_ipaddr);
- modem_send_status();
- uart_change_mode(EOS_CELL_UART_MODE_NONE);
- xSemaphoreTake(uart_mutex, portMAX_DELAY);
-
ppp_handle = NULL;
uart_change_mode(uart_mode);
@@ -607,6 +599,12 @@ static int ppp_setup(void) {
return EOS_ERR_TIMEOUT;
}
+ if (ppp_handle) {
+ uart_change_mode(uart_mode);
+ xSemaphoreGive(uart_mutex);
+ return EOS_ERR;
+ }
+
at_cmd(cmd);
r = at_expect("^OK", "^(ERROR|NO CARRIER)", 1000);
if (r) {
@@ -636,6 +634,7 @@ static int ppp_setup(void) {
}
void eos_modem_init(void) {
+ gpio_config_t io_conf = {};
uart_config_t uart_config = {
.baud_rate = 115200,
.data_bits = UART_DATA_8_BITS,
@@ -643,37 +642,91 @@ void eos_modem_init(void) {
.stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE
};
- uart_param_config(UART_NUM_2, &uart_config);
- uart_set_pin(UART_NUM_2, UART_GPIO_TXD, UART_GPIO_RXD, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
- uart_driver_install(UART_NUM_2, UART_SIZE_IO_BUF, UART_SIZE_IO_BUF, 10, &uart_queue, 0);
+ esp_err_t ret;
+ int rv;
- if (eos_power_wakeup_cause() == EOS_PWR_WAKE_RST) {
- uart_mode = EOS_CELL_UART_MODE_ATCMD;
+ ret = uart_param_config(UART_PORT, &uart_config);
+ assert(ret == ESP_OK);
+ ret = uart_set_pin(UART_PORT, UART_GPIO_TXD, UART_GPIO_RXD, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
+ assert(ret == ESP_OK);
+ ret = uart_driver_install(UART_PORT, UART_SIZE_IO_BUF, UART_SIZE_IO_BUF, 10, &uart_queue, 0);
+ assert(ret == ESP_OK);
+
+ // Configuration for the RST/DTR/USB/RI lines
+ gpio_set_level(MODEM_GPIO_RST, 1);
+ io_conf.intr_type = GPIO_INTR_DISABLE;
+ io_conf.mode = GPIO_MODE_OUTPUT_OD;
+ io_conf.pin_bit_mask = BIT64(MODEM_GPIO_RST);
+ io_conf.pull_up_en = 0;
+ io_conf.pull_down_en = 0;
+ gpio_config(&io_conf);
+
+ gpio_set_level(UART_GPIO_DTR, 0);
+ /* enable USB MUX and grab signals */
+ gpio_set_level(MODEM_GPIO_USB_EN, 0);
+ gpio_set_level(MODEM_GPIO_USB_S, 1);
+ io_conf.intr_type = GPIO_INTR_DISABLE;
+ io_conf.mode = GPIO_MODE_OUTPUT;
+ io_conf.pin_bit_mask = BIT64(UART_GPIO_DTR) | BIT64(MODEM_GPIO_USB_EN) | BIT64(MODEM_GPIO_USB_S);
+ io_conf.pull_up_en = 0;
+ io_conf.pull_down_en = 0;
+ gpio_config(&io_conf);
+
+ io_conf.intr_type = GPIO_INTR_NEGEDGE;
+ io_conf.mode = GPIO_MODE_INPUT;
+ io_conf.pin_bit_mask = BIT64(UART_GPIO_RI);
+ io_conf.pull_up_en = 1;
+ io_conf.pull_down_en = 0;
+ gpio_config(&io_conf);
+
+ if (esp_reset_reason() == ESP_RST_DEEPSLEEP) {
+ gpio_hold_dis(UART_GPIO_DTR);
+ gpio_hold_dis(MODEM_GPIO_USB_EN);
+ gpio_hold_dis(MODEM_GPIO_USB_S);
+ } else {
modem_present = 0;
modem_initialized = 0;
- modem_init_gpio();
}
mutex = xSemaphoreCreateBinary();
+ assert(mutex != NULL);
xSemaphoreGive(mutex);
uart_mutex = xSemaphoreCreateBinary();
+ assert(uart_mutex != NULL);
xSemaphoreGive(uart_mutex);
ppp_mutex = xSemaphoreCreateBinary();
+ assert(ppp_mutex != NULL);
xSemaphoreGive(ppp_mutex);
modem_queue = xQueueCreate(4, sizeof(modem_event_t));
- xTaskCreate(uart_event_task, "uart_event", EOS_TASK_SSIZE_UART, NULL, EOS_TASK_PRIORITY_UART, NULL);
- xTaskCreate(modem_event_task, "modem_event", EOS_TASK_SSIZE_MODEM, NULL, EOS_TASK_PRIORITY_MODEM, NULL);
+ assert(modem_queue != NULL);
at_init();
- at_urc_insert("^PB DONE", modem_atinit_handler, REG_EXTENDED);
- at_urc_insert("^\\+CME ERROR: SIM not inserted", modem_atinit_handler, REG_EXTENDED);
+ rv = at_urc_insert("^RDY", modem_atinit_handler, REG_EXTENDED);
+ assert(rv == EOS_OK);
+
+ eos_cell_sms_init();
+ eos_cell_ussd_init();
+ eos_cell_voice_init();
ESP_LOGI(TAG, "INIT");
}
+void eos_modem_run(void) {
+ BaseType_t rv;
+
+ gpio_isr_handler_add(UART_GPIO_RI, uart_ring_handler, NULL);
+
+ rv = xTaskCreate(uart_event_task, "uart_event", EOS_TASK_SSIZE_UART, NULL, EOS_TASK_PRIORITY_UART, NULL);
+ assert(rv == pdPASS);
+ rv = xTaskCreate(modem_event_task, "modem_event", EOS_TASK_SSIZE_MODEM, NULL, EOS_TASK_PRIORITY_MODEM, NULL);
+ assert(rv == pdPASS);
+
+ ESP_LOGI(TAG, "RUN");
+}
+
int eos_modem_atinit(void) {
int echo_on = 0;
int tries = 3;
@@ -706,32 +759,36 @@ int eos_modem_atinit(void) {
r = at_expect("^ATE0", NULL, 1000);
r = at_expect("^OK", "^ERROR", 1000);
- for (i=0; i<AT_CMD_INIT_SIZE; i++) {
+ for (i=0; i<sizeof(at_cmd_init)/sizeof(char *); i++) {
at_cmd(at_cmd_init[i]);
- r = at_expect("^OK", "^ERROR", 1000);
+ r = at_expect("^OK", "ERROR", 1000);
}
+ modem_present = 1;
modem_initialized = 1;
- eos_cell_voice_init();
- eos_cell_sms_init();
- eos_cell_ussd_init();
+ return EOS_OK;
+}
- modem_send_status();
+void eos_modem_reset(void) {
+ gpio_set_level(MODEM_GPIO_RST, 0);
+ vTaskDelay(500 / portTICK_PERIOD_MS);
+ gpio_set_level(MODEM_GPIO_RST, 1);
- return EOS_OK;
+ modem_initialized = 0;
+ uart_mode = EOS_CELL_UART_MODE_ATCMD;
}
void eos_modem_flush(void){
- uart_wait_tx_done(UART_NUM_2, portMAX_DELAY);
+ uart_wait_tx_done(UART_PORT, portMAX_DELAY);
}
size_t eos_modem_write(void *data, size_t size) {
- return uart_write_bytes(UART_NUM_2, (const char *)data, size);
+ return uart_write_bytes(UART_PORT, (const char *)data, size);
}
size_t eos_modem_read(void *data, size_t size, uint32_t timeout) {
- return uart_read_bytes(UART_NUM_2, (uint8_t *)data, size, timeout / portTICK_RATE_MS);
+ return uart_read_bytes(UART_PORT, (uint8_t *)data, size, timeout / portTICK_PERIOD_MS);
}
int eos_modem_readln(char *buf, size_t buf_size, uint32_t timeout) {
@@ -791,6 +848,16 @@ int eos_modem_present(void) {
return rv;
}
+int eos_modem_initialized(void) {
+ int rv;
+
+ xSemaphoreTake(mutex, portMAX_DELAY);
+ rv = modem_initialized;
+ xSemaphoreGive(mutex);
+
+ return rv;
+}
+
uint8_t eos_modem_get_mode(void) {
uint8_t ret;
@@ -832,7 +899,6 @@ int eos_modem_set_mode(uint8_t mode) {
}
if (!rv) {
uart_mode = mode;
- modem_send_status();
}
}
}
@@ -876,71 +942,53 @@ void eos_modem_give(void) {
xSemaphoreGive(mutex);
}
-void eos_modem_sleep(void) {
- int r;
+void eos_modem_sleep_req(void) {
+ int rv;
+ gpio_set_level(UART_GPIO_DTR, 1);
xSemaphoreTake(mutex, portMAX_DELAY);
uart_change_mode(EOS_CELL_UART_MODE_NONE);
- r = xSemaphoreTake(uart_mutex, 1000 / portTICK_PERIOD_MS);
- if (r == pdFALSE) {
- ESP_LOGE(TAG, "Obtaining mutex before sleep failed");
- }
- gpio_set_level(UART_GPIO_DTR, 1);
-}
-
-void eos_modem_deep_sleep(void) {
+ rv = xSemaphoreTake(uart_mutex, 1000 / portTICK_PERIOD_MS);
+ if (rv == pdFALSE) ESP_LOGE(TAG, "Obtaining UART mutex before sleep failed");
+ gpio_isr_handler_remove(UART_GPIO_RI);
+ gpio_reset_pin(UART_GPIO_RI);
+ /* for deep sleep */
gpio_hold_en(UART_GPIO_DTR);
+ gpio_hold_en(MODEM_GPIO_USB_EN);
+ gpio_hold_en(MODEM_GPIO_USB_S);
+ eos_power_sleep_rdy(EOS_PWR_DEV_MODEM);
}
-void eos_modem_wake(uint8_t source, uint8_t mode) {
- if (source == EOS_PWR_WAKE_UART) {
- modem_event_t evt;
+void eos_modem_wake(void) {
+ gpio_config_t io_conf = {
+ .pin_bit_mask = BIT64(UART_GPIO_RI),
+ .mode = GPIO_MODE_INPUT,
+ .intr_type = GPIO_INTR_NEGEDGE,
+ };
+ uint32_t dev;
- evt.type = MODEM_ETYPE_RING;
- xQueueSend(modem_queue, &evt, portMAX_DELAY);
- }
+ gpio_hold_dis(UART_GPIO_DTR);
+ gpio_hold_dis(MODEM_GPIO_USB_EN);
+ gpio_hold_dis(MODEM_GPIO_USB_S);
- switch (mode) {
- case EOS_PWR_SMODE_LIGHT: {
- gpio_set_intr_type(UART_GPIO_RI, GPIO_INTR_NEGEDGE);
- gpio_isr_handler_add(UART_GPIO_RI, uart_ring_handler, NULL);
- gpio_set_level(UART_GPIO_DTR, 0);
+ gpio_config(&io_conf);
+ gpio_isr_handler_add(UART_GPIO_RI, uart_ring_handler, NULL);
- uart_change_mode(uart_mode);
- xSemaphoreGive(uart_mutex);
- xSemaphoreGive(mutex);
+ uart_change_mode(uart_mode);
+ xSemaphoreGive(uart_mutex);
+ xSemaphoreGive(mutex);
- break;
- }
+ gpio_set_level(UART_GPIO_DTR, 0);
- case EOS_PWR_SMODE_DEEP: {
- gpio_hold_dis(UART_GPIO_DTR);
- modem_init_gpio();
+ dev = eos_power_wakeup_source();
+ if (dev == EOS_PWR_DEV_MODEM) {
+ modem_event_t evt;
- break;
- }
+ evt.type = MODEM_ETYPE_RING;
+ xQueueSend(modem_queue, &evt, portMAX_DELAY);
}
}
-int eos_modem_reset(void) {
- int rv;
-
- rv = eos_modem_take(1000);
- if (rv) return rv;
-
- at_cmd("AT+CRESET\r");
- at_expect("^OK", NULL, 1000);
-
- uart_change_mode(EOS_CELL_UART_MODE_ATCMD);
- xSemaphoreGive(uart_mutex);
-
- uart_mode = EOS_CELL_UART_MODE_ATCMD;
- modem_initialized = 0;
- modem_send_status();
- xSemaphoreGive(mutex);
-
- return EOS_OK;
-}
void eos_ppp_get_apn(char *apn) {
xSemaphoreTake(mutex, portMAX_DELAY);
diff --git a/fw/esp32/components/eos/cell_pcm.c b/fw/esp32/components/eos/cell_pcm.c
index b993021..3f5089d 100644
--- a/fw/esp32/components/eos/cell_pcm.c
+++ b/fw/esp32/components/eos/cell_pcm.c
@@ -1,309 +1,137 @@
+#include <stdint.h>
#include <stdlib.h>
-#include <string.h>
#include <freertos/FreeRTOS.h>
-#include <freertos/semphr.h>
#include <freertos/task.h>
-#include <freertos/queue.h>
-#include <driver/i2s.h>
-#include <driver/gpio.h>
+#include <driver/i2s_tdm.h>
#include <esp_log.h>
#include "eos.h"
#include "net.h"
-#include "msgq.h"
#include "cell.h"
-#define PCM_MIC_WM 128
-#define PCM_HOLD_CNT_TX 3
-#define PCM_HOLD_CNT_RX 3
-#define PCM_SIZE_BUFQ 4
-#define PCM_SIZE_BUF (PCM_MIC_WM * 4)
+#define PCM_GPIO_BCK 1
+#define PCM_GPIO_WS 41
+#define PCM_GPIO_DIN 2
+#define PCM_GPIO_DOUT 42
-#define PCM_GPIO_BCK 33
-#define PCM_GPIO_WS 4
-#define PCM_GPIO_DIN 34
-#define PCM_GPIO_DOUT 2
+#define PCM_RX_WM 256 /* receive watermark, must be less than NET_SIZE_MTU */
-#define PCM_ETYPE_WRITE 1
+static i2s_chan_handle_t tx_chan;
+static i2s_chan_handle_t rx_chan;
-static EOSBufQ pcm_buf_q;
-static unsigned char *pcm_bufq_array[PCM_SIZE_BUFQ];
+static const char *TAG = "EOS CELL PCM";
-static EOSMsgQ pcm_evt_q;
-static EOSMsgItem pcm_evtq_array[PCM_SIZE_BUFQ];
-static char pcm_hold_tx;
-static char pcm_active = 0;
-
-static i2s_dev_t* I2S[I2S_NUM_MAX] = {&I2S0, &I2S1};
-
-static QueueHandle_t i2s_queue;
-static SemaphoreHandle_t mutex;
-
-static const char *TAG = "EOS PCM";
-
-static void i2s_event_task(void *pvParameters) {
- i2s_event_t event;
- ssize_t hold_bytes_r = 0;
- unsigned char *hold_buf = NULL;
- char hold_cnt = 0;
-
- while (1) {
- // Waiting for I2S event.
- if (xQueueReceive(i2s_queue, &event, portMAX_DELAY)) {
- switch (event.type) {
- case I2S_EVENT_RX_DONE: {
- ssize_t bytes_r;
- size_t bytes_w;
- uint16_t bytes_e;
- unsigned char _type;
- unsigned char *buf;
-
- if (!pcm_active) {
- if (hold_buf) {
- eos_net_free(hold_buf);
- hold_buf = NULL;
- }
- break;
- }
-
- // Event of I2S receiving data
- if (!hold_cnt) {
- buf = eos_net_alloc();
- buf[0] = EOS_CELL_MTYPE_VOICE | EOS_CELL_MTYPE_VOICE_PCM;
- bytes_r = eos_cell_pcm_read(buf + 1, PCM_MIC_WM);
- if (bytes_r < 0) {
- ESP_LOGE(TAG, "*** I2S READ ERROR ***");
- eos_net_free(buf);
- break;
- }
- eos_net_send(EOS_NET_MTYPE_CELL, buf, bytes_r + 1);
- } else {
- if (hold_buf == NULL) {
- hold_buf = eos_net_alloc();
- hold_buf[0] = EOS_CELL_MTYPE_VOICE | EOS_CELL_MTYPE_VOICE_PCM;
- hold_bytes_r = 0;
- }
- if (1 + hold_bytes_r + PCM_MIC_WM <= EOS_NET_SIZE_BUF) {
- bytes_r = eos_cell_pcm_read(hold_buf + 1 + hold_bytes_r, PCM_MIC_WM);
- if (bytes_r < 0) {
- ESP_LOGE(TAG, "*** I2S READ ERROR ***");
- break;
- }
- hold_bytes_r += bytes_r;
- }
- hold_cnt--;
- if (hold_cnt == 0) {
- eos_net_send(EOS_NET_MTYPE_CELL, hold_buf, hold_bytes_r + 1);
- hold_buf = NULL;
- }
- }
-
- buf = NULL;
- xSemaphoreTake(mutex, portMAX_DELAY);
- if (pcm_hold_tx && (eos_msgq_len(&pcm_evt_q) == PCM_HOLD_CNT_TX)) pcm_hold_tx = 0;
- if (!pcm_hold_tx) eos_msgq_pop(&pcm_evt_q, &_type, &buf, &bytes_e);
- xSemaphoreGive(mutex);
-
- if (buf) {
- esp_err_t ret;
-
- ret = i2s_write(I2S_NUM_0, (const void *)buf, bytes_e, &bytes_w, 1000 / portTICK_RATE_MS);
- xSemaphoreTake(mutex, portMAX_DELAY);
- eos_bufq_push(&pcm_buf_q, buf);
- xSemaphoreGive(mutex);
- if (ret != ESP_OK) {
- ESP_LOGE(TAG, "*** I2S WRITE ERROR ***");
- break;
- }
- }
- break;
- }
+static void pcm_rcvr_task(void *pvParameters) {
+ unsigned char *buffer;
+ size_t size_r;
+ esp_err_t ret;
+ int done = 0;
+ int rv;
- case I2S_EVENT_DMA_ERROR: {
- ESP_LOGE(TAG, "*** I2S DMA ERROR ***");
- break;
- }
+ while (!done) {
+ buffer = eos_net_alloc();
+ buffer[0] = EOS_CELL_MTYPE_VOICE | EOS_CELL_MTYPE_VOICE_PCM;
+ ret = i2s_channel_read(rx_chan, buffer + 1, PCM_RX_WM, &size_r, 1000);
+ switch (ret) {
+ case ESP_OK: {
+ assert(size_r == PCM_RX_WM);
+ break;
+ }
- case I2S_EVENT_MAX: {
- hold_cnt = PCM_HOLD_CNT_RX;
- break;
- }
+ case ESP_ERR_INVALID_STATE: {
+ done = 1;
+ break;
+ }
- default:
- break;
+ default: {
+ done = 1;
+ ESP_LOGE(TAG, "CHAN READ ERR:%d", ret);
+ break;
}
}
+ if (ret == ESP_OK) {
+ rv = eos_net_send(EOS_NET_MTYPE_CELL, buffer, size_r + 1);
+ if (rv) ESP_LOGE(TAG, "NET SEND ERR:%d", rv);
+ } else {
+ eos_net_free(buffer);
+ }
}
vTaskDelete(NULL);
}
-void eos_cell_pcm_init(void) {
- int i;
-
- i2s_config_t i2s_config = {
- .mode = I2S_MODE_SLAVE | I2S_MODE_TX | I2S_MODE_RX,
- .sample_rate = 32000,
- .bits_per_sample = 32,
- .channel_format = I2S_CHANNEL_FMT_ONLY_LEFT,
- .communication_format = I2S_COMM_FORMAT_STAND_I2S,
- .dma_buf_count = 4,
- .dma_buf_len = PCM_MIC_WM,
- .use_apll = true,
- .fixed_mclk = 2048000 * 8,
- .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1
- };
-
- i2s_pin_config_t pin_config = {
- .bck_io_num = PCM_GPIO_BCK,
- .ws_io_num = PCM_GPIO_WS,
- .data_in_num = PCM_GPIO_DIN,
- .data_out_num = PCM_GPIO_DOUT
- };
- i2s_driver_install(I2S_NUM_0, &i2s_config, 10, &i2s_queue); //install and start i2s driver
- i2s_stop(I2S_NUM_0);
- i2s_set_pin(I2S_NUM_0, &pin_config);
- gpio_matrix_in(pin_config.ws_io_num, I2S0I_WS_IN_IDX, 1);
- gpio_matrix_in(pin_config.bck_io_num, I2S0I_BCK_IN_IDX, 1);
- ESP_LOGI(TAG, "TX FIFO:%d TX CHAN:%d RX FIFO:%d RX CHAN:%d", I2S[I2S_NUM_0]->fifo_conf.tx_fifo_mod, I2S[I2S_NUM_0]->conf_chan.tx_chan_mod, I2S[I2S_NUM_0]->fifo_conf.rx_fifo_mod, I2S[I2S_NUM_0]->conf_chan.rx_chan_mod);
-
- I2S[I2S_NUM_0]->fifo_conf.tx_fifo_mod = 2;
- I2S[I2S_NUM_0]->conf_chan.tx_chan_mod = 0;
-
- I2S[I2S_NUM_0]->fifo_conf.rx_fifo_mod = 3;
- I2S[I2S_NUM_0]->conf_chan.rx_chan_mod = 1;
- // I2S[I2S_NUM_0]->conf.tx_mono = 1;
- I2S[I2S_NUM_0]->conf.rx_mono = 1;
- // I2S[I2S_NUM_0]->timing.tx_dsync_sw = 1
- // I2S[I2S_NUM_0]->timing.rx_dsync_sw = 1
- // I2S[I2S_NUM_0]->conf.sig_loopback = 0;
-
- // I2S[I2S_NUM_0]->timing.tx_bck_in_inv = 1;
-
- eos_msgq_init(&pcm_evt_q, pcm_evtq_array, PCM_SIZE_BUFQ);
- eos_bufq_init(&pcm_buf_q, pcm_bufq_array, PCM_SIZE_BUFQ);
- for (i=0; i<PCM_SIZE_BUFQ; i++) {
- eos_bufq_push(&pcm_buf_q, malloc(PCM_SIZE_BUF));
- }
-
- mutex = xSemaphoreCreateBinary();
- xSemaphoreGive(mutex);
-
- // Create a task to handle i2s event from ISR
- xTaskCreate(i2s_event_task, "i2s_event", EOS_TASK_SSIZE_I2S, NULL, EOS_TASK_PRIORITY_I2S, NULL);
- ESP_LOGI(TAG, "INIT");
-}
-
-ssize_t eos_cell_pcm_read(unsigned char *data, size_t size) {
- static unsigned char buf[PCM_SIZE_BUF];
- size_t bytes_r;
+void eos_cell_pcm_start(void) {
+ BaseType_t rv;
esp_err_t ret;
- int i;
- if (size > PCM_MIC_WM) return EOS_ERR;
-
- ret = i2s_read(I2S_NUM_0, (void *)buf, size * 4, &bytes_r, 1000 / portTICK_RATE_MS);
- if (ret != ESP_OK) return EOS_ERR;
+ ret = i2s_channel_enable(tx_chan);
+ if (ret) {
+ ESP_LOGE(TAG, "TX CHAN ENABLE ERR:%d", ret);
+ return;
+ }
- for (i=0; i<size/2; i++) {
- data[i * 2] = buf[i * 8 + 3];
- data[i * 2 + 1] = buf[i * 8 + 2];
+ ret = i2s_channel_enable(rx_chan);
+ if (ret) {
+ ESP_LOGE(TAG, "RX CHAN ENABLE ERR:%d", ret);
+ return;
}
- return bytes_r / 4;
+ rv = xTaskCreate(&pcm_rcvr_task, "pcm_rcvr", EOS_TASK_SSIZE_PCM, NULL, EOS_TASK_PRIORITY_PCM, NULL);
+ assert(rv == pdPASS);
}
-static ssize_t pcm_expand(unsigned char *buf, unsigned char *data, size_t size) {
- int i;
-
- if (size > PCM_MIC_WM) return EOS_ERR;
+void eos_cell_pcm_stop(void) {
+ esp_err_t ret;
- memset(buf, 0, PCM_SIZE_BUF);
- for (i=0; i<size/2; i++) {
- buf[i * 8 + 3] = data[i * 2];
- buf[i * 8 + 2] = data[i * 2 + 1];
- }
+ ret = i2s_channel_disable(tx_chan);
+ if (ret) ESP_LOGE(TAG, "TX CHAN DISABLE ERR:%d", ret);
- return size * 4;
+ ret = i2s_channel_disable(rx_chan);
+ if (ret) ESP_LOGE(TAG, "RX CHAN DISABLE ERR:%d", ret);
}
-int eos_cell_pcm_push(unsigned char *data, size_t size) {
- unsigned char *buf = NULL;
- ssize_t esize;
- int rv;
-
- if (size > PCM_MIC_WM) return EOS_ERR;
-
- xSemaphoreTake(mutex, portMAX_DELAY);
- if (!pcm_active) {
- xSemaphoreGive(mutex);
- return EOS_ERR;
- }
- if (pcm_hold_tx && (eos_msgq_len(&pcm_evt_q) == PCM_HOLD_CNT_TX)) {
- unsigned char _type;
- uint16_t _len;
+void eos_cell_pcm_push(unsigned char *data, size_t size) {
+ esp_err_t ret;
+ size_t size_w;
- eos_msgq_pop(&pcm_evt_q, &_type, &buf, &_len);
+ ret = i2s_channel_write(tx_chan, data, size, &size_w, 1000);
+ if (ret == ESP_OK) {
+ assert(size_w == size);
} else {
- buf = eos_bufq_pop(&pcm_buf_q);
- }
- xSemaphoreGive(mutex);
-
- if (buf == NULL) return EOS_ERR_EMPTY;
-
- esize = pcm_expand(buf, data, size);
- if (esize < 0) {
- xSemaphoreTake(mutex, portMAX_DELAY);
- eos_bufq_push(&pcm_buf_q, buf);
- xSemaphoreGive(mutex);
- return esize;
+ ESP_LOGE(TAG, "CHAN WRITE ERR:%d", ret);
}
-
- xSemaphoreTake(mutex, portMAX_DELAY);
- rv = eos_msgq_push(&pcm_evt_q, PCM_ETYPE_WRITE, buf, esize);
- if (rv) eos_bufq_push(&pcm_buf_q, buf);
- xSemaphoreGive(mutex);
-
- return rv;
}
-void eos_cell_pcm_start(void) {
- i2s_event_t evt;
-
- xSemaphoreTake(mutex, portMAX_DELAY);
- if (pcm_active) {
- xSemaphoreGive(mutex);
- return;
- }
- while (1) {
- unsigned char _type;
- unsigned char *buf;
- uint16_t len;
-
- eos_msgq_pop(&pcm_evt_q, &_type, &buf, &len);
- if (buf) {
- eos_bufq_push(&pcm_buf_q, buf);
- } else {
- break;
- }
- }
- pcm_active = 1;
- pcm_hold_tx = 1;
- xSemaphoreGive(mutex);
+void eos_cell_pcm_init(void) {
+ i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_AUTO, I2S_ROLE_SLAVE);
+ i2s_tdm_config_t tdm_cfg = {
+ .clk_cfg = I2S_TDM_CLK_DEFAULT_CONFIG(8000),
+ .slot_cfg = I2S_TDM_PCM_SHORT_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_MONO,
+ I2S_TDM_SLOT0),
+ .gpio_cfg = {
+ .mclk = I2S_GPIO_UNUSED,
+ .bclk = PCM_GPIO_BCK,
+ .ws = PCM_GPIO_WS,
+ .din = PCM_GPIO_DIN,
+ .dout = PCM_GPIO_DOUT,
+ .invert_flags = {
+ .mclk_inv = false,
+ .bclk_inv = false,
+ .ws_inv = false,
+ },
+ },
+ };
+ esp_err_t ret;
- evt.type = I2S_EVENT_MAX; /* my type */
- xQueueSend(i2s_queue, &evt, portMAX_DELAY);
- i2s_zero_dma_buffer(I2S_NUM_0);
- i2s_start(I2S_NUM_0);
-}
+ tdm_cfg.slot_cfg.total_slot = 16;
+ ret = i2s_new_channel(&chan_cfg, &tx_chan, &rx_chan);
+ assert(ret == ESP_OK);
-void eos_cell_pcm_stop(void) {
- char active;
+ ret = i2s_channel_init_tdm_mode(tx_chan, &tdm_cfg);
+ assert(ret == ESP_OK);
- xSemaphoreTake(mutex, portMAX_DELAY);
- active = pcm_active;
- pcm_active = 0;
- xSemaphoreGive(mutex);
+ ret = i2s_channel_init_tdm_mode(rx_chan, &tdm_cfg);
+ assert(ret == ESP_OK);
- if (active) i2s_stop(I2S_NUM_0);
+ ESP_LOGI(TAG, "INIT");
}
diff --git a/fw/esp32/components/eos/cell_sms.c b/fw/esp32/components/eos/cell_sms.c
index 5145cd7..1cd4cda 100644
--- a/fw/esp32/components/eos/cell_sms.c
+++ b/fw/esp32/components/eos/cell_sms.c
@@ -13,7 +13,7 @@
#define CTRL_Z 0x1a
-static const char *TAG = "EOS SMS";
+static const char *TAG = "EOS CELL SMS";
static char _pdu_in[2048];
static char _pdu_out[2048];
@@ -266,7 +266,8 @@ void eos_cell_sms_handler(unsigned char mtype, unsigned char *buffer, uint16_t b
}
buf_len = _rv;
- eos_net_send(EOS_NET_MTYPE_CELL, buf, buf_len + 1);
+ rv = eos_net_send(EOS_NET_MTYPE_CELL, buf, buf_len + 1);
+ if (rv) ESP_LOGE(TAG, "NET SEND ERR:%d", rv);
} while (1);
eos_modem_give();
@@ -345,9 +346,13 @@ static void sms_received_handler(char *urc, regmatch_t m[]) {
}
buf_len = _rv;
- eos_net_send(EOS_NET_MTYPE_CELL, buf, buf_len + 1);
+ rv = eos_net_send(EOS_NET_MTYPE_CELL, buf, buf_len + 1);
+ if (rv) ESP_LOGE(TAG, "NET SEND ERR:%d", rv);
}
void eos_cell_sms_init(void) {
- at_urc_insert("^\\+CMTI: .*,([0-9]+)$", sms_received_handler, REG_EXTENDED);
+ int rv;
+
+ rv = at_urc_insert("^\\+CMTI: .*,([0-9]+)$", sms_received_handler, REG_EXTENDED);
+ assert(rv == EOS_OK);
}
diff --git a/fw/esp32/components/eos/cell_ussd.c b/fw/esp32/components/eos/cell_ussd.c
index 375025f..fb77b67 100644
--- a/fw/esp32/components/eos/cell_ussd.c
+++ b/fw/esp32/components/eos/cell_ussd.c
@@ -9,7 +9,7 @@
#include "at_cmd.h"
#include "cell.h"
-static const char *TAG = "EOS USSD";
+static const char *TAG = "EOS CELL USSD";
extern char *at_cmd_buf;
@@ -64,7 +64,8 @@ static void ussd_reply_handler(char *urc, regmatch_t m[]) {
len = 2;
if (m[2].rm_so == -1) {
- eos_net_send(EOS_NET_MTYPE_CELL, buf, len);
+ rv = eos_net_send(EOS_NET_MTYPE_CELL, buf, len);
+ if (rv) ESP_LOGE(TAG, "NET SEND ERR:%d", rv);
return;
}
@@ -101,9 +102,13 @@ static void ussd_reply_handler(char *urc, regmatch_t m[]) {
return;
}
- eos_net_send(EOS_NET_MTYPE_CELL, buf, len);
+ rv = eos_net_send(EOS_NET_MTYPE_CELL, buf, len);
+ if (rv) ESP_LOGE(TAG, "NET SEND ERR:%d", rv);
}
void eos_cell_ussd_init(void) {
- at_urc_insert("^\\+CUSD: ([0-9])(,\".*)?", ussd_reply_handler, REG_EXTENDED);
+ int rv;
+
+ rv = at_urc_insert("^\\+CUSD: ([0-9])(,\".*)?", ussd_reply_handler, REG_EXTENDED);
+ assert(rv == EOS_OK);
}
diff --git a/fw/esp32/components/eos/cell_voice.c b/fw/esp32/components/eos/cell_voice.c
index 2a7bb18..273b402 100644
--- a/fw/esp32/components/eos/cell_voice.c
+++ b/fw/esp32/components/eos/cell_voice.c
@@ -13,6 +13,8 @@
#include "at_cmd.h"
#include "cell.h"
+static const char *TAG = "EOS CELL VOICE";
+
extern char *at_cmd_buf;
void eos_cell_voice_handler(unsigned char mtype, unsigned char *buffer, uint16_t buf_len) {
@@ -93,35 +95,41 @@ static void ring_handler(char *urc, regmatch_t m[]) {
memcpy(buf + 1, ring_buf + match[1].rm_so, num_len);
len += num_len;
}
- eos_net_send(EOS_NET_MTYPE_CELL, buf, len);
+ rv = eos_net_send(EOS_NET_MTYPE_CELL, buf, len);
+ if (rv) ESP_LOGE(TAG, "NET SEND ERR:%d", rv);
}
static void busy_handler(char *urc, regmatch_t m[]) {
unsigned char *buf;
uint16_t len;
+ int rv;
eos_cell_pcm_stop();
buf = eos_net_alloc();
buf[0] = EOS_CELL_MTYPE_VOICE | EOS_CELL_MTYPE_VOICE_BUSY;
len = 1;
- eos_net_send(EOS_NET_MTYPE_CELL, buf, len);
+ rv = eos_net_send(EOS_NET_MTYPE_CELL, buf, len);
+ if (rv) ESP_LOGE(TAG, "NET SEND ERR:%d", rv);
}
static void miss_handler(char *urc, regmatch_t m[]) {
unsigned char *buf;
uint16_t len;
+ int rv;
eos_cell_pcm_stop();
buf = eos_net_alloc();
buf[0] = EOS_CELL_MTYPE_VOICE | EOS_CELL_MTYPE_VOICE_MISS;
len = 1;
- eos_net_send(EOS_NET_MTYPE_CELL, buf, len);
+ rv = eos_net_send(EOS_NET_MTYPE_CELL, buf, len);
+ if (rv) ESP_LOGE(TAG, "NET SEND ERR:%d", rv);
}
static void call_begin_handler(char *urc, regmatch_t m[]) {
unsigned char *buf;
+ int rv;
vTaskDelay(100 / portTICK_PERIOD_MS);
at_cmd("AT+CECH=0x0000\r");
@@ -142,12 +150,14 @@ static void call_begin_handler(char *urc, regmatch_t m[]) {
buf = eos_net_alloc();
buf[0] = EOS_CELL_MTYPE_VOICE | EOS_CELL_MTYPE_VOICE_BEGIN;
- eos_net_send(EOS_NET_MTYPE_CELL, buf, 1);
+ rv = eos_net_send(EOS_NET_MTYPE_CELL, buf, 1);
+ if (rv) ESP_LOGE(TAG, "NET SEND ERR:%d", rv);
}
static void call_end_handler(char *urc, regmatch_t m[]) {
unsigned char *buf;
int duration = 0;
+ int rv;
eos_cell_pcm_stop();
@@ -158,14 +168,29 @@ static void call_end_handler(char *urc, regmatch_t m[]) {
buf[2] = duration >> 16;
buf[3] = duration >> 8;
buf[4] = duration;
- eos_net_send(EOS_NET_MTYPE_CELL, buf, 5);
+ rv = eos_net_send(EOS_NET_MTYPE_CELL, buf, 5);
+ if (rv) ESP_LOGE(TAG, "NET SEND ERR:%d", rv);
}
void eos_cell_voice_init(void) {
- at_urc_insert("^RING", ring_handler, REG_EXTENDED);
- at_urc_insert("^BUSY", busy_handler, REG_EXTENDED);
- at_urc_insert("^NO CARRIER", miss_handler, REG_EXTENDED);
- at_urc_insert("^MISSED.CALL: [^ ]+ (\\+?[0-9]+)$", miss_handler, REG_EXTENDED);
- at_urc_insert("^VOICE CALL: BEGIN", call_begin_handler, REG_EXTENDED);
- at_urc_insert("^VOICE CALL: END: ([0-9]{6}$)$", call_end_handler, REG_EXTENDED);
-} \ No newline at end of file
+ int rv;
+
+ rv = at_urc_insert("^RING", ring_handler, REG_EXTENDED);
+ assert(rv == EOS_OK);
+
+ rv = at_urc_insert("^BUSY", busy_handler, REG_EXTENDED);
+ assert(rv == EOS_OK);
+
+ rv = at_urc_insert("^NO CARRIER", miss_handler, REG_EXTENDED);
+ assert(rv == EOS_OK);
+
+ rv = at_urc_insert("^MISSED.CALL: [^ ]+ (\\+?[0-9]+)$", miss_handler, REG_EXTENDED);
+ assert(rv == EOS_OK);
+
+ rv = at_urc_insert("^VOICE CALL: BEGIN", call_begin_handler, REG_EXTENDED);
+ assert(rv == EOS_OK);
+
+ rv = at_urc_insert("^VOICE CALL: END: ([0-9]{6}$)$", call_end_handler, REG_EXTENDED);
+ assert(rv == EOS_OK);
+
+}
diff --git a/fw/esp32/components/eos/i2c.c b/fw/esp32/components/eos/i2c.c
deleted file mode 100644
index 828e4cd..0000000
--- a/fw/esp32/components/eos/i2c.c
+++ /dev/null
@@ -1,82 +0,0 @@
-#include <stdlib.h>
-
-#include <esp_log.h>
-#include <driver/i2c.h>
-
-#include "eos.h"
-
-static const char *TAG = "EOS I2C";
-
-#define I2C_MASTER_NUM I2C_NUM_0
-#define I2C_MASTER_FREQ_HZ 100000
-#define I2C_MASTER_GPIO_SCL 25
-#define I2C_MASTER_GPIO_SDA 26
-
-#define I2C_MASTER_TX_BUF_DISABLE 0 /*!< I2C master doesn't need buffer */
-#define I2C_MASTER_RX_BUF_DISABLE 0 /*!< I2C master doesn't need buffer */
-#define ACK_CHECK_EN 0x1 /*!< I2C master will check ack from slave*/
-#define ACK_CHECK_DIS 0x0 /*!< I2C master will not check ack from slave */
-#define ACK_VAL 0x0 /*!< I2C ack value */
-#define NCK_VAL 0x1 /*!< I2C nack value */
-
-void eos_i2c_init(void) {
- i2c_config_t conf;
- conf.mode = I2C_MODE_MASTER;
- conf.sda_io_num = I2C_MASTER_GPIO_SDA;
- conf.sda_pullup_en = GPIO_PULLUP_ENABLE;
- conf.scl_io_num = I2C_MASTER_GPIO_SCL;
- conf.scl_pullup_en = GPIO_PULLUP_ENABLE;
- conf.master.clk_speed = I2C_MASTER_FREQ_HZ;
- i2c_param_config(I2C_MASTER_NUM, &conf);
- i2c_driver_install(I2C_MASTER_NUM, conf.mode, I2C_MASTER_RX_BUF_DISABLE, I2C_MASTER_TX_BUF_DISABLE, 0);
- ESP_LOGI(TAG, "INIT");
-}
-
-int eos_i2c_read(uint8_t addr, uint8_t reg, uint8_t *data, size_t len) {
- int i, ret;
- i2c_cmd_handle_t cmd = i2c_cmd_link_create();
- i2c_master_start(cmd);
- i2c_master_write_byte(cmd, addr << 1 | I2C_MASTER_WRITE, ACK_CHECK_EN);
- i2c_master_write_byte(cmd, reg, ACK_CHECK_EN);
- i2c_master_start(cmd);
- i2c_master_write_byte(cmd, addr << 1 | I2C_MASTER_READ, ACK_CHECK_EN);
- for (i=0; i < len - 1; i++) {
- i2c_master_read_byte(cmd, data+i, ACK_VAL);
- }
- i2c_master_read_byte(cmd, data+i, NCK_VAL);
- i2c_master_stop(cmd);
-
- ret = i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, 1000 / portTICK_RATE_MS);
- i2c_cmd_link_delete(cmd);
- if (ret != ESP_OK) {
- return EOS_ERR;
- }
- return EOS_OK;
-}
-
-int eos_i2c_write(uint8_t addr, uint8_t reg, uint8_t *data, size_t len) {
- int i, ret;
- i2c_cmd_handle_t cmd = i2c_cmd_link_create();
- i2c_master_start(cmd);
- i2c_master_write_byte(cmd, addr << 1 | I2C_MASTER_WRITE, ACK_CHECK_EN);
- i2c_master_write_byte(cmd, reg, ACK_CHECK_EN);
- for (i=0; i < len; i++) {
- i2c_master_write_byte(cmd, *(data+i), ACK_CHECK_EN);
- }
- i2c_master_stop(cmd);
-
- ret = i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, 1000 / portTICK_RATE_MS);
- i2c_cmd_link_delete(cmd);
- if (ret != ESP_OK) {
- return EOS_ERR;
- }
- return EOS_OK;
-}
-
-int eos_i2c_read8(uint8_t addr, uint8_t reg, uint8_t *data) {
- return eos_i2c_read(addr, reg, data, 1);
-}
-
-int eos_i2c_write8(uint8_t addr, uint8_t reg, uint8_t data) {
- return eos_i2c_write(addr, reg, &data, 1);
-}
diff --git a/fw/esp32/components/eos/include/_net.h b/fw/esp32/components/eos/include/_net.h
deleted file mode 100644
index 35b5308..0000000
--- a/fw/esp32/components/eos/include/_net.h
+++ /dev/null
@@ -1 +0,0 @@
-#include "net.h" \ No newline at end of file
diff --git a/fw/esp32/components/eos/include/app.h b/fw/esp32/components/eos/include/app.h
index 2033b2b..b6dba99 100644
--- a/fw/esp32/components/eos/include/app.h
+++ b/fw/esp32/components/eos/include/app.h
@@ -1,5 +1,7 @@
#include <stdint.h>
+#include "net.h"
+
/* common */
#define EOS_APP_MTU 1500
#define EOS_APP_SIZE_BUF EOS_APP_MTU
@@ -7,17 +9,18 @@
#define EOS_APP_MTYPE_TUN 1
#define EOS_APP_MAX_MTYPE 8
-#define EOS_APP_MTYPE_FLAG_MASK 0xc0
-
/* esp32 specific */
#define EOS_APP_SIZE_BUFQ 4
#define EOS_APP_SIZE_SNDQ 4
-typedef void (*eos_app_fptr_t) (unsigned char, unsigned char *, uint16_t);
-
void eos_app_init(void);
+void eos_app_run(void);
unsigned char *eos_app_alloc(void);
void eos_app_free(unsigned char *buf);
-int eos_app_send(unsigned char mtype, unsigned char *buffer, uint16_t len);
-void eos_app_set_handler(unsigned char mtype, eos_app_fptr_t handler);
+
+int eos_app_send(unsigned char mtype, unsigned char *buffer, uint16_t buf_len);
+
+void eos_app_sleep_req(void);
+void eos_app_wake(void);
+void eos_app_set_handler(unsigned char mtype, eos_net_handler_t handler);
diff --git a/fw/esp32/components/eos/include/cell.h b/fw/esp32/components/eos/include/cell.h
index cb9f49c..c1e7545 100644
--- a/fw/esp32/components/eos/include/cell.h
+++ b/fw/esp32/components/eos/include/cell.h
@@ -27,7 +27,6 @@
#define EOS_CELL_MTYPE_VOICE_END 7
#define EOS_CELL_MTYPE_VOICE_MISS 8
#define EOS_CELL_MTYPE_VOICE_BUSY 9
-#define EOS_CELL_MTYPE_VOICE_ERR 10
#define EOS_CELL_MTYPE_SMS_MSG 1
#define EOS_CELL_MTYPE_SMS_LIST 2
@@ -76,24 +75,26 @@
#define EOS_CELL_UART_SIZE_BUF 1024
void eos_cell_init(void);
+void eos_cell_run(void);
void eos_modem_init(void);
+void eos_modem_run(void);
int eos_modem_atinit(void);
+void eos_modem_reset(void);
void eos_modem_flush(void);
size_t eos_modem_write(void *data, size_t size);
size_t eos_modem_read(void *data, size_t size, uint32_t timeout);
int eos_modem_readln(char *buf, size_t buf_size, uint32_t timeout);
-int eos_modem_resp(char *ok_str, char *err_str, uint32_t timeout);
int eos_modem_present(void);
+int eos_modem_initialized(void);
uint8_t eos_modem_get_mode(void);
size_t eos_modem_get_status(unsigned char *buffer);
int eos_modem_set_mode(uint8_t mode);
int eos_modem_take(uint32_t timeout);
void eos_modem_give(void);
-void eos_modem_sleep(void);
-void eos_modem_deep_sleep(void);
-void eos_modem_wake(uint8_t source, uint8_t mode);
-int eos_modem_reset(void);
+
+void eos_modem_sleep_req(void);
+void eos_modem_wake(void);
void eos_ppp_get_apn(char *apn);
void eos_ppp_set_apn(char *apn);
@@ -105,8 +106,7 @@ int eos_ppp_connect(void);
void eos_ppp_disconnect(void);
void eos_cell_pcm_init(void);
-ssize_t eos_cell_pcm_read(unsigned char *data, size_t size);
-int eos_cell_pcm_push(unsigned char *data, size_t size);
+void eos_cell_pcm_push(unsigned char *data, size_t size);
void eos_cell_pcm_start(void);
void eos_cell_pcm_stop(void);
diff --git a/fw/esp32/components/eos/include/eos.h b/fw/esp32/components/eos/include/eos.h
index bc9dc51..e772637 100644
--- a/fw/esp32/components/eos/include/eos.h
+++ b/fw/esp32/components/eos/include/eos.h
@@ -11,21 +11,21 @@
#define EOS_ERR_NOMEM -100
-#define EOS_TASK_PRIORITY_NET_XCHG 1
-#define EOS_TASK_PRIORITY_APP_XCHG 1
-#define EOS_TASK_PRIORITY_UDP_RCVR 1
+#define EOS_TASK_PRIORITY_NET 1
+#define EOS_TASK_PRIORITY_APP 1
+#define EOS_TASK_PRIORITY_SOCK 1
#define EOS_TASK_PRIORITY_UART 1
#define EOS_TASK_PRIORITY_MODEM 1
-#define EOS_TASK_PRIORITY_I2S 1
+#define EOS_TASK_PRIORITY_PCM 1
#define EOS_TASK_PRIORITY_CELL 1
#define EOS_TASK_PRIORITY_PWR 1
-#define EOS_TASK_SSIZE_NET_XCHG 8192
-#define EOS_TASK_SSIZE_APP_XCHG 8192
-#define EOS_TASK_SSIZE_UDP_RCVR 4096
+#define EOS_TASK_SSIZE_NET 8192
+#define EOS_TASK_SSIZE_APP 8192
+#define EOS_TASK_SSIZE_SOCK 4096
#define EOS_TASK_SSIZE_UART 4096
#define EOS_TASK_SSIZE_MODEM 4096
-#define EOS_TASK_SSIZE_I2S 4096
+#define EOS_TASK_SSIZE_PCM 4096
#define EOS_TASK_SSIZE_CELL 4096
#define EOS_TASK_SSIZE_PWR 4096
diff --git a/fw/esp32/components/eos/include/i2c.h b/fw/esp32/components/eos/include/i2c.h
deleted file mode 100644
index f014141..0000000
--- a/fw/esp32/components/eos/include/i2c.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#include <sys/types.h>
-#include <stdint.h>
-
-void eos_i2c_init(void);
-
-int eos_i2c_read(uint8_t addr, uint8_t reg, uint8_t *data, size_t len);
-int eos_i2c_write(uint8_t addr, uint8_t reg, uint8_t *data, size_t len);
-int eos_i2c_read8(uint8_t addr, uint8_t reg, uint8_t *data);
-int eos_i2c_write8(uint8_t addr, uint8_t reg, uint8_t data);
diff --git a/fw/esp32/components/eos/include/msgq.h b/fw/esp32/components/eos/include/msgq.h
index bbfe041..b5ae9ac 100644
--- a/fw/esp32/components/eos/include/msgq.h
+++ b/fw/esp32/components/eos/include/msgq.h
@@ -14,9 +14,9 @@ typedef struct EOSMsgQ {
} EOSMsgQ;
void eos_msgq_init(EOSMsgQ *msgq, EOSMsgItem *array, uint8_t size);
+uint8_t eos_msgq_len(EOSMsgQ *msgq);
int eos_msgq_push(EOSMsgQ *msgq, unsigned char type, unsigned char *buffer, uint16_t len);
void eos_msgq_pop(EOSMsgQ *msgq, unsigned char *type, unsigned char **buffer, uint16_t *len);
-uint8_t eos_msgq_len(EOSMsgQ *msgq);
typedef struct EOSBufQ {
uint8_t idx_r;
@@ -26,6 +26,6 @@ typedef struct EOSBufQ {
} EOSBufQ;
void eos_bufq_init(EOSBufQ *bufq, unsigned char **array, uint8_t size);
+uint8_t eos_bufq_len(EOSBufQ *bufq);
int eos_bufq_push(EOSBufQ *bufq, unsigned char *buffer);
unsigned char *eos_bufq_pop(EOSBufQ *bufq);
-uint8_t eos_bufq_len(EOSBufQ *bufq);
diff --git a/fw/esp32/components/eos/include/net.h b/fw/esp32/components/eos/include/net.h
index 3e9e625..b500e82 100644
--- a/fw/esp32/components/eos/include/net.h
+++ b/fw/esp32/components/eos/include/net.h
@@ -5,32 +5,36 @@
#define EOS_NET_SIZE_BUF EOS_NET_MTU
#define EOS_NET_MTYPE_SOCK 1
-#define EOS_NET_MTYPE_RNG 3
-#define EOS_NET_MTYPE_POWER 4
+#define EOS_NET_MTYPE_WIFI 2
+#define EOS_NET_MTYPE_CELL 3
+#define EOS_NET_MTYPE_APP 4
+#define EOS_NET_MTYPE_RNG 5
-#define EOS_NET_MTYPE_WIFI 5
-#define EOS_NET_MTYPE_CELL 6
-#define EOS_NET_MTYPE_SIP 7
-#define EOS_NET_MTYPE_APP 8
+#define EOS_NET_MAX_MTYPE 5
-#define EOS_NET_MAX_MTYPE 8
+#define EOS_NET_MTYPE_SLEEP 0x10 /* does not have net handler */
#define EOS_NET_MTYPE_FLAG_ONEW 0x40
#define EOS_NET_MTYPE_FLAG_REPL 0x80
-#define EOS_NET_MTYPE_FLAG_MASK 0xc0
+#define EOS_NET_MTYPE_MASK 0x3F /* 0x0F if mtype is handled by evtq */
/* esp32 specific */
#define EOS_NET_SIZE_BUFQ 4
#define EOS_NET_SIZE_SNDQ 4
-typedef void (*eos_net_fptr_t) (unsigned char, unsigned char *, uint16_t);
+typedef void (*eos_net_handler_t) (unsigned char, unsigned char *, uint16_t);
+void eos_net_xchg_task(void *param);
void eos_net_init(void);
+void eos_net_run(void);
unsigned char *eos_net_alloc(void);
void eos_net_free(unsigned char *buf);
-int eos_net_send(unsigned char mtype, unsigned char *buffer, uint16_t len);
-void eos_net_reply(unsigned char mtype, unsigned char *buffer, uint16_t len);
-void eos_net_set_handler(unsigned char mtype, eos_net_fptr_t handler);
-void eos_net_sleep(void);
-void eos_net_wake(uint8_t source, uint8_t mode);
+
+int eos_net_send(unsigned char mtype, unsigned char *buffer, uint16_t buf_len);
+void eos_net_reply(unsigned char mtype, unsigned char *buffer, uint16_t buf_len);
+
+void eos_net_sleep_req(void);
+void eos_net_wake(void);
+
+void eos_net_set_handler(unsigned char mtype, eos_net_handler_t handler);
diff --git a/fw/esp32/components/eos/include/net_priv.h b/fw/esp32/components/eos/include/net_priv.h
new file mode 100644
index 0000000..fa1de61
--- /dev/null
+++ b/fw/esp32/components/eos/include/net_priv.h
@@ -0,0 +1,33 @@
+#define NET_DEV_NET EOS_PWR_DEV_NET
+#define NET_DEV_APP EOS_PWR_DEV_APP
+
+typedef struct NETConfig {
+ int sleep;
+ int sleep_req;
+ int present;
+ int gpio_mosi;
+ int gpio_miso;
+ int gpio_sclk;
+ int gpio_cs;
+ int gpio_rts;
+ int gpio_cts;
+ uint32_t dev;
+ spi_host_device_t spi_host;
+ spi_bus_config_t *spi_bus_cfg;
+ spi_slave_interface_config_t *spi_iface_cfg;
+ spi_slave_transaction_t *spi_tr_cfg;
+ TaskHandle_t xchg_task_handle;
+ SemaphoreHandle_t mutex;
+ SemaphoreHandle_t bufq_mutex;
+ SemaphoreHandle_t bufq_semaph;
+ EOSBufQ *buf_q;
+ EOSMsgQ *send_q;
+ eos_net_handler_t msg_handler;
+} NETConfig;
+
+void _eos_net_init_gpio(NETConfig *config);
+unsigned char *_eos_net_alloc(NETConfig *config);
+void _eos_net_free(NETConfig *config, unsigned char *buf);
+int _eos_net_send(NETConfig *config, unsigned char mtype, unsigned char *buffer, uint16_t buf_len);
+void _eos_net_sleep_req(NETConfig *config);
+void _eos_net_wake(NETConfig *config);
diff --git a/fw/esp32/components/eos/include/power.h b/fw/esp32/components/eos/include/power.h
index 2215907..2590b80 100644
--- a/fw/esp32/components/eos/include/power.h
+++ b/fw/esp32/components/eos/include/power.h
@@ -1,22 +1,25 @@
#include <stdint.h>
-#define EOS_PWR_MTYPE_BUTTON 1
+#define EOS_PWR_GPIO_NET 8
+#define EOS_PWR_GPIO_APP 10
+#define EOS_PWR_GPIO_MODEM 16
-#define EOS_PWR_WAKE_RST 0
-#define EOS_PWR_WAKE_BTN 1
-#define EOS_PWR_WAKE_UART 2
-#define EOS_PWR_WAKE_NET 3
-#define EOS_PWR_WAKE_NETQ 4
-#define EOS_PWR_WAKE_UNDEF 5
+#define EOS_PWR_DEV_NONE 0
+#define EOS_PWR_DEV_NET ((uint32_t)1 << EOS_PWR_GPIO_NET)
+#define EOS_PWR_DEV_APP ((uint32_t)1 << EOS_PWR_GPIO_APP)
+#define EOS_PWR_DEV_MODEM ((uint32_t)1 << EOS_PWR_GPIO_MODEM)
+#define EOS_PWR_DEV_ALL (EOS_PWR_DEV_NET | EOS_PWR_DEV_APP | EOS_PWR_DEV_MODEM)
-#define EOS_PWR_SMODE_LIGHT 1
-#define EOS_PWR_SMODE_DEEP 2
+#define EOS_PWR_SMODE_TICKLESS 1
+#define EOS_PWR_SMODE_LIGHT 2
+#define EOS_PWR_SMODE_DEEP 3
void eos_power_init(void);
+void eos_power_run(void);
+void eos_power_sys_sleep(uint8_t mode);
+void eos_power_sys_wake(uint8_t mode) ;
+uint32_t eos_power_wakeup_source(void);
-void eos_power_wait4init(void);
-void eos_power_wait4wake(void);
-uint8_t eos_power_wakeup_cause(void);
-void eos_power_sleep(void);
-void eos_power_wake(uint8_t source);
-void eos_power_net_ready(void); \ No newline at end of file
+void eos_power_sleep_req(uint8_t mode, uint32_t dev);
+void eos_power_sleep_rdy(uint32_t dev);
+void eos_power_wake(uint32_t dev);
diff --git a/fw/esp32/components/eos/include/sock.h b/fw/esp32/components/eos/include/sock.h
index 7e937cb..f2cf0c4 100644
--- a/fw/esp32/components/eos/include/sock.h
+++ b/fw/esp32/components/eos/include/sock.h
@@ -15,4 +15,6 @@ typedef struct EOSNetAddr {
uint16_t port;
} EOSNetAddr;
-void eos_sock_init(void); \ No newline at end of file
+void eos_sock_init(void);
+void eos_sock_run(void);
+void eos_sock_reopen(void); \ No newline at end of file
diff --git a/fw/esp32/components/eos/include/wifi.h b/fw/esp32/components/eos/include/wifi.h
index c1819e7..d080e25 100644
--- a/fw/esp32/components/eos/include/wifi.h
+++ b/fw/esp32/components/eos/include/wifi.h
@@ -13,6 +13,7 @@
#define EOS_WIFI_MAX_SCAN_RECORDS 20
void eos_wifi_init(void);
+void eos_wifi_run(void);
int eos_wifi_scan(void);
int eos_wifi_auth(char *ssid, char *pass);
@@ -21,4 +22,4 @@ int eos_wifi_disconnect(void);
ssize_t eos_wifi_get_status(unsigned char *buffer);
void eos_wifi_send_status(void);
-void eos_wifi_send_scan(void); \ No newline at end of file
+void eos_wifi_send_scan(void);
diff --git a/fw/esp32/components/eos/msgq.c b/fw/esp32/components/eos/msgq.c
index c200f7c..57fb669 100644
--- a/fw/esp32/components/eos/msgq.c
+++ b/fw/esp32/components/eos/msgq.c
@@ -12,6 +12,10 @@ void eos_msgq_init(EOSMsgQ *msgq, EOSMsgItem *array, uint8_t size) {
msgq->array = array;
}
+uint8_t eos_msgq_len(EOSMsgQ *msgq) {
+ return (uint8_t)(msgq->idx_w - msgq->idx_r);
+}
+
int eos_msgq_push(EOSMsgQ *msgq, unsigned char type, unsigned char *buffer, uint16_t len) {
if ((uint8_t)(msgq->idx_w - msgq->idx_r) == msgq->size) return EOS_ERR_FULL;
@@ -37,10 +41,6 @@ void eos_msgq_pop(EOSMsgQ *msgq, unsigned char *type, unsigned char **buffer, ui
}
}
-uint8_t eos_msgq_len(EOSMsgQ *msgq) {
- return (uint8_t)(msgq->idx_w - msgq->idx_r);
-}
-
void eos_bufq_init(EOSBufQ *bufq, unsigned char **array, uint8_t size) {
bufq->idx_r = 0;
bufq->idx_w = 0;
@@ -48,6 +48,10 @@ void eos_bufq_init(EOSBufQ *bufq, unsigned char **array, uint8_t size) {
bufq->array = array;
}
+uint8_t eos_bufq_len(EOSBufQ *bufq) {
+ return (uint8_t)(bufq->idx_w - bufq->idx_r);
+}
+
int eos_bufq_push(EOSBufQ *bufq, unsigned char *buffer) {
if ((uint8_t)(bufq->idx_w - bufq->idx_r) == bufq->size) return EOS_ERR_FULL;
@@ -60,7 +64,3 @@ unsigned char *eos_bufq_pop(EOSBufQ *bufq) {
return bufq->array[IDX_MASK(bufq->idx_r++, bufq->size)];
}
-
-uint8_t eos_bufq_len(EOSBufQ *bufq) {
- return (uint8_t)(bufq->idx_w - bufq->idx_r);
-}
diff --git a/fw/esp32/components/eos/net.c b/fw/esp32/components/eos/net.c
index 56ec940..0ba2a2d 100644
--- a/fw/esp32/components/eos/net.c
+++ b/fw/esp32/components/eos/net.c
@@ -16,20 +16,21 @@
#include "eos.h"
#include "msgq.h"
#include "power.h"
+#include "app.h"
#include "net.h"
+#include "net_priv.h"
-#define SPI_GPIO_RTS 22
-#define SPI_GPIO_CTS 21
-#define SPI_GPIO_MOSI 23
-#define SPI_GPIO_MISO 19
-#define SPI_GPIO_SCLK 18
-#define SPI_GPIO_CS 5
+#define SPI_GPIO_RTS 35
+#define SPI_GPIO_CTS 3
+#define SPI_GPIO_MOSI 40
+#define SPI_GPIO_MISO 39
+#define SPI_GPIO_SCLK 38
+#define SPI_GPIO_CS 8
#define SPI_SIZE_BUF (EOS_NET_SIZE_BUF + 4)
#define SPI_SIZE_HDR 3
-static volatile int net_sleep = 0;
-static volatile int net_wake = 0;
+#define SPI_HOST SPI3_HOST
static EOSBufQ net_buf_q;
static unsigned char *net_bufq_array[EOS_NET_SIZE_BUFQ];
@@ -37,262 +38,440 @@ static unsigned char *net_bufq_array[EOS_NET_SIZE_BUFQ];
static EOSMsgQ net_send_q;
static EOSMsgItem net_sndq_array[EOS_NET_SIZE_SNDQ];
-static SemaphoreHandle_t mutex;
-static SemaphoreHandle_t semaph;
-static TaskHandle_t net_xchg_task_handle;
+static NETConfig net_config;
+static eos_net_handler_t net_handler[EOS_NET_MAX_MTYPE];
+
+static spi_bus_config_t net_spi_bus_cfg;
+static spi_slave_interface_config_t net_spi_iface_cfg;
+static spi_slave_transaction_t net_spi_tr_cfg;
+
static const char *TAG = "EOS NET";
-static eos_net_fptr_t net_handler[EOS_NET_MAX_MTYPE];
+static void bad_handler(unsigned char mtype, unsigned char *buffer, uint16_t buf_len) {
+ ESP_LOGE(TAG, "bad handler: 0x%.2X len: %d", mtype, buf_len);
+}
+
+static void net_msg_handler(unsigned char mtype, unsigned char *buffer, uint16_t buf_len) {
+ uint8_t idx;
-static void bad_handler(unsigned char mtype, unsigned char *buffer, uint16_t len) {
- ESP_LOGE(TAG, "bad handler: %d len: %d", mtype, len);
+ idx = mtype & EOS_NET_MTYPE_MASK;
+ if (idx && (idx <= EOS_NET_MAX_MTYPE) && (buf_len <= EOS_NET_MTU)) {
+ net_handler[idx - 1](mtype, buffer, buf_len);
+ } else {
+ bad_handler(mtype, buffer, buf_len);
+ }
}
-// Called after a transaction is queued and ready for pickup by master. We use this to set the handshake line high.
+/* Called after a transaction is queued and ready for pickup by master */
static void _post_setup_cb(spi_slave_transaction_t *trans) {
- gpio_set_level(SPI_GPIO_CTS, 1);
+ NETConfig *config = trans->user;
+
+ gpio_set_level(config->gpio_cts, 0);
}
-// Called after transaction is sent/received. We use this to set the handshake line low.
+/* Called after transaction is sent/received */
static void _post_trans_cb(spi_slave_transaction_t *trans) {
- gpio_set_level(SPI_GPIO_CTS, 0);
+ NETConfig *config = trans->user;
+
+ gpio_set_level(config->gpio_cts, 1);
+}
+
+static void net_goto_sleep(NETConfig *config) {
+ esp_err_t ret;
+ uint8_t msgq_len;
+
+
+ xSemaphoreTake(config->mutex, portMAX_DELAY);
+ msgq_len = eos_msgq_len(config->send_q);
+ if (msgq_len) {
+ gpio_set_level(config->gpio_rts, 0);
+ } else {
+ gpio_set_level(config->gpio_rts, 1);
+ }
+ xSemaphoreGive(config->mutex);
+
+ ret = spi_slave_free(config->spi_host);
+ assert(ret == ESP_OK);
+
+ /* for deep sleep */
+ gpio_hold_en(config->gpio_cts);
+
+ eos_power_sleep_rdy(config->dev);
+ vTaskSuspend(NULL);
+
+ gpio_hold_dis(config->gpio_cts);
+
+ ret = spi_slave_initialize(config->spi_host, config->spi_bus_cfg, config->spi_iface_cfg, SPI_DMA_CH_AUTO);
+ assert(ret == ESP_OK);
+
+ xSemaphoreTake(config->mutex, portMAX_DELAY);
+ config->sleep = 0;
+ msgq_len = eos_msgq_len(config->send_q);
+ if (msgq_len) {
+ gpio_set_level(config->gpio_rts, 0);
+ } else {
+ gpio_set_level(config->gpio_rts, 1);
+ }
+ xSemaphoreGive(config->mutex);
}
-static void net_xchg_task(void *pvParameters) {
- int wake = 0;
- int skip_msg = 0;
+void eos_net_xchg_task(void *param) {
+ NETConfig *config = param;
+ int present, skip_msg = 0, sleep_msg = 0;
unsigned char mtype = 0;
unsigned char mtype_flags = 0;
unsigned char *buffer;
- uint16_t len;
unsigned char *buf_send = heap_caps_malloc(SPI_SIZE_BUF, MALLOC_CAP_DMA);
unsigned char *buf_recv = heap_caps_malloc(SPI_SIZE_BUF, MALLOC_CAP_DMA);
+ uint16_t buf_len;
+ size_t trans_len;
+ spi_bus_config_t *spi_bus_cfg = config->spi_bus_cfg;
+ spi_slave_interface_config_t *spi_iface_cfg = config->spi_iface_cfg;
+ spi_slave_transaction_t *spi_tr_cfg = config->spi_tr_cfg;
esp_err_t ret;
- static spi_slave_transaction_t spi_tr;
-
- //Configuration for the SPI bus
- static spi_bus_config_t spi_bus_cfg = {
- .mosi_io_num = SPI_GPIO_MOSI,
- .miso_io_num = SPI_GPIO_MISO,
- .sclk_io_num = SPI_GPIO_SCLK
- };
-
- //Configuration for the SPI slave interface
- static spi_slave_interface_config_t spi_slave_cfg = {
- .mode = 0,
- .spics_io_num = SPI_GPIO_CS,
- .queue_size = 2,
- .flags = 0,
- .post_setup_cb = _post_setup_cb,
- .post_trans_cb = _post_trans_cb
- };
-
- //Initialize SPI slave interface
- ret = spi_slave_initialize(VSPI_HOST, &spi_bus_cfg, &spi_slave_cfg, 2);
- assert(ret == ESP_OK);
-
- memset(&spi_tr, 0, sizeof(spi_tr));
- spi_tr.tx_buffer = buf_send;
- spi_tr.rx_buffer = buf_recv;
- spi_tr.length = SPI_SIZE_BUF * 8;
-
- if (eos_power_wakeup_cause() != EOS_PWR_WAKE_RST) {
- wake = 1;
- skip_msg = 1;
+ assert(buf_send != NULL);
+ assert(buf_recv != NULL);
+
+ /* Configuration for the SPI bus */
+ spi_bus_cfg->mosi_io_num = config->gpio_mosi;
+ spi_bus_cfg->miso_io_num = config->gpio_miso;
+ spi_bus_cfg->sclk_io_num = config->gpio_sclk;
+
+ /* Configuration for the SPI slave interface */
+ spi_iface_cfg->mode = 0;
+ spi_iface_cfg->spics_io_num = config->gpio_cs;
+ spi_iface_cfg->queue_size = 2;
+ spi_iface_cfg->flags = 0;
+ spi_iface_cfg->post_setup_cb = _post_setup_cb;
+ spi_iface_cfg->post_trans_cb = _post_trans_cb;
+
+ spi_tr_cfg->tx_buffer = buf_send;
+ spi_tr_cfg->rx_buffer = buf_recv;
+ spi_tr_cfg->length = SPI_SIZE_BUF * 8;
+ spi_tr_cfg->user = config;
+
+ xSemaphoreTake(config->mutex, portMAX_DELAY);
+ present = config->present;
+ xSemaphoreGive(config->mutex);
+ if (!present) {
+ vTaskSuspend(NULL);
}
- eos_power_wait4init();
+ /* Initialize SPI slave interface */
+ ret = spi_slave_initialize(config->spi_host, spi_bus_cfg, spi_iface_cfg, SPI_DMA_CH_AUTO);
+ assert(ret == ESP_OK);
+
while (1) {
if (!skip_msg) {
- xSemaphoreTake(mutex, portMAX_DELAY);
+ xSemaphoreTake(config->mutex, portMAX_DELAY);
- eos_msgq_pop(&net_send_q, &mtype, &buffer, &len);
+ eos_msgq_pop(config->send_q, &mtype, &buffer, &buf_len);
if (mtype) {
buf_send[0] = mtype;
- buf_send[1] = len >> 8;
- buf_send[2] = len & 0xFF;
+ buf_send[1] = buf_len >> 8;
+ buf_send[2] = buf_len & 0xFF;
if (buffer) {
- memcpy(buf_send + SPI_SIZE_HDR, buffer, len);
- eos_bufq_push(&net_buf_q, buffer);
- xSemaphoreGive(semaph);
+ memcpy(buf_send + SPI_SIZE_HDR, buffer, buf_len);
+ xSemaphoreTake(config->bufq_mutex, portMAX_DELAY);
+ eos_bufq_push(config->buf_q, buffer);
+ xSemaphoreGive(config->bufq_mutex);
+ xSemaphoreGive(config->bufq_semaph);
}
+ } else if (!sleep_msg && config->sleep_req) {
+ buf_send[0] = EOS_NET_MTYPE_SLEEP;
+ buf_send[1] = 0;
+ buf_send[2] = 0;
+ sleep_msg = 1;
+ config->sleep_req = 0;
+ if (config->dev == NET_DEV_NET) config->sleep = 1;
} else {
- gpio_set_level(SPI_GPIO_RTS, 0);
+ gpio_set_level(config->gpio_rts, 1);
buf_send[0] = 0;
buf_send[1] = 0;
buf_send[2] = 0;
}
- xSemaphoreGive(mutex);
+ xSemaphoreGive(config->mutex);
}
skip_msg = 0;
buf_recv[0] = 0;
buf_recv[1] = 0;
buf_recv[2] = 0;
- spi_slave_transmit(VSPI_HOST, &spi_tr, portMAX_DELAY);
- // ESP_LOGI(TAG, "RECV:%d", buf_recv[0]);
+ ret = spi_slave_transmit(config->spi_host, spi_tr_cfg, portMAX_DELAY);
+ assert(ret == ESP_OK);
+
+ trans_len = spi_tr_cfg->trans_len / 8;
+
+ ESP_LOGI(TAG, "RECV:0x%.2X DEV:0x%.8lX LEN:%d", buf_recv[0], config->dev, trans_len);
+
+ if (sleep_msg && (config->dev == NET_DEV_NET)) {
+ net_goto_sleep(config);
+ sleep_msg = 0;
+ continue;
+ }
+
+ if (trans_len < 1) {
+ ESP_LOGE(TAG, "RECV LEN:%d", trans_len);
+ continue;
+ }
- if (wake) {
- eos_power_net_ready();
- wake = 0;
+ /* SPI reset */
+ if ((trans_len == 1) && (buf_recv[0] == 0)) {
+ if (buf_send[0]) skip_msg = 1;
+ continue;
}
- if ((spi_tr.trans_len / 8) < SPI_SIZE_HDR) continue;
- if (buf_recv[0] == 0x00) continue;
+ mtype = buf_recv[0] & EOS_NET_MTYPE_MASK;
+ mtype_flags = buf_recv[0] & ~EOS_NET_MTYPE_MASK;
+ if (buf_send[0] && (mtype_flags & EOS_NET_MTYPE_FLAG_ONEW)) {
+ skip_msg = 1;
+ }
- if (buf_recv[0] == 0xFF) { // Sleep req
- if (buf_send[0] == 0) {
- spi_slave_free(VSPI_HOST);
- eos_power_sleep();
+ if (buf_send[0] && (trans_len < buf_len + SPI_SIZE_HDR) && !skip_msg) {
+ spi_tr_cfg->tx_buffer = buf_send + trans_len;
+ spi_tr_cfg->rx_buffer = buf_recv + trans_len;
+ spi_tr_cfg->length = (SPI_SIZE_BUF - trans_len) * 8;
+ ret = spi_slave_transmit(config->spi_host, spi_tr_cfg, portMAX_DELAY);
+ assert(ret == ESP_OK);
+ trans_len += spi_tr_cfg->trans_len / 8;
+ spi_tr_cfg->tx_buffer = buf_send;
+ spi_tr_cfg->rx_buffer = buf_recv;
+ spi_tr_cfg->length = SPI_SIZE_BUF * 8;
+ }
- xSemaphoreTake(mutex, portMAX_DELAY);
- net_sleep = 1;
- if (eos_msgq_len(&net_send_q)) net_wake = 1;
- xSemaphoreGive(mutex);
+ if (mtype == 0) continue;
- if (net_wake) eos_power_wake(EOS_PWR_WAKE_NETQ);
- vTaskSuspend(NULL);
+ if (mtype == EOS_NET_MTYPE_SLEEP) {
+ uint8_t mode;
- xSemaphoreTake(mutex, portMAX_DELAY);
- net_sleep = 0;
- net_wake = 0;
- xSemaphoreGive(mutex);
+ mode = EOS_PWR_SMODE_LIGHT;
- spi_slave_initialize(VSPI_HOST, &spi_bus_cfg, &spi_slave_cfg, 1);
- wake = 1;
- skip_msg = 1;
+ switch (config->dev) {
+ case NET_DEV_NET: {
+ eos_power_sleep_req(mode, EOS_PWR_DEV_ALL);
+ break;
+ }
+ case NET_DEV_APP: {
+ uint8_t msgq_len;
+
+ xSemaphoreTake(config->mutex, portMAX_DELAY);
+ msgq_len = eos_msgq_len(config->send_q);
+ if (msgq_len == 0) {
+ config->sleep = 1;
+ config->sleep_req = 0;
+ }
+ xSemaphoreGive(config->mutex);
+ if (msgq_len == 0) {
+ net_goto_sleep(config);
+ sleep_msg = 0;
+ }
+ break;
+ }
}
continue;
}
- mtype = buf_recv[0] & ~EOS_NET_MTYPE_FLAG_MASK;
- mtype_flags = buf_recv[0] & EOS_NET_MTYPE_FLAG_MASK;
- len = (uint16_t)buf_recv[1] << 8;
- len |= (uint16_t)buf_recv[2] & 0xFF;
- buffer = buf_recv + SPI_SIZE_HDR;
- if ((mtype <= EOS_NET_MAX_MTYPE) && (len <= EOS_NET_MTU)) {
- net_handler[mtype - 1](buf_recv[0], buffer, len);
- } else {
- bad_handler(buf_recv[0], buffer, len);
- }
- if ((mtype_flags & EOS_NET_MTYPE_FLAG_ONEW) && buf_send[0]) {
- skip_msg = 1;
+ if (trans_len < SPI_SIZE_HDR) {
+ ESP_LOGE(TAG, "RECV LEN:%d", trans_len);
+ continue;
}
+ buf_len = (uint16_t)buf_recv[1] << 8;
+ buf_len |= (uint16_t)buf_recv[2] & 0xFF;
+ buffer = buf_recv + SPI_SIZE_HDR;
+ config->msg_handler(buf_recv[0], buffer, buf_len);
+
if (mtype_flags & EOS_NET_MTYPE_FLAG_REPL) {
- spi_tr.tx_buffer = buf_recv;
- spi_tr.rx_buffer = NULL;
- spi_slave_transmit(VSPI_HOST, &spi_tr, portMAX_DELAY);
- spi_tr.tx_buffer = buf_send;
- spi_tr.rx_buffer = buf_recv;
+ spi_tr_cfg->tx_buffer = buf_recv;
+ spi_tr_cfg->rx_buffer = NULL;
+ ret = spi_slave_transmit(config->spi_host, spi_tr_cfg, portMAX_DELAY);
+ assert(ret == ESP_OK);
+ spi_tr_cfg->tx_buffer = buf_send;
+ spi_tr_cfg->rx_buffer = buf_recv;
}
}
+
vTaskDelete(NULL);
}
-void eos_net_init(void) {
- int i;
-
- // Configuration for the handshake lines
+void _eos_net_init_gpio(NETConfig *config) {
+ /* Configuration for the handshake lines */
gpio_config_t io_conf = {};
+ gpio_set_level(config->gpio_rts, 1);
+ gpio_set_level(config->gpio_cts, 1);
io_conf.intr_type = GPIO_INTR_DISABLE;
io_conf.mode = GPIO_MODE_OUTPUT;
- io_conf.pull_up_en = 0;
- io_conf.pull_down_en = 0;
- io_conf.pin_bit_mask = ((uint64_t)1 << SPI_GPIO_CTS);
+ io_conf.pull_up_en = GPIO_PULLUP_DISABLE;
+ io_conf.pull_down_en = GPIO_PULLDOWN_DISABLE;
+ io_conf.pin_bit_mask = BIT64(config->gpio_rts) | BIT64(config->gpio_cts);
gpio_config(&io_conf);
- gpio_set_level(SPI_GPIO_CTS, 0);
+}
- io_conf.intr_type = GPIO_INTR_DISABLE;
- io_conf.mode = GPIO_MODE_OUTPUT;
- io_conf.pull_up_en = 0;
- io_conf.pull_down_en = 0;
- io_conf.pin_bit_mask = ((uint64_t)1 << SPI_GPIO_RTS);
- gpio_config(&io_conf);
- gpio_set_level(SPI_GPIO_RTS, 0);
+void eos_net_init(void) {
+ SemaphoreHandle_t mutex;
+ SemaphoreHandle_t bufq_mutex;
+ SemaphoreHandle_t bufq_semaph;
+ int i;
eos_msgq_init(&net_send_q, net_sndq_array, EOS_NET_SIZE_SNDQ);
eos_bufq_init(&net_buf_q, net_bufq_array, EOS_NET_SIZE_BUFQ);
for (i=0; i<EOS_NET_SIZE_BUFQ; i++) {
- eos_bufq_push(&net_buf_q, malloc(EOS_NET_SIZE_BUF));
+ unsigned char *buffer;
+
+ buffer = malloc(EOS_NET_SIZE_BUF);
+ assert(buffer != NULL);
+ eos_bufq_push(&net_buf_q, buffer);
}
for (i=0; i<EOS_NET_MAX_MTYPE; i++) {
net_handler[i] = bad_handler;
}
- semaph = xSemaphoreCreateCounting(EOS_NET_SIZE_BUFQ, EOS_NET_SIZE_BUFQ);
mutex = xSemaphoreCreateBinary();
+ assert(mutex != NULL);
+ bufq_mutex = xSemaphoreCreateBinary();
+ assert(bufq_mutex != NULL);
+ bufq_semaph = xSemaphoreCreateCounting(EOS_NET_SIZE_BUFQ, EOS_NET_SIZE_BUFQ);
+ assert(bufq_semaph != NULL);
+
xSemaphoreGive(mutex);
- xTaskCreate(&net_xchg_task, "net_xchg", EOS_TASK_SSIZE_NET_XCHG, NULL, EOS_TASK_PRIORITY_NET_XCHG, &net_xchg_task_handle);
+ xSemaphoreGive(bufq_mutex);
+
+ net_config.sleep = 0;
+ net_config.sleep_req = 0;
+ net_config.present = 1;
+ net_config.dev = NET_DEV_NET;
+ net_config.gpio_mosi = SPI_GPIO_MOSI;
+ net_config.gpio_miso = SPI_GPIO_MISO;
+ net_config.gpio_sclk = SPI_GPIO_SCLK;
+ net_config.gpio_cs = SPI_GPIO_CS;
+ net_config.gpio_rts = SPI_GPIO_RTS;
+ net_config.gpio_cts = SPI_GPIO_CTS;
+ net_config.spi_host = SPI_HOST;
+ net_config.spi_bus_cfg = &net_spi_bus_cfg;
+ net_config.spi_iface_cfg = &net_spi_iface_cfg;
+ net_config.spi_tr_cfg = &net_spi_tr_cfg;
+ net_config.mutex = mutex;
+ net_config.bufq_mutex = bufq_mutex;
+ net_config.bufq_semaph = bufq_semaph;
+ net_config.buf_q = &net_buf_q;
+ net_config.send_q = &net_send_q;
+ net_config.msg_handler = net_msg_handler;
+
+ _eos_net_init_gpio(&net_config);
+
+ if (esp_reset_reason() == ESP_RST_DEEPSLEEP) {
+ gpio_hold_dis(net_config.gpio_cts);
+ }
+
ESP_LOGI(TAG, "INIT");
}
-unsigned char *eos_net_alloc(void) {
+void eos_net_run(void) {
+ BaseType_t rv;
+
+ rv = xTaskCreate(&eos_net_xchg_task, "net_xchg", EOS_TASK_SSIZE_NET, &net_config, EOS_TASK_PRIORITY_NET, &net_config.xchg_task_handle);
+ assert(rv == pdPASS);
+
+ ESP_LOGI(TAG, "RUN");
+}
+
+unsigned char *_eos_net_alloc(NETConfig *config) {
unsigned char *ret;
- xSemaphoreTake(semaph, portMAX_DELAY);
- xSemaphoreTake(mutex, portMAX_DELAY);
- ret = eos_bufq_pop(&net_buf_q);
- xSemaphoreGive(mutex);
+ xSemaphoreTake(config->bufq_semaph, portMAX_DELAY);
+ xSemaphoreTake(config->bufq_mutex, portMAX_DELAY);
+ ret = eos_bufq_pop(config->buf_q);
+ xSemaphoreGive(config->bufq_mutex);
return ret;
}
+void _eos_net_free(NETConfig *config, unsigned char *buf) {
+ xSemaphoreTake(config->bufq_mutex, portMAX_DELAY);
+ eos_bufq_push(config->buf_q, buf);
+ xSemaphoreGive(config->bufq_semaph);
+ xSemaphoreGive(config->bufq_mutex);
+}
+
+unsigned char *eos_net_alloc(void) {
+ return _eos_net_alloc(&net_config);
+}
+
void eos_net_free(unsigned char *buf) {
- xSemaphoreTake(mutex, portMAX_DELAY);
- eos_bufq_push(&net_buf_q, buf);
- xSemaphoreGive(semaph);
- xSemaphoreGive(mutex);
+ _eos_net_free(&net_config, buf);
}
-int eos_net_send(unsigned char mtype, unsigned char *buffer, uint16_t len) {
+int _eos_net_send(NETConfig *config, unsigned char mtype, unsigned char *buffer, uint16_t buf_len) {
int rv = EOS_OK;
int sleep;
- xSemaphoreTake(mutex, portMAX_DELAY);
- sleep = net_sleep && !net_wake;
- gpio_set_level(SPI_GPIO_RTS, 1);
- rv = eos_msgq_push(&net_send_q, mtype, buffer, len);
- xSemaphoreGive(mutex);
-
- if (rv) eos_net_free(buffer);
+ xSemaphoreTake(config->mutex, portMAX_DELAY);
+ sleep = config->sleep;
+ rv = eos_msgq_push(config->send_q, mtype, buffer, buf_len);
+ if (!rv && !sleep) gpio_set_level(config->gpio_rts, 0);
+ xSemaphoreGive(config->mutex);
- if (sleep) eos_power_wake(EOS_PWR_WAKE_NETQ);
+ if (!rv && sleep) eos_power_wake(config->dev);
+ if (rv) _eos_net_free(config, buffer);
return rv;
}
-void eos_net_reply(unsigned char mtype, unsigned char *buffer, uint16_t len) {
+int eos_net_send(unsigned char mtype, unsigned char *buffer, uint16_t buf_len) {
+ return _eos_net_send(&net_config, mtype, buffer, buf_len);
+}
+
+void eos_net_reply(unsigned char mtype, unsigned char *buffer, uint16_t buf_len) {
buffer -= SPI_SIZE_HDR;
buffer[0] = mtype;
- buffer[1] = len >> 8;
- buffer[2] = len & 0xFF;
+ buffer[1] = buf_len >> 8;
+ buffer[2] = buf_len & 0xFF;
}
-void eos_net_set_handler(unsigned char mtype, eos_net_fptr_t handler) {
- if (handler == NULL) handler = bad_handler;
- if (mtype && (mtype <= EOS_NET_MAX_MTYPE)) net_handler[mtype - 1] = handler;
-}
+void _eos_net_sleep_req(NETConfig *config) {
+ int sleep, present;
+
+ xSemaphoreTake(config->mutex, portMAX_DELAY);
+ sleep = config->sleep;
+ present = config->present;
+ if (!sleep && present) {
+ config->sleep_req = 1;
+ gpio_set_level(config->gpio_rts, 0);
+ }
+ xSemaphoreGive(config->mutex);
-void eos_net_sleep(void) {
- gpio_set_level(SPI_GPIO_CTS, 1);
- vTaskDelay(200 / portTICK_PERIOD_MS);
- gpio_set_level(SPI_GPIO_CTS, 0);
+ if (!present) eos_power_sleep_rdy(config->dev);
}
-void eos_net_wake(uint8_t source, uint8_t mode) {
- int sleep;
+void _eos_net_wake(NETConfig *config) {
+ int sleep, present;
+
+ xSemaphoreTake(config->mutex, portMAX_DELAY);
+ present = config->present;
+ xSemaphoreGive(config->mutex);
- if (mode == EOS_PWR_SMODE_DEEP) return;
+ if (!present) return;
do {
- vTaskResume(net_xchg_task_handle);
+ vTaskResume(config->xchg_task_handle);
vTaskDelay(10 / portTICK_PERIOD_MS);
-
- xSemaphoreTake(mutex, portMAX_DELAY);
- sleep = net_sleep;
- xSemaphoreGive(mutex);
+ xSemaphoreTake(config->mutex, portMAX_DELAY);
+ sleep = config->sleep;
+ xSemaphoreGive(config->mutex);
} while (sleep);
}
+
+void eos_net_sleep_req(void) {
+ _eos_net_sleep_req(&net_config);
+}
+
+void eos_net_wake(void) {
+ _eos_net_wake(&net_config);
+}
+
+void eos_net_set_handler(unsigned char mtype, eos_net_handler_t handler) {
+ if (handler == NULL) handler = bad_handler;
+ if (mtype && (mtype <= EOS_NET_MAX_MTYPE)) net_handler[mtype - 1] = handler;
+}
diff --git a/fw/esp32/components/eos/power.c b/fw/esp32/components/eos/power.c
index b98c0ec..27c44a5 100644
--- a/fw/esp32/components/eos/power.c
+++ b/fw/esp32/components/eos/power.c
@@ -4,37 +4,30 @@
#include <freertos/task.h>
#include <freertos/queue.h>
#include <driver/gpio.h>
+#include <driver/rtc_io.h>
+#include <driver/uart.h>
+
+#include <esp_system.h>
#include <esp_sleep.h>
-#include <esp_timer.h>
#include <esp_pm.h>
#include <esp_log.h>
-#include <esp32/rom/rtc.h>
#include "eos.h"
#include "net.h"
+#include "app.h"
#include "cell.h"
#include "power.h"
-#define POWER_GPIO_BTN 0
-#define POWER_GPIO_NET 5
-#define POWER_GPIO_UART 35
-
-#define POWER_ETYPE_BTN 1
-#define POWER_ETYPE_SLEEP1 2
-#define POWER_ETYPE_SLEEP2 3
-#define POWER_ETYPE_WAKE 4
-#define POWER_ETYPE_NETRDY 5
+#define PWR_ETYPE_SLEEP_REQ 1
+#define PWR_ETYPE_SLEEP_RDY 2
+#define PWR_ETYPE_WAKE 3
typedef struct {
uint8_t type;
- union {
- uint8_t source;
- uint8_t level;
- };
+ uint8_t mode;
+ uint32_t dev;
} power_event_t;
-static esp_timer_handle_t timer;
-
static esp_pm_lock_handle_t power_lock_cpu_freq;
static esp_pm_lock_handle_t power_lock_apb_freq;
static esp_pm_lock_handle_t power_lock_no_sleep;
@@ -43,232 +36,119 @@ static const char *TAG = "EOS POWER";
static QueueHandle_t power_queue;
-static volatile int init_done = 0;
-static volatile int wake_done = 0;
-
-static void IRAM_ATTR btn_handler(void *arg) {
- power_event_t evt;
-
- evt.type = POWER_ETYPE_BTN;
- evt.level = gpio_get_level(POWER_GPIO_BTN);
- xQueueSendFromISR(power_queue, &evt, NULL);
-}
-
-static void IRAM_ATTR btn_wake_handler(void *arg) {
- power_event_t evt;
-
- gpio_intr_disable(POWER_GPIO_BTN);
-
- evt.type = POWER_ETYPE_WAKE;
- evt.source = EOS_PWR_WAKE_BTN;
- xQueueSendFromISR(power_queue, &evt, NULL);
-
-}
-
static void IRAM_ATTR net_wake_handler(void *arg) {
power_event_t evt;
- gpio_intr_disable(POWER_GPIO_NET);
-
- evt.type = POWER_ETYPE_WAKE;
- evt.source = EOS_PWR_WAKE_NET;
+ evt.type = PWR_ETYPE_WAKE;
+ evt.dev = EOS_PWR_DEV_NET;
xQueueSendFromISR(power_queue, &evt, NULL);
}
-static void IRAM_ATTR uart_wake_handler(void *arg) {
+static void IRAM_ATTR app_wake_handler(void *arg) {
power_event_t evt;
- gpio_intr_disable(POWER_GPIO_UART);
-
- evt.type = POWER_ETYPE_WAKE;
- evt.source = EOS_PWR_WAKE_UART;
+ evt.type = PWR_ETYPE_WAKE;
+ evt.dev = EOS_PWR_DEV_APP;
xQueueSendFromISR(power_queue, &evt, NULL);
}
-static void timer_handler(void *arg) {
+static void IRAM_ATTR modem_wake_handler(void *arg) {
power_event_t evt;
- evt.type = POWER_ETYPE_SLEEP2;
+ evt.type = PWR_ETYPE_WAKE;
+ evt.dev = EOS_PWR_DEV_MODEM;
xQueueSendFromISR(power_queue, &evt, NULL);
}
-static void power_sleep_stage1(int modem_wake_en) {
- gpio_config_t io_conf = {};
-
- eos_modem_sleep();
- eos_net_sleep();
-
- io_conf.intr_type = GPIO_INTR_DISABLE;
- io_conf.mode = GPIO_MODE_INPUT;
- io_conf.pin_bit_mask = ((uint64_t)1 << POWER_GPIO_NET);
- io_conf.pull_up_en = 0;
- io_conf.pull_down_en = 0;
- gpio_config(&io_conf);
-
- gpio_isr_handler_add(POWER_GPIO_BTN, btn_wake_handler, NULL);
- gpio_isr_handler_add(POWER_GPIO_NET, net_wake_handler, NULL);
- if (modem_wake_en) {
- gpio_isr_handler_add(POWER_GPIO_UART, uart_wake_handler, NULL);
- }
-
- esp_sleep_enable_gpio_wakeup();
- gpio_wakeup_enable(POWER_GPIO_BTN, GPIO_INTR_LOW_LEVEL);
- gpio_wakeup_enable(POWER_GPIO_NET, GPIO_INTR_LOW_LEVEL);
- if (modem_wake_en) {
- gpio_wakeup_enable(POWER_GPIO_UART, GPIO_INTR_LOW_LEVEL);
- }
-
- esp_timer_start_once(timer, 10 * 1000000);
-
- esp_pm_lock_release(power_lock_cpu_freq);
- esp_pm_lock_release(power_lock_apb_freq);
- esp_pm_lock_release(power_lock_no_sleep);
-}
-
-static void power_sleep_stage2(int modem_wake_en, uint8_t mode) {
- switch (mode) {
- case EOS_PWR_SMODE_LIGHT: {
- ESP_LOGI(TAG, "LIGHT SLEEP");
-
- esp_light_sleep_start();
- break;
- }
-
- case EOS_PWR_SMODE_DEEP: {
- esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_ALL);
-
- gpio_deep_sleep_hold_en();
- esp_sleep_enable_ext0_wakeup(POWER_GPIO_BTN, 0);
- if (modem_wake_en) {
- esp_sleep_enable_ext1_wakeup((uint64_t)1 << POWER_GPIO_UART, ESP_EXT1_WAKEUP_ALL_LOW);
- }
-
- ESP_LOGI(TAG, "DEEP SLEEP");
-
- eos_modem_deep_sleep();
- esp_deep_sleep_start();
- break;
- }
- }
-}
-
-static void power_wake_stage1(uint8_t source, uint8_t mode) {
- if (mode == EOS_PWR_SMODE_LIGHT) {
- gpio_config_t io_conf = {};
-
- esp_pm_lock_acquire(power_lock_cpu_freq);
- esp_pm_lock_acquire(power_lock_apb_freq);
- esp_pm_lock_acquire(power_lock_no_sleep);
-
- gpio_wakeup_disable(POWER_GPIO_BTN);
- gpio_wakeup_disable(POWER_GPIO_NET);
- gpio_wakeup_disable(POWER_GPIO_UART);
- esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_ALL);
-
- gpio_isr_handler_remove(POWER_GPIO_NET);
- io_conf.intr_type = GPIO_INTR_DISABLE;
- io_conf.mode = GPIO_MODE_DISABLE;
- io_conf.pin_bit_mask = ((uint64_t)1 << POWER_GPIO_NET);
- io_conf.pull_up_en = 0;
- io_conf.pull_down_en = 0;
- gpio_config(&io_conf);
- }
-
- gpio_intr_disable(POWER_GPIO_BTN);
- if ((source != EOS_PWR_WAKE_BTN) && (source != EOS_PWR_WAKE_NET)) {
- gpio_set_level(POWER_GPIO_BTN, 0);
- gpio_set_direction(POWER_GPIO_BTN, GPIO_MODE_OUTPUT);
- vTaskDelay(200 / portTICK_PERIOD_MS);
- gpio_set_direction(POWER_GPIO_BTN, GPIO_MODE_INPUT);
- }
-
- eos_net_wake(source, mode);
-}
-
-static void power_wake_stage2(uint8_t source, uint8_t mode) {
- eos_modem_wake(source, mode);
-
- gpio_set_intr_type(POWER_GPIO_BTN, GPIO_INTR_ANYEDGE);
- gpio_isr_handler_add(POWER_GPIO_BTN, btn_handler, NULL);
-
- ESP_LOGI(TAG, "WAKE");
- wake_done = 1;
-}
-
static void power_event_task(void *pvParameters) {
power_event_t evt;
- uint8_t source;
- uint8_t wakeup_cause;
uint8_t mode;
- int sleep1, sleep2;
- int modem_wake_en;
+ uint32_t sleep_req, sleep_rdy;
+ int sys_sleep;
mode = 0;
- source = 0;
- wakeup_cause = eos_power_wakeup_cause();
- if (wakeup_cause != EOS_PWR_WAKE_RST) {
- mode = EOS_PWR_SMODE_DEEP;
- sleep1 = 1;
- } else {
- sleep1 = 0;
- }
- sleep2 = 0;
- modem_wake_en = 0;
-
+ sys_sleep = 0;
+ sleep_req = 0;
+ sleep_rdy = 0;
while (1) {
if (xQueueReceive(power_queue, &evt, portMAX_DELAY)) {
switch (evt.type) {
- case POWER_ETYPE_SLEEP1: {
- if (!sleep1) {
- modem_wake_en = eos_modem_present();
- mode = EOS_PWR_SMODE_LIGHT;
- power_sleep_stage1(modem_wake_en);
- sleep1 = 1;
- sleep2 = 1;
+ case PWR_ETYPE_SLEEP_REQ: {
+ if (evt.mode) mode = evt.mode;
+ if ((evt.dev & EOS_PWR_DEV_NET) && !(sleep_req & EOS_PWR_DEV_NET)) {
+ eos_net_sleep_req();
}
- break;
- }
-
- case POWER_ETYPE_SLEEP2: {
- if (sleep2) {
- mode = EOS_PWR_SMODE_DEEP;
- power_sleep_stage2(modem_wake_en, mode);
- sleep2 = 0;
+ if ((evt.dev & EOS_PWR_DEV_APP) && !(sleep_req & EOS_PWR_DEV_APP)) {
+ eos_app_sleep_req();
}
- break;
- }
-
- case POWER_ETYPE_WAKE: {
- if (sleep1) {
- source = evt.source;
- power_wake_stage1(source, mode);
- if (sleep2) {
- esp_timer_stop(timer);
- sleep2 = 0;
- }
+ if ((evt.dev & EOS_PWR_DEV_MODEM) && !(sleep_req & EOS_PWR_DEV_MODEM)) {
+ eos_modem_sleep_req();
+ }
+ sleep_req |= evt.dev;
+ if (sleep_rdy == EOS_PWR_DEV_ALL) {
+ eos_power_sleep_rdy(0);
}
break;
}
- case POWER_ETYPE_NETRDY: {
- power_wake_stage2(source, mode);
- sleep1 = 0;
- source = 0;
+ case PWR_ETYPE_SLEEP_RDY: {
+ gpio_config_t io_conf = {
+ .mode = GPIO_MODE_INPUT,
+ .intr_type = GPIO_INTR_NEGEDGE,
+ .pull_up_en = 1,
+ .pull_down_en = 0,
+ };
+
+ if (evt.dev & EOS_PWR_DEV_NET) {
+ io_conf.pin_bit_mask = BIT64(EOS_PWR_GPIO_NET);
+ gpio_config(&io_conf);
+ gpio_isr_handler_add(EOS_PWR_GPIO_NET, net_wake_handler, NULL);
+ }
+ if (evt.dev & EOS_PWR_DEV_APP) {
+ io_conf.pin_bit_mask = BIT64(EOS_PWR_GPIO_APP);
+ gpio_config(&io_conf);
+ gpio_isr_handler_add(EOS_PWR_GPIO_APP, app_wake_handler, NULL);
+ }
+ if (evt.dev & EOS_PWR_DEV_MODEM) {
+ io_conf.pin_bit_mask = BIT64(EOS_PWR_GPIO_MODEM);
+ gpio_config(&io_conf);
+ gpio_isr_handler_add(EOS_PWR_GPIO_MODEM, modem_wake_handler, NULL);
+ }
+ sleep_rdy |= evt.dev;
+ if (!sys_sleep && mode && (sleep_rdy == EOS_PWR_DEV_ALL)) {
+ sys_sleep = 1;
+ eos_power_sys_sleep(mode);
+ }
break;
}
- case POWER_ETYPE_BTN: {
- unsigned char *buf;
-
- buf = eos_net_alloc();
- buf[0] = EOS_PWR_MTYPE_BUTTON;
- buf[1] = evt.level;
- eos_net_send(EOS_NET_MTYPE_POWER, buf, 2);
+ case PWR_ETYPE_WAKE: {
+ ESP_LOGI(TAG, "WAKE:0x%.8lX", evt.dev);
+ if (sys_sleep) {
+ eos_power_sys_wake(mode);
+ sys_sleep = 0;
+ mode = 0;
+ }
+ if ((evt.dev & EOS_PWR_DEV_NET) && (sleep_rdy & EOS_PWR_DEV_NET)) {
+ gpio_isr_handler_remove(EOS_PWR_GPIO_NET);
+ gpio_reset_pin(EOS_PWR_GPIO_NET);
+ eos_net_wake();
+ }
+ if ((evt.dev & EOS_PWR_DEV_APP) && (sleep_rdy & EOS_PWR_DEV_APP)) {
+ gpio_isr_handler_remove(EOS_PWR_GPIO_APP);
+ gpio_reset_pin(EOS_PWR_GPIO_APP);
+ eos_app_wake();
+ }
+ if ((evt.dev & EOS_PWR_DEV_MODEM) && (sleep_rdy & EOS_PWR_DEV_MODEM)) {
+ gpio_isr_handler_remove(EOS_PWR_GPIO_MODEM);
+ gpio_reset_pin(EOS_PWR_GPIO_MODEM);
+ eos_modem_wake();
+ }
+ sleep_req &= ~evt.dev;
+ sleep_rdy &= ~evt.dev;
+ ESP_LOGI(TAG, "WAKE DONE:0x%.8lX", evt.dev);
break;
}
-
- default:
- break;
}
}
}
@@ -276,35 +156,9 @@ static void power_event_task(void *pvParameters) {
}
void eos_power_init(void) {
- esp_err_t ret;
- gpio_config_t io_conf = {};
- esp_timer_create_args_t timer_args = {};
- esp_pm_config_esp32_t pwr_conf;
- uint8_t wakeup_cause;
-
- io_conf.intr_type = GPIO_INTR_ANYEDGE;
- io_conf.mode = GPIO_MODE_INPUT;
- io_conf.pin_bit_mask = ((uint64_t)1 << POWER_GPIO_BTN);
- io_conf.pull_up_en = 1;
- io_conf.pull_down_en = 0;
- gpio_config(&io_conf);
- gpio_isr_handler_add(POWER_GPIO_BTN, btn_handler, NULL);
-
- timer_args.callback = timer_handler,
- timer_args.arg = NULL;
- timer_args.name = "sleep";
-
- ret = esp_timer_create(&timer_args, &timer);
- assert(ret == ESP_OK);
-
/*
- ret = esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON);
- assert(ret == ESP_OK);
- ret = esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_FAST_MEM, ESP_PD_OPTION_ON);
- assert(ret == ESP_OK);
- ret = esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_SLOW_MEM, ESP_PD_OPTION_ON);
- assert(ret == ESP_OK);
- */
+ esp_err_t ret;
+ esp_pm_config_t pwr_conf;
ret = esp_pm_lock_create(ESP_PM_CPU_FREQ_MAX, 0, NULL, &power_lock_cpu_freq);
assert(ret == ESP_OK);
@@ -326,70 +180,118 @@ void eos_power_init(void) {
ret = esp_pm_configure(&pwr_conf);
assert(ret == ESP_OK);
+ */
- power_queue = xQueueCreate(4, sizeof(power_event_t));
- xTaskCreate(power_event_task, "power_event", EOS_TASK_SSIZE_PWR, NULL, EOS_TASK_PRIORITY_PWR, NULL);
-
- wakeup_cause = eos_power_wakeup_cause();
- if (wakeup_cause != EOS_PWR_WAKE_RST) {
- eos_power_wake(wakeup_cause);
+ if (esp_reset_reason() == ESP_RST_DEEPSLEEP) {
+ rtc_gpio_deinit(EOS_PWR_GPIO_NET);
+ rtc_gpio_deinit(EOS_PWR_GPIO_APP);
+ rtc_gpio_deinit(EOS_PWR_GPIO_MODEM);
+ eos_power_sys_wake(EOS_PWR_SMODE_DEEP);
}
- init_done = 1;
+ power_queue = xQueueCreate(4, sizeof(power_event_t));
+ assert(power_queue != NULL);
+
ESP_LOGI(TAG, "INIT");
}
-void eos_power_wait4init(void) {
- while (!init_done);
-}
+void eos_power_run(void) {
+ BaseType_t rv;
-void eos_power_wait4wake(void) {
- if (eos_power_wakeup_cause() == EOS_PWR_WAKE_RST) return;
- while (!wake_done);
-}
+ rv = xTaskCreate(power_event_task, "power_event", EOS_TASK_SSIZE_PWR, NULL, EOS_TASK_PRIORITY_PWR, NULL);
+ assert(rv == pdPASS);
-uint8_t eos_power_wakeup_cause(void) {
- esp_reset_reason_t reset_cause = esp_reset_reason();
- esp_sleep_wakeup_cause_t wakeup_cause = esp_sleep_get_wakeup_cause();
+ ESP_LOGI(TAG, "RUN");
+}
- if (reset_cause == ESP_RST_DEEPSLEEP) {
- switch (wakeup_cause) {
- case ESP_SLEEP_WAKEUP_EXT0:
- return EOS_PWR_WAKE_BTN;
+void eos_power_sys_sleep(uint8_t mode) {
+ switch (mode) {
+ case EOS_PWR_SMODE_TICKLESS: {
+ esp_pm_lock_release(power_lock_cpu_freq);
+ esp_pm_lock_release(power_lock_apb_freq);
+ esp_pm_lock_release(power_lock_no_sleep);
+ break;
+ }
- case ESP_SLEEP_WAKEUP_EXT1:
- return EOS_PWR_WAKE_UART;
+ case EOS_PWR_SMODE_LIGHT:
+ case EOS_PWR_SMODE_DEEP: {
+ esp_err_t ret;
+
+ /* in case of missing modem */
+ rtc_gpio_pullup_en(EOS_PWR_GPIO_MODEM);
+ esp_sleep_enable_ext1_wakeup_io(EOS_PWR_DEV_ALL, ESP_EXT1_WAKEUP_ANY_LOW);
+ if (mode == EOS_PWR_SMODE_DEEP) {
+ gpio_deep_sleep_hold_en();
+ esp_deep_sleep_start();
+ } else {
+ ESP_LOGI(TAG, "LIGHT SLEEP");
+ uart_wait_tx_idle_polling(UART_NUM_0);
+ ret = esp_light_sleep_start();
+ ESP_LOGI(TAG, "LIGHT WAKE: %d", ret);
+ eos_power_wake(eos_power_wakeup_source());
+ }
+ break;
+ }
+ }
+}
- default:
- return EOS_PWR_WAKE_UNDEF;
+void eos_power_sys_wake(uint8_t mode) {
+ switch (mode) {
+ case EOS_PWR_SMODE_TICKLESS: {
+ esp_pm_lock_acquire(power_lock_cpu_freq);
+ esp_pm_lock_acquire(power_lock_apb_freq);
+ esp_pm_lock_acquire(power_lock_no_sleep);
+ break;
+ }
+ case EOS_PWR_SMODE_LIGHT:
+ case EOS_PWR_SMODE_DEEP: {
+ rtc_gpio_pullup_dis(EOS_PWR_GPIO_MODEM);
+ esp_sleep_disable_ext1_wakeup_io(0);
+ if (mode == EOS_PWR_SMODE_DEEP) {
+ gpio_deep_sleep_hold_dis();
+ }
+ break;
}
+ }
+}
+
+uint32_t eos_power_wakeup_source(void) {
+ esp_sleep_wakeup_cause_t wakeup_cause;
+ uint32_t dev;
+
+ dev = EOS_PWR_DEV_NONE;
+ wakeup_cause = esp_sleep_get_wakeup_cause();
+ if (wakeup_cause == ESP_SLEEP_WAKEUP_EXT1) {
+ dev = esp_sleep_get_ext1_wakeup_status();
+ return dev;
} else {
- return EOS_PWR_WAKE_RST;
+ ESP_LOGE(TAG, "BAD WAKEUP CAUSE");
}
+ return dev;
}
-void eos_power_sleep(void) {
+void eos_power_sleep_req(uint8_t mode, uint32_t dev) {
power_event_t evt;
- evt.type = POWER_ETYPE_SLEEP1;
- evt.source = 0;
+ evt.type = PWR_ETYPE_SLEEP_REQ;
+ evt.mode = mode;
+ evt.dev = dev;
xQueueSend(power_queue, &evt, portMAX_DELAY);
}
-void eos_power_wake(uint8_t source) {
+void eos_power_sleep_rdy(uint32_t dev) {
power_event_t evt;
- evt.type = POWER_ETYPE_WAKE;
- evt.source = source;
-
+ evt.type = PWR_ETYPE_SLEEP_RDY;
+ evt.dev = dev;
xQueueSend(power_queue, &evt, portMAX_DELAY);
}
-void eos_power_net_ready(void) {
+void eos_power_wake(uint32_t dev) {
power_event_t evt;
- evt.type = POWER_ETYPE_NETRDY;
- evt.source = 0;
-
+ ESP_LOGI(TAG, "WAKE SENT");
+ evt.type = PWR_ETYPE_WAKE;
+ evt.dev = dev;
xQueueSend(power_queue, &evt, portMAX_DELAY);
}
diff --git a/fw/esp32/components/eos/rng.c b/fw/esp32/components/eos/rng.c
index 3927df1..675a79c 100644
--- a/fw/esp32/components/eos/rng.c
+++ b/fw/esp32/components/eos/rng.c
@@ -1,4 +1,4 @@
-#include <esp_system.h>
+#include <esp_random.h>
#include <esp_log.h>
#include <esp_err.h>
@@ -26,6 +26,7 @@ rng_handler_fin:
void eos_rng_init(void) {
eos_net_set_handler(EOS_NET_MTYPE_RNG, rng_handler);
+
ESP_LOGI(TAG, "INIT");
}
diff --git a/fw/esp32/components/eos/sock.c b/fw/esp32/components/eos/sock.c
index 08d95d5..b6ed3e9 100644
--- a/fw/esp32/components/eos/sock.c
+++ b/fw/esp32/components/eos/sock.c
@@ -1,6 +1,7 @@
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
+#include <sys/select.h>
#include <freertos/FreeRTOS.h>
#include <freertos/semphr.h>
@@ -9,6 +10,9 @@
#include <esp_system.h>
#include <esp_log.h>
#include <esp_err.h>
+#include <esp_vfs.h>
+#include <esp_vfs_dev.h>
+#include <esp_vfs_eventfd.h>
#include <lwip/sockets.h>
#include <lwip/err.h>
@@ -23,8 +27,14 @@
static const char *TAG = "EOS SOCK";
static SemaphoreHandle_t mutex;
+static int cmd_fd, rep_fd;
static int _socks[EOS_SOCK_MAX_SOCK];
+#define CMD_OPEN 1
+#define CMD_CLOSE 2
+#define CMD_SEND 3
+#define CMD_REOPEN 4
+
static int t_open_dgram(void) {
struct sockaddr_in _myaddr;
int sock;
@@ -74,83 +84,246 @@ static ssize_t t_recvfrom(int sock, void *msg, size_t msg_size, EOSNetAddr *addr
return recvlen;
}
+static void populate_fds(fd_set *fds, int *max_fd) {
+ int i;
+
+ *max_fd = cmd_fd;
+
+ FD_ZERO(fds);
+ FD_SET(cmd_fd, fds);
+ for (i=0; i<EOS_SOCK_MAX_SOCK; i++) {
+ if (_socks[i]) {
+ FD_SET(_socks[i], fds);
+ if (_socks[i] > *max_fd) {
+ *max_fd = _socks[i];
+ }
+ }
+ }
+}
+
static void udp_rcvr_task(void *pvParameters) {
- uint8_t sock_i = (uint8_t)pvParameters;
- int sock = _socks[sock_i-1];
-
- do {
- EOSNetAddr addr;
- unsigned char *buf, *_buf;
- ssize_t rv;
-
- buf = eos_net_alloc();
- rv = t_recvfrom(sock, buf + EOS_SOCK_SIZE_UDP_HDR, EOS_NET_SIZE_BUF - EOS_SOCK_SIZE_UDP_HDR, &addr);
- if (rv < 0) {
- eos_net_free(buf);
- ESP_LOGE(TAG, "UDP RECV ERR:%d", rv);
- break;
+ EOSNetAddr addr;
+ unsigned char *buffer;
+ uint16_t buf_len;
+ fd_set all_fds, read_fds;
+ uint8_t sock_i;
+ uint8_t cmd[8];
+ ssize_t _rv;
+ int sock, max_fd, i;
+ int rv;
+
+ assert(sizeof(buffer) == 4);
+
+ populate_fds(&all_fds, &max_fd);
+ while (1) {
+ memcpy(&read_fds, &all_fds, sizeof(fd_set));
+ rv = select(max_fd + 1, &read_fds, NULL, NULL, NULL);
+ if (rv <= 0) {
+ ESP_LOGE(TAG, "SELECT ERR:%d", rv);
+ continue;
}
- _buf = buf;
- _buf[0] = EOS_SOCK_MTYPE_PKT;
- _buf[1] = sock_i;
- _buf += 2;
- memcpy(_buf, addr.host, sizeof(addr.host));
- _buf += sizeof(addr.host);
- _buf[0] = addr.port >> 8;
- _buf[1] = addr.port;
- _buf += sizeof(addr.port);
- eos_net_send(EOS_NET_MTYPE_SOCK, buf, rv + EOS_SOCK_SIZE_UDP_HDR);
- } while (1);
- xSemaphoreTake(mutex, portMAX_DELAY);
- _socks[sock_i-1] = 0;
- xSemaphoreGive(mutex);
+ for (i=0; i<EOS_SOCK_MAX_SOCK; i++) {
+ sock = _socks[i];
+ if (sock && FD_ISSET(sock, &read_fds)) {
+ unsigned char *_buf;
+
+ buffer = eos_net_alloc();
+ _rv = t_recvfrom(sock, buffer + EOS_SOCK_SIZE_UDP_HDR, EOS_NET_SIZE_BUF - EOS_SOCK_SIZE_UDP_HDR, &addr);
+ if (_rv < 0) {
+ eos_net_free(buffer);
+ ESP_LOGE(TAG, "RECV ERR:%d", _rv);
+ }
+ _buf = buffer;
+ _buf[0] = EOS_SOCK_MTYPE_PKT;
+ _buf[1] = i + 1;
+ _buf += 2;
+ memcpy(_buf, addr.host, sizeof(addr.host));
+ _buf += sizeof(addr.host);
+ _buf[0] = addr.port >> 8;
+ _buf[1] = addr.port;
+ _buf += sizeof(addr.port);
+ rv = eos_net_send(EOS_NET_MTYPE_SOCK, buffer, _rv + EOS_SOCK_SIZE_UDP_HDR);
+ if (rv) ESP_LOGE(TAG, "NET SEND ERR:%d", rv);
+ }
+ }
+ if (FD_ISSET(cmd_fd, &read_fds)) {
+ rv = read(cmd_fd, cmd, sizeof(cmd));
+ assert(rv == sizeof(cmd));
+
+ switch (cmd[0]) {
+ case CMD_OPEN: {
+ sock = t_open_dgram();
+ sock_i = 0;
+ if (sock > 0) {
+ for (i=0; i<EOS_SOCK_MAX_SOCK; i++) {
+ if (_socks[i] == 0) {
+ sock_i = i + 1;
+ _socks[i] = sock;
+ break;
+ }
+ }
+ if (sock_i) {
+ populate_fds(&all_fds, &max_fd);
+ }
+ }
+ memset(cmd, 0, sizeof(cmd));
+ cmd[1] = sock_i;
+
+ rv = write(rep_fd, cmd, sizeof(cmd));
+ assert(rv == sizeof(cmd));
+
+ break;
+ }
+
+ case CMD_CLOSE: {
+ sock_i = cmd[1] - 1;
+ sock = _socks[sock_i];
+ if (sock) {
+ t_close(sock);
+ _socks[sock_i] = 0;
+ populate_fds(&all_fds, &max_fd);
+ }
+
+ rv = write(rep_fd, cmd, sizeof(cmd));
+ assert(rv == sizeof(cmd));
+
+ break;
+ }
+
+ case CMD_SEND: {
+ sock_i = cmd[1] - 1;
+ buf_len = (uint16_t)cmd[2] << 8;
+ buf_len |= (uint16_t)cmd[3];
+ memcpy(&buffer, cmd + 4, sizeof(buffer));
+
+ sock = _socks[sock_i];
+ memcpy(addr.host, buffer, sizeof(addr.host));
+ buffer += sizeof(addr.host);
+ buf_len -= sizeof(addr.host);
+ addr.port = (uint16_t)buffer[0] << 8;
+ addr.port |= (uint16_t)buffer[1];
+ buffer += sizeof(addr.port);
+ buf_len -= sizeof(addr.port);
+ _rv = t_sendto(sock, buffer, buf_len, &addr);
+
+ memset(cmd, 0, sizeof(cmd));
+
+ rv = write(rep_fd, cmd, sizeof(cmd));
+ assert(rv == sizeof(cmd));
+
+ break;
+ }
+
+ case CMD_REOPEN: {
+ buffer = NULL;
+ buf_len = 0;
+
+ for (i=0; i<EOS_SOCK_MAX_SOCK; i++) {
+ sock = _socks[i];
+ if (sock) {
+ t_close(sock);
+ _socks[i] = -1;
+ }
+ }
+ for (i=0; i<EOS_SOCK_MAX_SOCK; i++) {
+ sock = _socks[i];
+ if (sock) {
+ sock = t_open_dgram();
+ if (sock > 0) {
+ _socks[i] = sock;
+ } else {
+ _socks[i] = 0;
+ if (buffer) {
+ buffer[buf_len] = i + 1;
+ buf_len++;
+ } else {
+ buffer = eos_net_alloc();
+ buffer[0] = EOS_SOCK_MTYPE_CLOSE;
+ buffer[1] = i + 1;
+ buf_len = 2;
+ }
+ }
+ }
+ }
+ if (buffer) {
+ rv = eos_net_send(EOS_NET_MTYPE_SOCK, buffer, buf_len);
+ if (rv) ESP_LOGE(TAG, "NET SEND ERR:%d", rv);
+ }
+
+ rv = write(rep_fd, cmd, sizeof(cmd));
+ assert(rv == sizeof(cmd));
+
+ break;
+ }
+
+ default:
+ ESP_LOGE(TAG, "BAD CMD:%d", cmd[0]);
+ break;
+ }
+
+ }
+ }
+
vTaskDelete(NULL);
}
static void sock_handler(unsigned char _mtype, unsigned char *buffer, uint16_t buf_len) {
unsigned char mtype;
uint8_t sock_i;
- int sock, i;
+ uint8_t cmd[8];
+ int rv;
if (buf_len < 1) return;
+ memset(cmd, 0, sizeof(cmd));
+
mtype = buffer[0];
switch (mtype) {
case EOS_SOCK_MTYPE_PKT: {
- EOSNetAddr addr;
+ unsigned char *_buf = buffer;
if (buf_len < EOS_SOCK_SIZE_UDP_HDR) return;
- sock_i = buffer[1]-1;
- if (sock_i >= EOS_SOCK_MAX_SOCK) return;
-
- sock = _socks[sock_i];
- buffer += 2;
- memcpy(addr.host, buffer, sizeof(addr.host));
- buffer += sizeof(addr.host);
- addr.port = (uint16_t)buffer[0] << 8;
- addr.port |= (uint16_t)buffer[1];
- buffer += sizeof(addr.port);
- t_sendto(sock, buffer, buf_len - EOS_SOCK_SIZE_UDP_HDR, &addr);
+ sock_i = buffer[1];
+ if ((sock_i == 0) || (sock_i > EOS_SOCK_MAX_SOCK)) return;
+
+ _buf += 2;
+ cmd[0] = CMD_SEND;
+ cmd[1] = sock_i;
+ cmd[2] = buf_len >> 8;
+ cmd[3] = buf_len;
+ memcpy(cmd + 4, &_buf, sizeof(_buf));
+
+ xSemaphoreTake(mutex, portMAX_DELAY);
+
+ rv = write(cmd_fd, cmd, sizeof(cmd));
+ assert(rv == sizeof(cmd));
+
+ rv = read(rep_fd, cmd, sizeof(cmd));
+ assert(rv == sizeof(cmd));
+
+ xSemaphoreGive(mutex);
+
+ assert(cmd[0] == CMD_SEND);
break;
}
case EOS_SOCK_MTYPE_OPEN_DGRAM: {
- sock = t_open_dgram();
- sock_i = 0;
- if (sock > 0) {
- xSemaphoreTake(mutex, portMAX_DELAY);
- for (i=0; i<EOS_SOCK_MAX_SOCK; i++) {
- if (_socks[i] == 0) {
- sock_i = i+1;
- _socks[i] = sock;
- break;
- }
- }
- xSemaphoreGive(mutex);
- }
- if (sock_i) xTaskCreate(&udp_rcvr_task, "udp_rcvr", EOS_TASK_SSIZE_UDP_RCVR, (void *)sock_i, EOS_TASK_PRIORITY_UDP_RCVR, NULL);
+ cmd[0] = CMD_OPEN;
+
+ xSemaphoreTake(mutex, portMAX_DELAY);
+
+ rv = write(cmd_fd, cmd, sizeof(cmd));
+ assert(rv == sizeof(cmd));
+
+ rv = read(rep_fd, cmd, sizeof(cmd));
+ assert(rv == sizeof(cmd));
+
+ xSemaphoreGive(mutex);
+
+ assert(cmd[0] == CMD_OPEN);
+ sock_i = cmd[1];
buffer[0] = EOS_SOCK_MTYPE_OPEN_DGRAM;
buffer[1] = sock_i;
eos_net_reply(EOS_NET_MTYPE_SOCK, buffer, 2);
@@ -160,19 +333,72 @@ static void sock_handler(unsigned char _mtype, unsigned char *buffer, uint16_t b
case EOS_SOCK_MTYPE_CLOSE: {
if (buf_len < 2) return;
- sock_i = buffer[1]-1;
- if (sock_i >= EOS_SOCK_MAX_SOCK) return;
+ sock_i = buffer[1];
+ if ((sock_i == 0) || (sock_i > EOS_SOCK_MAX_SOCK)) return;
+
+ cmd[0] = CMD_CLOSE;
+ cmd[1] = sock_i;
+
+ xSemaphoreTake(mutex, portMAX_DELAY);
- sock = _socks[sock_i];
- t_close(sock);
+ rv = write(cmd_fd, cmd, sizeof(cmd));
+ assert(rv == sizeof(cmd));
+
+ rv = read(rep_fd, cmd, sizeof(cmd));
+ assert(rv == sizeof(cmd));
+
+ xSemaphoreGive(mutex);
+
+ assert(cmd[0] == CMD_CLOSE);
break;
}
}
}
void eos_sock_init(void) {
+ esp_vfs_eventfd_config_t config = ESP_VFS_EVENTD_CONFIG_DEFAULT();
+ esp_err_t ret;
+
+ ret = esp_vfs_eventfd_register(&config);
+ assert(ret == ESP_OK);
+
+ cmd_fd = eventfd(0, 0);
+ assert(cmd_fd > 0);
+
+ rep_fd = eventfd(0, 0);
+ assert(rep_fd > 0);
+
mutex = xSemaphoreCreateBinary();
+ assert(mutex != NULL);
xSemaphoreGive(mutex);
+
eos_net_set_handler(EOS_NET_MTYPE_SOCK, sock_handler);
+
ESP_LOGI(TAG, "INIT");
}
+
+void eos_sock_run(void) {
+ BaseType_t rv;
+
+ rv = xTaskCreate(&udp_rcvr_task, "udp_rcvr", EOS_TASK_SSIZE_SOCK, NULL, EOS_TASK_PRIORITY_SOCK, NULL);
+ assert(rv == pdPASS);
+
+ ESP_LOGI(TAG, "RUN");
+}
+
+void eos_sock_reopen(void) {
+ uint8_t cmd[8];
+ int rv;
+
+ cmd[0] = CMD_REOPEN;
+ xSemaphoreTake(mutex, portMAX_DELAY);
+
+ rv = write(cmd_fd, cmd, sizeof(cmd));
+ assert(rv == sizeof(cmd));
+
+ rv = read(rep_fd, cmd, sizeof(cmd));
+ assert(rv == sizeof(cmd));
+
+ xSemaphoreGive(mutex);
+ assert(cmd[0] == CMD_REOPEN);
+}
diff --git a/fw/esp32/components/eos/tun.c b/fw/esp32/components/eos/tun.c
index a7181ee..f27fcfe 100644
--- a/fw/esp32/components/eos/tun.c
+++ b/fw/esp32/components/eos/tun.c
@@ -6,13 +6,14 @@
#include <lwip/tcpip.h>
#include <lwip/etharp.h>
+#include "net.h"
#include "app.h"
#include "tun.h"
static ip4_addr_t ipaddr, netmask, gw;
static struct netif netif_tun;
-static err_t ESP_IRAM_ATTR tun_output(struct netif *netif, struct pbuf *p, const struct ip4_addr *ipaddr) {
+static err_t IRAM_ATTR tun_output(struct netif *netif, struct pbuf *p, const struct ip4_addr *ipaddr) {
unsigned char *buf;
struct pbuf *q;
@@ -27,7 +28,7 @@ static err_t ESP_IRAM_ATTR tun_output(struct netif *netif, struct pbuf *p, const
return ERR_OK;
}
-static void ESP_IRAM_ATTR tun_input(unsigned char mtype, unsigned char *buffer, uint16_t len) {
+static void IRAM_ATTR tun_input(unsigned char mtype, unsigned char *buffer, uint16_t len) {
struct netif *netif = &netif_tun;
struct pbuf *p;
int rv;
@@ -55,11 +56,15 @@ static err_t tun_init(struct netif *netif) {
}
void eos_tun_init(void) {
+ struct netif *rv;
+
IP4_ADDR(&gw, 0,0,0,0);
IP4_ADDR(&ipaddr, 192,168,10,2);
IP4_ADDR(&netmask, 255,255,255,0);
- netif_add(&netif_tun, &ipaddr, &netmask, &gw, NULL, tun_init, tcpip_input);
+ rv = netif_add(&netif_tun, &ipaddr, &netmask, &gw, NULL, tun_init, tcpip_input);
+ assert(rv != NULL);
+
netif_set_up(&netif_tun);
eos_app_set_handler(EOS_APP_MTYPE_TUN, tun_input);
-} \ No newline at end of file
+}
diff --git a/fw/esp32/components/eos/wifi.c b/fw/esp32/components/eos/wifi.c
index 2be169f..77f9143 100755
--- a/fw/esp32/components/eos/wifi.c
+++ b/fw/esp32/components/eos/wifi.c
@@ -10,7 +10,6 @@
#include <esp_log.h>
#include <esp_err.h>
#include <esp_wifi.h>
-#include <nvs_flash.h>
#include "eos.h"
#include "net.h"
@@ -53,8 +52,6 @@ static void wifi_event_handler(void *arg, esp_event_base_t event_base, int32_t e
ESP_LOGI(TAG, "Event disconnected - reason: %d", sta_disconnected->reason);
if (sta_disconnected->reason == WIFI_REASON_ASSOC_LEAVE) {
- stop = 0;
- reconnect_cnt = 0;
eos_wifi_send_status();
break;
}
@@ -113,25 +110,25 @@ static void wifi_handler(unsigned char _mtype, unsigned char *buffer, uint16_t b
mtype = buffer[0];
switch (mtype) {
case EOS_WIFI_MTYPE_STATUS: {
- int reply;
- ssize_t rv;
+ unsigned char *_buffer;
+ ssize_t _rv;
+ int reply, rv;
reply = _mtype & EOS_NET_MTYPE_FLAG_REPL;
if (reply) {
- rv = eos_wifi_get_status(buffer + 1);
- if (rv < 0) break;
+ _rv = eos_wifi_get_status(buffer + 1);
+ if (_rv < 0) break;
- eos_net_reply(EOS_NET_MTYPE_WIFI, buffer, rv + 1);
+ eos_net_reply(EOS_NET_MTYPE_WIFI, buffer, _rv + 1);
} else {
- unsigned char *buf;
-
- buf = eos_net_alloc();
- buf[0] = EOS_WIFI_MTYPE_STATUS;
- rv = eos_wifi_get_status(buf + 1);
- if (rv < 0) break;
+ _buffer = eos_net_alloc();
+ _buffer[0] = EOS_WIFI_MTYPE_STATUS;
+ _rv = eos_wifi_get_status(_buffer + 1);
+ if (_rv < 0) break;
- eos_net_send(EOS_NET_MTYPE_WIFI, buf, rv + 1);
+ rv = eos_net_send(EOS_NET_MTYPE_WIFI, _buffer, _rv + 1);
+ if (rv) ESP_LOGE(TAG, "NET SEND ERR:%d", rv);
}
break;
}
@@ -202,20 +199,14 @@ static void wifi_handler(unsigned char _mtype, unsigned char *buffer, uint16_t b
}
void eos_wifi_init(void) {
- esp_err_t ret;
wifi_init_config_t wifi_config = WIFI_INIT_CONFIG_DEFAULT();
+ esp_err_t ret;
wifi_netif = esp_netif_create_default_wifi_sta();
ret = esp_wifi_init(&wifi_config);
assert(ret == ESP_OK);
- ret = esp_event_handler_instance_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &wifi_event_handler, NULL, NULL);
- assert(ret == ESP_OK);
-
- ret = esp_event_handler_instance_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &wifi_event_handler, NULL, NULL);
- assert(ret == ESP_OK);
-
ret = esp_wifi_set_storage(WIFI_STORAGE_RAM);
assert(ret == ESP_OK);
@@ -226,9 +217,22 @@ void eos_wifi_init(void) {
assert(ret == ESP_OK);
eos_net_set_handler(EOS_NET_MTYPE_WIFI, wifi_handler);
+
ESP_LOGI(TAG, "INIT");
}
+void eos_wifi_run(void) {
+ esp_err_t ret;
+
+ ret = esp_event_handler_instance_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &wifi_event_handler, NULL, NULL);
+ assert(ret == ESP_OK);
+
+ ret = esp_event_handler_instance_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &wifi_event_handler, NULL, NULL);
+ assert(ret == ESP_OK);
+
+ ESP_LOGI(TAG, "RUN");
+}
+
ssize_t eos_wifi_get_status(unsigned char *buffer) {
unsigned char *p;
wifi_ap_record_t ap_info;
@@ -293,26 +297,28 @@ ssize_t eos_wifi_get_status(unsigned char *buffer) {
void eos_wifi_send_status(void) {
unsigned char *rbuf;
- ssize_t rv;
+ ssize_t _rv;
+ int rv;
rbuf = eos_net_alloc();
rbuf[0] = EOS_WIFI_MTYPE_STATUS;
- rv = eos_wifi_get_status(rbuf + 1);
- if (rv < 0) {
+ _rv = eos_wifi_get_status(rbuf + 1);
+ if (_rv < 0) {
eos_net_free(rbuf);
return;
}
- eos_net_send(EOS_NET_MTYPE_WIFI, rbuf, rv + 1);
+ rv = eos_net_send(EOS_NET_MTYPE_WIFI, rbuf, _rv + 1);
+ if (rv) ESP_LOGE(TAG, "NET SEND ERR:%d", rv);
}
void eos_wifi_send_scan(void) {
static wifi_ap_record_t scan_r[EOS_WIFI_MAX_SCAN_RECORDS];
static uint16_t scan_n;
- unsigned char *rbuf, *p;
- int i;
size_t len;
esp_err_t ret;
+ unsigned char *rbuf, *p;
+ int i, rv;
scan_n = EOS_WIFI_MAX_SCAN_RECORDS;
memset(scan_r, 0, sizeof(scan_r));
@@ -336,5 +342,7 @@ void eos_wifi_send_scan(void) {
strcpy((char *)p, (char *)scan_r[i].ssid);
p += len + 1;
}
- eos_net_send(EOS_NET_MTYPE_WIFI, rbuf, p - rbuf);
+
+ rv = eos_net_send(EOS_NET_MTYPE_WIFI, rbuf, p - rbuf);
+ if (rv) ESP_LOGE(TAG, "NET SEND ERR:%d", rv);
}
diff --git a/fw/esp32/main/component.mk b/fw/esp32/main/component.mk
deleted file mode 100644
index 61f8990..0000000
--- a/fw/esp32/main/component.mk
+++ /dev/null
@@ -1,8 +0,0 @@
-#
-# Main component makefile.
-#
-# This Makefile can be left empty. By default, it will take the sources in the
-# src/ directory, compile them and link them into lib(subdirectory_name).a
-# in the build directory. This behaviour is entirely configurable,
-# please read the ESP-IDF documents if you need to do this.
-#
diff --git a/fw/fe310/eos/board.h b/fw/fe310/eos/board.h
index 21732dc..7836bd7 100644
--- a/fw/fe310/eos/board.h
+++ b/fw/fe310/eos/board.h
@@ -1,24 +1,30 @@
-#define SPI_DIV_NET 16
-#define SPI_DIV_EVE 4
-#define SPI_DIV_SDC 1024
+#define SPI_DIV_NET 16 /* 60 MHz max */
+#define SPI_DIV_EVE 5 /* 30 MHz max */
+#define SPI_DIV_SDC 5
#define SPI_DIV_CAM 24
+#define SPI_DIV_LCD 0 /* spi 9bit */
+#define SPI_DIV_HPAMP 1024
#define SPI_CSID_NET 0
#define SPI_CSID_EVE 2
-#define SPI_CSID_SDC -1
+#define SPI_CSID_SDC SPI_CSID_NONE
#define SPI_CSID_CAM 3
+#define SPI_CSID_LCD SPI_CSID_NONE
+#define SPI_CSID_HPAMP SPI_CSID_NONE
-#define SPI_IOF_MASK ((1 << IOF_SPI1_SCK) | (1 << IOF_SPI1_MOSI) | (1 << IOF_SPI1_MISO) | (1 << IOF_SPI1_SS0) | (1 << IOF_SPI1_SS2) | (1 << IOF_SPI1_SS3))
-
-#define SPI_CSPIN_NET -1
-#define SPI_CSPIN_EVE -1
+#define SPI_CSPIN_NET 2
+#define SPI_CSPIN_EVE 9
#define SPI_CSPIN_SDC 0
-#define SPI_CSPIN_CAM -1
-/* only when i2s is off */
-#define SPI_CSPIN_LCD 21
+#define SPI_CSPIN_CAM 10
+#define SPI_CSPIN_LCD 21 /* only when i2s is off */
+#define SPI_CSPIN_HPAMP (SPI_CSFLAG_EGPIO | EGPIO_PIN_HPAMP_CS)
-#define NET_PIN_RTS 20
-#define NET_PIN_CTS 22
+#define SPI_IOF_MASK ((1 << IOF_SPI1_SCK) | (1 << IOF_SPI1_MOSI) | (1 << IOF_SPI1_MISO) | (1 << IOF_SPI1_SS0) | (1 << IOF_SPI1_SS2) | (1 << IOF_SPI1_SS3))
+// #define SPI_IOF_CSXOR ((1 << IOF_SPI1_SS0) | (1 << IOF_SPI1_SS3))
+#define SPI_IOF_CSXOR 0
+
+#define NET_PIN_RTS 22
+#define NET_PIN_CTS 20
#define EGPIO_PIN_INT 23
@@ -32,6 +38,8 @@
#define I2S_PIN_INT 16
/* only when i2s is off */
-#define EVE_PIN_INTR 1 /* only when EGPIO_PIN_CTP_SEL is off */
-#define CTP_PIN_INT 1 /* only when EGPIO_PIN_CTP_SEL is on */
-#define CTP_PIN_RST 19
+#define CTP_PIN_INT 1 /* EGPIO_PIN_CTP_SEL is on: CTP int; EGPIO_PIN_CTP_SEL is off: EVE int */
+#define CTP_PIN_RST 19 /* only when EGPIO_PIN_CTP_SEL is on */
+
+/* EVE gpio in dev/eve_priv.h */
+/* FXL6408 gpio in dev/egpio.h */ \ No newline at end of file
diff --git a/fw/fe310/eos/dev/Makefile b/fw/fe310/eos/dev/Makefile
index 75f36ab..874e625 100644
--- a/fw/fe310/eos/dev/Makefile
+++ b/fw/fe310/eos/dev/Makefile
@@ -1,7 +1,8 @@
include ../../common.mk
CFLAGS += -I$(bsp_dir)/include -I$(ext_dir)/crypto
-obj = flash.o spi.o net.o bq25895.o sdcard.o sdc_crypto.o lcd.o gt911.o ili9806e.o eve.o ov2640.o cam.o egpio.o fxl6408.o apds9151.o tps61052.o
+obj = flash.o aon.o pwr.o batt.o hpamp.o egpio.o eve.o lcd.o ctp.o spi.o net.o sdcard.o sdc_crypto.o app.o
+subdirs = drv
lib = ../../libeos-dev.a
@@ -14,7 +15,13 @@ lib = ../../libeos-dev.a
all: $(lib)
$(lib): $(obj)
- $(AR) rcs $@ $(obj)
+ for i in $(subdirs); do \
+ (cd $$i && $(MAKE)) || exit; \
+ done
+ $(AR) rcs $@ $(obj) drv/*.o
clean:
+ for i in $(subdirs); do \
+ (cd $$i && $(MAKE) clean) || exit; \
+ done
rm -f *.o $(lib)
diff --git a/fw/fe310/eos/dev/aon.c b/fw/fe310/eos/dev/aon.c
new file mode 100644
index 0000000..7e4f5ec
--- /dev/null
+++ b/fw/fe310/eos/dev/aon.c
@@ -0,0 +1,42 @@
+#include <stdlib.h>
+#include <stdint.h>
+
+#include "eos.h"
+#include "soc/aon.h"
+
+#include "aon.h"
+
+#define AON_EVE_REG 0
+#define AON_EVE_MASK 0x03
+
+#define AON_NET_REG 0
+#define AON_NET_MASK 0x04
+
+void eos_aon_save4eve(uint8_t power_state) {
+ uint32_t reg;
+
+ power_state &= AON_EVE_MASK;
+ reg = eos_aon_get_reg(AON_EVE_REG);
+ reg &= ~AON_EVE_MASK;
+ reg |= power_state;
+
+ eos_aon_set_reg(AON_EVE_REG, reg);
+}
+
+uint8_t eos_aon_load4eve(void) {
+ return (eos_aon_get_reg(AON_EVE_REG) & AON_EVE_MASK);
+}
+
+void eos_aon_save4net(int absent) {
+ uint32_t reg;
+
+ reg = eos_aon_get_reg(AON_NET_REG);
+ reg &= ~AON_NET_MASK;
+ if (absent) reg |= AON_NET_MASK;
+
+ eos_aon_set_reg(AON_NET_REG, reg);
+}
+
+int eos_aon_load4net(void) {
+ return !!(eos_aon_get_reg(AON_NET_REG) & AON_NET_MASK);
+} \ No newline at end of file
diff --git a/fw/fe310/eos/dev/aon.h b/fw/fe310/eos/dev/aon.h
new file mode 100644
index 0000000..4551cc0
--- /dev/null
+++ b/fw/fe310/eos/dev/aon.h
@@ -0,0 +1,7 @@
+#include <stdint.h>
+
+void eos_aon_save4eve(uint8_t power_state);
+uint8_t eos_aon_load4eve(void);
+
+void eos_aon_save4net(int absent);
+int eos_aon_load4net(void); \ No newline at end of file
diff --git a/fw/fe310/eos/dev/app.c b/fw/fe310/eos/dev/app.c
index 3c215f4..ce2cf05 100644
--- a/fw/fe310/eos/dev/app.c
+++ b/fw/fe310/eos/dev/app.c
@@ -2,23 +2,18 @@
#include <stdint.h>
#include "eos.h"
+#include "log.h"
#include "hpamp.h"
#include "app.h"
-#ifdef EOS_DEBUG
-#include <stdio.h>
-#endif
-
void eos_app_hp_change(int hp_det) {
if (hp_det) {
int rv;
rv = eos_hpamp_init();
if (rv) {
-#ifdef EOS_DEBUG
- printf("I2S HP CHANGE: PCM1770 INIT ERR:%d\n", rv);
-#endif
+ EOS_LOG(EOS_LOG_ERR, "I2S HP CHANGE: PCM1770 INIT ERR:%d\n", rv);
return;
}
}
diff --git a/fw/fe310/eos/dev/batt.c b/fw/fe310/eos/dev/batt.c
new file mode 100644
index 0000000..45e6af0
--- /dev/null
+++ b/fw/fe310/eos/dev/batt.c
@@ -0,0 +1,52 @@
+#include <stdlib.h>
+#include <stdint.h>
+
+#include "eos.h"
+#include "log.h"
+
+#include "soc/pwr.h"
+
+#include "drv/bq25895.h"
+
+int eos_batt_init(void) {
+ uint8_t wakeup_cause;
+ int rst, rv;
+#ifdef EOS_DEBUG
+ uint8_t data;
+ int i;
+#endif
+
+ rv = EOS_OK;
+
+ wakeup_cause = eos_pwr_wakeup_cause();
+ rst = (wakeup_cause == EOS_PWR_WAKE_RST);
+ if (rst) {
+ // if (!rv) rv = bq25895_reg_write(0x14, 0x80); // reset
+ // if (!rv) rv = bq25895_reg_write(0x14, 0x00);
+ if (!rv) rv = bq25895_reg_write(0x07, 0x8d); // disable watchdog
+ if (!rv) rv = bq25895_reg_write(0x03, 0x2e); // disable charging, 3.7V minimum output
+ }
+ if (rv) return rv;
+
+#ifdef EOS_DEBUG
+ EOS_LOG(EOS_LOG_INFO, "BQ25895:\n");
+ for (i=0; i<0x15; i++) {
+ rv = bq25895_reg_read(i, &data);
+ if (!rv) EOS_LOG(EOS_LOG_INFO, " REG%.2X: %.2X\n", i, data);
+ }
+#endif
+
+ return EOS_OK;
+}
+
+int eos_batt_read_fault(uint8_t *fault0, uint8_t *fault1) {
+ int rv;
+
+ rv = bq25895_read_fault(fault0);
+ if (rv) return rv;
+
+ rv = bq25895_read_fault(fault1);
+ if (rv) return rv;
+
+ return EOS_OK;
+} \ No newline at end of file
diff --git a/fw/fe310/eos/dev/batt.h b/fw/fe310/eos/dev/batt.h
new file mode 100644
index 0000000..e761a37
--- /dev/null
+++ b/fw/fe310/eos/dev/batt.h
@@ -0,0 +1,4 @@
+#include <stdint.h>
+
+int eos_batt_init(void);
+int eos_batt_read_fault(uint8_t *fault0, uint8_t *fault1);
diff --git a/fw/fe310/eos/dev/cam.h b/fw/fe310/eos/dev/cam.h
new file mode 100644
index 0000000..b0e1368
--- /dev/null
+++ b/fw/fe310/eos/dev/cam.h
@@ -0,0 +1,20 @@
+#include "cam_def.h"
+#include "drv/ov2640.h"
+#include "drv/arducam.h"
+
+#include "egpio.h"
+#include "egpio_priv.h"
+
+#define eos_cam_init ov2640_init
+#define eos_cam_set_pixfmt ov2640_set_pixfmt
+#define eos_cam_set_framesize ov2640_set_pixfmt
+
+#define eos_cam_capture arducam_capture
+#define eos_cam_capture_done arducam_capture_done
+#define eos_cam_capture_wait arducam_capture_wait
+#define eos_cam_fbuf_size arducam_fbuf_size
+#define eos_cam_fbuf_read arducam_fbuf_read
+#define eos_cam_fbuf_done arducam_fbuf_done
+
+#define eos_cam_en() eos_egpio_set_val(EGPIO_PIN_CAM_EN, 1)
+#define eos_cam_dis() eos_egpio_set_val(EGPIO_PIN_CAM_EN, 0)
diff --git a/fw/fe310/eos/dev/cam_def.h b/fw/fe310/eos/dev/cam_def.h
new file mode 100644
index 0000000..4a44f98
--- /dev/null
+++ b/fw/fe310/eos/dev/cam_def.h
@@ -0,0 +1,65 @@
+typedef enum {
+ CAM_PIXFORMAT_INVALID = 0,
+ CAM_PIXFORMAT_BINARY, // 1BPP/BINARY
+ CAM_PIXFORMAT_GRAYSCALE, // 1BPP/GRAYSCALE
+ CAM_PIXFORMAT_RGB565, // 2BPP/RGB565
+ CAM_PIXFORMAT_YUV422, // 2BPP/YUV422
+ CAM_PIXFORMAT_BAYER, // 1BPP/RAW
+ CAM_PIXFORMAT_JPEG, // JPEG/COMPRESSED
+} cam_pixformat_t;
+
+typedef enum {
+ CAM_FRAMESIZE_INVALID = 0,
+ // C/SIF Resolutions
+ CAM_FRAMESIZE_QQCIF, // 88x72
+ CAM_FRAMESIZE_QCIF, // 176x144
+ CAM_FRAMESIZE_CIF, // 352x288
+ CAM_FRAMESIZE_QQSIF, // 88x60
+ CAM_FRAMESIZE_QSIF, // 176x120
+ CAM_FRAMESIZE_SIF, // 352x240
+ // VGA Resolutions
+ CAM_FRAMESIZE_QQQQVGA, // 40x30
+ CAM_FRAMESIZE_QQQVGA, // 80x60
+ CAM_FRAMESIZE_QQVGA, // 160x120
+ CAM_FRAMESIZE_QVGA, // 320x240
+ CAM_FRAMESIZE_VGA, // 640x480
+ CAM_FRAMESIZE_HQQQVGA, // 60x40
+ CAM_FRAMESIZE_HQQVGA, // 120x80
+ CAM_FRAMESIZE_HQVGA, // 240x160
+ // FFT Resolutions
+ CAM_FRAMESIZE_64X32, // 64x32
+ CAM_FRAMESIZE_64X64, // 64x64
+ CAM_FRAMESIZE_128X64, // 128x64
+ CAM_FRAMESIZE_128X128, // 128x128
+ CAM_FRAMESIZE_320X320, // 320x320
+ // Other
+ CAM_FRAMESIZE_LCD, // 128x160
+ CAM_FRAMESIZE_QQVGA2, // 128x160
+ CAM_FRAMESIZE_WVGA, // 720x480
+ CAM_FRAMESIZE_WVGA2, // 752x480
+ CAM_FRAMESIZE_SVGA, // 800x600
+ CAM_FRAMESIZE_XGA, // 1024x768
+ CAM_FRAMESIZE_SXGA, // 1280x1024
+ CAM_FRAMESIZE_UXGA, // 1600x1200
+ CAM_FRAMESIZE_HD, // 1280x720
+ CAM_FRAMESIZE_FHD, // 1920x1080
+ CAM_FRAMESIZE_QHD, // 2560x1440
+ CAM_FRAMESIZE_QXGA, // 2048x1536
+ CAM_FRAMESIZE_WQXGA, // 2560x1600
+ CAM_FRAMESIZE_WQXGA2, // 2592x1944
+} cam_framesize_t;
+
+typedef enum {
+ CAM_GAINCEILING_2X,
+ CAM_GAINCEILING_4X,
+ CAM_GAINCEILING_8X,
+ CAM_GAINCEILING_16X,
+ CAM_GAINCEILING_32X,
+ CAM_GAINCEILING_64X,
+ CAM_GAINCEILING_128X,
+} cam_gainceiling_t;
+
+typedef enum {
+ CAM_SDE_NORMAL,
+ CAM_SDE_NEGATIVE,
+} cam_sde_t;
diff --git a/fw/fe310/eos/dev/ctp.c b/fw/fe310/eos/dev/ctp.c
index fcc3c68..b6459b4 100644
--- a/fw/fe310/eos/dev/ctp.c
+++ b/fw/fe310/eos/dev/ctp.c
@@ -10,17 +10,13 @@
#include "eve/eve_touch_engine.h"
#include "egpio.h"
+#include "egpio_priv.h"
#include "eve.h"
-#include "pwr.h"
#include "drv/fxl6408.h"
#include "drv/gt911.h"
#include "ctp.h"
-#ifdef EOS_DEBUG
-#include <stdio.h>
-#endif
-
int eos_ctp_init(void) {
uint8_t wakeup_cause;
int rv, rst;
@@ -37,6 +33,7 @@ int eos_ctp_init(void) {
}
int eos_ctp_reset(void) {
+ uint8_t status = 0;
int rv;
if (eos_i2s_running() || !eos_egpio_get_val(EGPIO_PIN_DISP_SEL) || !eos_egpio_get_val(EGPIO_PIN_CTP_SEL)) return EOS_ERR_BUSY;
@@ -56,6 +53,7 @@ int eos_ctp_sleep(void) {
int rv;
if (eos_i2s_running() || !eos_egpio_get_val(EGPIO_PIN_DISP_SEL) || !eos_egpio_get_val(EGPIO_PIN_CTP_SEL)) return EOS_ERR_BUSY;
+ if (!gt911_running()) return EOS_ERR;
rv = eos_egpio_intr_disable();
if (rv) return rv;
@@ -73,6 +71,7 @@ int eos_ctp_wake(void) {
int rv;
if (eos_i2s_running() || !eos_egpio_get_val(EGPIO_PIN_DISP_SEL) || !eos_egpio_get_val(EGPIO_PIN_CTP_SEL)) return EOS_ERR_BUSY;
+ if (gt911_running()) return EOS_ERR;
rv = eos_egpio_fxl_set_pin(EGPIO_PIN_CTP_INT, FXL6408_REG_PULL_DIR, 1);
if (rv) return rv;
@@ -94,10 +93,10 @@ int eos_ctp_give(void) {
rv = eos_egpio_intr_disable();
if (rv) return rv;
- rv = eve_select();
+ rv = eos_egpio_set_val(EGPIO_PIN_CTP_SEL, 0);
if (rv) return rv;
- rv = eos_egpio_set_val(EGPIO_PIN_CTP_SEL, 0);
+ rv = eve_select();
if (rv) return rv;
eve_touch_set_engine(EVE_TOUCH_ENGINE_GOODIX);
@@ -138,7 +137,6 @@ int eos_ctp_take(void) {
int eos_ctp_handle_intr(void) {
uint8_t status;
uint8_t points[GT911_SIZE_PBUF * GT911_MAX_POINTS];
- static int clear_tag0 = 0;
int i, num_points;
int rv;
uint32_t start;
@@ -150,11 +148,11 @@ int eos_ctp_handle_intr(void) {
num_points = status & 0xf;
if (num_points > 5) {
rv = EOS_ERR;
- goto handle_intr_fin;
+ goto handle_intr_fin1;
}
rv = eve_select();
- if (rv) goto handle_intr_fin;
+ if (rv) goto handle_intr_fin1;
start = eos_get_tick();
while (!eve_touch_ehost_ready()) {
@@ -163,20 +161,14 @@ int eos_ctp_handle_intr(void) {
if (eos_tdelta_ms(start) > EVE_CMD_EXEC_TO) {
rv = EOS_ERR_TIMEOUT;
- eve_deselect();
- goto handle_intr_fin;
+ goto handle_intr_fin0;
}
if (num_points) {
- if (clear_tag0) {
- eve_touch_clear_tag0();
- clear_tag0 = 0;
- }
rv = gt911_get_points(num_points, points);
if (rv) {
rv = EOS_ERR;
- eve_deselect();
- goto handle_intr_fin;
+ goto handle_intr_fin0;
}
for (i=0; i<num_points; i++) {
@@ -193,20 +185,14 @@ int eos_ctp_handle_intr(void) {
}
} else {
eve_touch_ehost_enter(0, 0x8000, 0x8000);
- clear_tag0 = 1;
}
eve_touch_ehost_end();
+handle_intr_fin0:
eve_deselect();
-
-handle_intr_fin:
+handle_intr_fin1:
gt911_set_status(0);
- if (rv) {
-#ifdef EOS_DEBUG
- printf("CTP HANDLE INTR ERR:%d\n", rv);
-#endif
- return rv;
- }
+ if (rv) return rv;
- return 1;
+ return status;
}
diff --git a/fw/fe310/eos/dev/drv/arducam.c b/fw/fe310/eos/dev/drv/arducam.c
index a50830a..8ac3823 100644
--- a/fw/fe310/eos/dev/drv/arducam.c
+++ b/fw/fe310/eos/dev/drv/arducam.c
@@ -36,21 +36,21 @@
#define ARDUCAM_VAL_GPIO_PWREN 0x04
static uint8_t reg_read(uint8_t addr) {
- uint8_t ret;
+ uint8_t rv;
- drv_spi_cs_set();
+ drv_spi_set_cs();
drv_spi_xchg8(addr, 0);
- ret = drv_spi_xchg8(0, 0);
- drv_spi_cs_clear();
+ rv = drv_spi_xchg8(0, 0);
+ drv_spi_clear_cs();
- return ret;
+ return rv;
}
static void reg_write(uint8_t addr, uint8_t val) {
- drv_spi_cs_set();
+ drv_spi_set_cs();
drv_spi_xchg8(addr | 0x80, 0);
drv_spi_xchg8(val, 0);
- drv_spi_cs_clear();
+ drv_spi_clear_cs();
}
void arducam_capture(void) {
@@ -70,25 +70,25 @@ void arducam_capture_wait(void) {
}
uint32_t arducam_fbuf_size(void) {
- uint32_t ret;
+ uint32_t rv;
- ret = reg_read(ARDUCAM_REG_FIFO_SIZE1);
- ret |= reg_read(ARDUCAM_REG_FIFO_SIZE2) << 8;
- ret |= (reg_read(ARDUCAM_REG_FIFO_SIZE3) & 0x7f) << 16;
- return ret;
+ rv = reg_read(ARDUCAM_REG_FIFO_SIZE1);
+ rv |= reg_read(ARDUCAM_REG_FIFO_SIZE2) << 8;
+ rv |= (reg_read(ARDUCAM_REG_FIFO_SIZE3) & 0x7f) << 16;
+ return rv;
}
void arducam_fbuf_read(uint8_t *buffer, uint16_t sz, int first) {
int i;
- drv_spi_cs_set();
+ drv_spi_set_cs();
drv_spi_xchg8(ARDUCAM_REG_READ_BURST, 0);
if (first) drv_spi_xchg8(0, 0);
for (i=0; i<sz; i++) {
buffer[i] = drv_spi_xchg8(0, 0);
}
- drv_spi_cs_clear();
+ drv_spi_clear_cs();
}
void arducam_fbuf_done(void) {
diff --git a/fw/fe310/eos/dev/drv/gt911.c b/fw/fe310/eos/dev/drv/gt911.c
index cd71d9a..8eb4358 100644
--- a/fw/fe310/eos/dev/drv/gt911.c
+++ b/fw/fe310/eos/dev/drv/gt911.c
@@ -124,6 +124,10 @@ void gt911_wake(void) {
drv_gpio_set(GPIO_INPUT_EN, GT911_PIN_INT);
}
+int gt911_running(void) {
+ return drv_gpio_get(GPIO_INPUT_EN, GT911_PIN_INT);
+}
+
int gt911_cfg_read(uint8_t *cfg_buf) {
int rv;
@@ -148,20 +152,20 @@ int gt911_cfg_print(void) {
rv = gt911_cfg_read(cfg_buf);
if (rv) return rv;
- printf("GT911 CFG:\n");
+ DRV_LOG(DRV_LOG_INFO, "GT911 CFG:\n");
for (i=0; i<GT911_SIZE_CFG-2; i++) {
- printf("%.2X", cfg_buf[i]);
+ DRV_LOG(DRV_LOG_INFO, "%.2X", cfg_buf[i]);
if (i % 8 == 7) {
- printf("\n");
+ DRV_LOG(DRV_LOG_INFO, "\n");
} else {
- printf(" ");
+ DRV_LOG(DRV_LOG_INFO, " ");
}
}
rv = gt911_fw_ver(cfg_buf);
if (rv) return rv;
- printf("GT911 FW VER:%.2X%.2X\n", cfg_buf[1], cfg_buf[0]);
+ DRV_LOG(DRV_LOG_INFO, "GT911 FW VER:%.2X%.2X\n", cfg_buf[1], cfg_buf[0]);
return DRV_OK;
}
diff --git a/fw/fe310/eos/dev/drv/gt911.h b/fw/fe310/eos/dev/drv/gt911.h
index 9db6981..61a6593 100644
--- a/fw/fe310/eos/dev/drv/gt911.h
+++ b/fw/fe310/eos/dev/drv/gt911.h
@@ -10,6 +10,7 @@
void gt911_reset(void);
int gt911_sleep(void);
void gt911_wake(void);
+int gt911_running(void);
int gt911_cfg_read(uint8_t *cfg_buf);
int gt911_cfg_write(uint8_t *cfg_buf);
diff --git a/fw/fe310/eos/dev/drv/ili9806e.c b/fw/fe310/eos/dev/drv/ili9806e.c
index 45aabb7..b57a14c 100644
--- a/fw/fe310/eos/dev/drv/ili9806e.c
+++ b/fw/fe310/eos/dev/drv/ili9806e.c
@@ -5,15 +5,11 @@
#include "platform.h"
#include "ili9806e.h"
-#ifdef DRV_DEBUG
-#include <stdio.h>
-#endif
-
int ili9806e_init(void) {
int rv;
uint8_t chip_id[3];
- drv_spi_cs_set();
+ drv_spi_set_cs();
/* LCD Setting */
drv_spi9bit_write(0, 0xFF); // change to Page 1 CMD
@@ -38,15 +34,13 @@ int ili9806e_init(void) {
drv_spi9bit_write(0, 0x02);
drv_spi9bit_read(&chip_id[2]);
-#ifdef DRV_DEBUG
- printf("LCD CHIP ID: %.2x%.2x%.2x\n", chip_id[0], chip_id[1], chip_id[2]);
-#endif
+ DRV_LOG(DRV_LOG_INFO, "LCD CHIP ID: %.2x%.2x%.2x\n", chip_id[0], chip_id[1], chip_id[2]);
drv_spi9bit_write(0, 0xFE); // disable read
drv_spi9bit_write(1, 0x00);
if (memcmp(chip_id, "\x98\x06\x04", sizeof(chip_id))) {
- drv_spi_cs_clear();
+ drv_spi_clear_cs();
return DRV_ERR_NOTFOUND;
}
@@ -404,28 +398,28 @@ int ili9806e_init(void) {
drv_spi9bit_write(0, 0x29);
drv_sleep(25);
- drv_spi_cs_clear();
+ drv_spi_clear_cs();
return DRV_OK;
}
void ili9806e_sleep(void) {
- drv_spi_cs_set();
+ drv_spi_set_cs();
drv_spi9bit_write(0, 0x28);
drv_sleep(10);
drv_spi9bit_write(0, 0x10);
- drv_spi_cs_clear();
+ drv_spi_clear_cs();
}
void ili9806e_wake(void) {
- drv_spi_cs_set();
+ drv_spi_set_cs();
drv_spi9bit_write(0, 0x11);
drv_sleep(120);
drv_spi9bit_write(0, 0x29);
- drv_spi_cs_clear();
+ drv_spi_clear_cs();
}
diff --git a/fw/fe310/eos/dev/drv/pcm1770.c b/fw/fe310/eos/dev/drv/pcm1770.c
index c617ae9..eec7bd0 100644
--- a/fw/fe310/eos/dev/drv/pcm1770.c
+++ b/fw/fe310/eos/dev/drv/pcm1770.c
@@ -5,8 +5,8 @@
#include "pcm1770.h"
void pcm1770_reg_write(uint8_t addr, uint8_t val) {
- drv_spi_cs_set();
+ drv_spi_set_cs();
drv_spi_xchg8(addr, 0);
drv_spi_xchg8(val, 0);
- drv_spi_cs_clear();
+ drv_spi_clear_cs();
}
diff --git a/fw/fe310/eos/dev/drv/platform.h b/fw/fe310/eos/dev/drv/platform.h
index d1f7248..a2405d5 100644
--- a/fw/fe310/eos/dev/drv/platform.h
+++ b/fw/fe310/eos/dev/drv/platform.h
@@ -1,6 +1,7 @@
#include "board.h"
#include "eos.h"
+#include "log.h"
#include "soc/timer.h"
#include "soc/i2c.h"
#include "soc/spi.h"
@@ -16,17 +17,18 @@
#define DRV_ERR EOS_ERR
#define DRV_ERR_NOTFOUND EOS_ERR_NOTFOUND
-/* should define theese for non-EOS platforms:
-#define GPIO_INPUT_EN
-#define GPIO_OUTPUT_EN
-#define GPIO_OUTPUT_VAL
-*/
+#define DRV_LOG_DEBUG EOS_LOG_DEBUG
+#define DRV_LOG_INFO EOS_LOG_INFO
+#define DRV_LOG_ERR EOS_LOG_ERR
+#define DRV_LOG_NONE EOS_LOG_NONE
+#define DRV_LOG_LEVEL EOS_LOG_LEVEL
+#define DRV_LOG(l, ...) EOS_LOG(l, __VA_ARGS__)
#define GT911_PIN_INT CTP_PIN_INT
#define GT911_PIN_RST CTP_PIN_RST
-#define drv_spi_cs_set eos_spi_cs_set
-#define drv_spi_cs_clear eos_spi_cs_clear
+#define drv_spi_set_cs eos_spi_set_cs
+#define drv_spi_clear_cs eos_spi_clear_cs
#define drv_spi_xchg8 eos_spi_xchg8
#define drv_spi9bit_read eos_spi9bit_read
#define drv_spi9bit_write eos_spi9bit_write
@@ -38,5 +40,12 @@
#define drv_sleep eos_sleep
+/* should define theese for non-EOS platforms:
+#define GPIO_INPUT_EN
+#define GPIO_OUTPUT_EN
+#define GPIO_OUTPUT_VAL
+*/
+
+#define drv_gpio_get eos_gpio_get
#define drv_gpio_set eos_gpio_set
#define drv_gpio_clear eos_gpio_clear
diff --git a/fw/fe310/eos/dev/drv/sdc_platform.h b/fw/fe310/eos/dev/drv/sdc_platform.h
index 5d562c2..daf2670 100644
--- a/fw/fe310/eos/dev/drv/sdc_platform.h
+++ b/fw/fe310/eos/dev/drv/sdc_platform.h
@@ -1,19 +1,31 @@
/* included from sdcard.h - needs relative includes */
#include "../../eos.h"
+#include "../../log.h"
#include "../../soc/timer.h"
#include "../../soc/spi.h"
#include "../sdc_crypto.h"
+#ifdef EOS_DEBUG
+#define SDC_DEBUG
+#endif
+
#define SDC_OK EOS_OK
#define SDC_ERR EOS_ERR
#define SDC_ERR_BUSY EOS_ERR_BUSY
+#define SDC_LOG_DEBUG EOS_LOG_DEBUG
+#define SDC_LOG_INFO EOS_LOG_INFO
+#define SDC_LOG_ERR EOS_LOG_ERR
+#define SDC_LOG_NONE EOS_LOG_NONE
+#define SDC_LOG_LEVEL EOS_LOG_LEVEL
+#define SDC_LOG(l, ...) EOS_LOG(l, __VA_ARGS__)
+
#define sdc_spi_xchg8 eos_spi_xchg8
#define sdc_spi_xchg16 eos_spi_xchg16
#define sdc_spi_xchg32 eos_spi_xchg32
-#define sdc_spi_cs_set eos_spi_cs_set
-#define sdc_spi_cs_clear eos_spi_cs_clear
+#define sdc_spi_set_cs eos_spi_set_cs
+#define sdc_spi_clear_cs eos_spi_clear_cs
#define sdc_sleep eos_sleep
#define sdc_get_tick eos_get_tick
#define sdc_tdelta_ms eos_tdelta_ms
diff --git a/fw/fe310/eos/dev/drv/sdcard.c b/fw/fe310/eos/dev/drv/sdcard.c
index 96b01ae..7d21b3d 100644
--- a/fw/fe310/eos/dev/drv/sdcard.c
+++ b/fw/fe310/eos/dev/drv/sdcard.c
@@ -126,18 +126,18 @@ static void sdc_buf_recv(unsigned char *buffer, uint16_t len) {
}
static void sdc_select(void) {
- sdc_spi_cs_set();
+ sdc_spi_set_cs();
sdc_spi_xchg8(0xff, 0);
}
static void sdc_deselect(void) {
- sdc_spi_cs_clear();
+ sdc_spi_clear_cs();
sdc_spi_xchg8(0xff, 0);
}
static int sdc_xchg_cmd(uint8_t cmd, uint32_t arg, uint8_t flags) {
int i;
- uint8_t ret;
+ uint8_t rv;
uint8_t crc = 0x7f;
cmd |= 0x40;
@@ -156,11 +156,11 @@ static int sdc_xchg_cmd(uint8_t cmd, uint32_t arg, uint8_t flags) {
i = SDC_NCR;
do {
- ret = sdc_xchg8(0xff);
- } while ((ret & 0x80) && --i);
- if (ret & 0x80) return SDC_ERR_BUSY;
+ rv = sdc_xchg8(0xff);
+ } while ((rv & 0x80) && --i);
+ if (rv & 0x80) return SDC_ERR_BUSY;
- return ret;
+ return rv;
}
static int sdc_ready(uint32_t timeout) {
@@ -256,11 +256,12 @@ int sdc_init(uint32_t timeout) {
uint32_t start;
start = sdc_get_tick();
- sdc_sleep(5);
- for (i=10; i--;) sdc_xchg8(0xff); /* 80 dummy cycles */
+ do {
+ if (sdc_tdelta_ms(start) > timeout) return SDC_ERR_BUSY;
+ for (i=10; i--;) sdc_xchg8(0xff); /* 80 dummy cycles */
- rv = sdc_cmd(GO_IDLE_STATE, 0, SDC_CMD_FLAG_CRC, SDC_TIMEOUT_CMD);
- if (rv != SDC_R1_IDLE_STATE) return SDC_RV2ERR(rv);
+ rv = sdc_cmd(GO_IDLE_STATE, 0, SDC_CMD_FLAG_CRC, SDC_TIMEOUT_CMD);
+ } while (rv != SDC_R1_IDLE_STATE);
sdc_select();
rv = sdc_cmd(SEND_IF_COND, 0x1aa, SDC_CMD_FLAG_CRC | SDC_CMD_FLAG_NOCS, sdc_nto(start, timeout));
@@ -341,11 +342,11 @@ int sdc_init(uint32_t timeout) {
if (rv) return rv;
#ifdef SDC_DEBUG
- printf("SDCARD CSD: ");
+ SDC_LOG(SDC_LOG_INFO, "SDCARD CSD: ");
for (i=0; i<16; i++) {
- printf("%.2x ", csd[i]);
+ SDC_LOG(SDC_LOG_INFO, "%.2x ", csd[i]);
}
- printf("\n");
+ SDC_LOG(SDC_LOG_INFO, "\n");
#endif
if (csd[10] & 0x40) _type |= SDC_CAP_ERASE_EN;
}
@@ -366,7 +367,7 @@ void sdc_clear(void) {
sdc_type = SDC_TYPE_NONE;
}
-int sdc_get_sect_count(uint32_t timeout, uint32_t *sectors) {
+int sdc_get_sect_count(uint32_t *sectors, uint32_t timeout) {
int rv;
uint8_t csd[16];
uint32_t start;
@@ -393,7 +394,7 @@ int sdc_get_sect_count(uint32_t timeout, uint32_t *sectors) {
return SDC_OK;
}
-int sdc_get_blk_size(uint32_t timeout, uint32_t *size) {
+int sdc_get_blk_size(uint32_t *size, uint32_t timeout) {
int rv;
uint8_t rbl[64]; /* SD Status or CSD register */
uint32_t start;
diff --git a/fw/fe310/eos/dev/drv/sdcard.h b/fw/fe310/eos/dev/drv/sdcard.h
index 39891bb..b4da896 100644
--- a/fw/fe310/eos/dev/drv/sdcard.h
+++ b/fw/fe310/eos/dev/drv/sdcard.h
@@ -20,8 +20,8 @@ uint8_t sdc_get_type(void);
uint8_t sdc_get_cap(void);
void sdc_clear(void);
-int sdc_get_sect_count(uint32_t timeout, uint32_t *sectors);
-int sdc_get_blk_size(uint32_t timeout, uint32_t *size);
+int sdc_get_sect_count(uint32_t *sectors, uint32_t timeout);
+int sdc_get_blk_size(uint32_t *size, uint32_t timeout);
int sdc_sync(uint32_t timeout);
int sdc_erase(uint32_t blk_start, uint32_t blk_end, uint32_t timeout);
int sdc_sect_read(uint32_t sect, unsigned int count, uint8_t *buffer);
diff --git a/fw/fe310/eos/dev/egpio.c b/fw/fe310/eos/dev/egpio.c
index 7358082..cfcd0f3 100644
--- a/fw/fe310/eos/dev/egpio.c
+++ b/fw/fe310/eos/dev/egpio.c
@@ -6,6 +6,8 @@
#include "board.h"
#include "eos.h"
+#include "log.h"
+
#include "event.h"
#include "soc/interrupt.h"
@@ -18,24 +20,31 @@
#include "sdcard.h"
#include "ctp.h"
#include "eve.h"
+
#include "app.h"
#include "drv/fxl6408.h"
#include "egpio.h"
+#include "egpio_priv.h"
/* FXL chip only */
-static const uint8_t egpio_switch[2] = {
- EGPIO_BIT_SDCARD_DET | EGPIO_BIT_BTN_WAKE,
+static const uint8_t egpio_switch[EGPIO_MAX_FXL_CHIP] = {
+ EGPIO_BIT_SDCARD_NDET | EGPIO_BIT_BTN_WAKE,
EGPIO_BIT_MIC_MUTE | EGPIO_BIT_HP_NDET,
};
static uint8_t egpio_pinval[EGPIO_MAX_CHIP];
+static uint8_t egpio_intmask[EGPIO_MAX_FXL_CHIP];
static uint8_t egpio_alt_pin;
static uint32_t wake_start;
static eos_egpio_intr_handler_t egpio_intr_handler;
static eos_egpio_ext_handler_t egpio_ext_handler;
+static int egpio_fxl_set_mask(uint8_t chip_id, uint8_t mask);
+static int egpio_set_val(uint8_t pin, int val);
+static int egpio_get_val(uint8_t pin);
+
#define EGPIO_ALT_EVEAUDIO_DIS 0x01
#define EGPIO_ALT_LSGAIN_SEL 0x02
#define EGPIO_ALT_AUDIO_SEL 0x04
@@ -43,8 +52,8 @@ static eos_egpio_ext_handler_t egpio_ext_handler;
#define BITSET(var, bit, val) { var = (val) ? (var | (bit)) : (var & ~(bit)); }
#define PINSWITCH(STPIN, SETPIN) { \
int rv; \
- BITSET(egpio_alt_pin, pin2alt_bit(STPIN), _eos_egpio_get_val(STPIN)); \
- rv = _eos_egpio_set_val(SETPIN, !!(egpio_alt_pin & pin2alt_bit(SETPIN))); \
+ BITSET(egpio_alt_pin, pin2alt_bit(STPIN), egpio_get_val(STPIN)); \
+ rv = egpio_set_val(SETPIN, !!(egpio_alt_pin & pin2alt_bit(SETPIN))); \
if (rv) return rv; \
}
@@ -65,20 +74,22 @@ static int handle_egpio_intr(uint8_t chip_id, uint8_t intr) {
int rv;
switch (chip_id) {
- case 0: {
+ case EGPIO_CHIP_FXL0: {
if (intr & EGPIO_BIT_BAT_INT) {
uint8_t fault0, fault1;
rv = eos_batt_read_fault(&fault0, &fault1);
if (rv) return rv;
- if (egpio_intr_handler) egpio_intr_handler(EGPIO_INT_TYPE_BAT, fault1, fault0);
+ if (egpio_intr_handler) egpio_intr_handler(EOS_EGPIO_INT_TYPE_BAT, fault1, fault0);
}
if (intr & EGPIO_BIT_CTP_INT) {
- eos_ctp_handle_intr();
+ rv = eos_ctp_handle_intr();
+ if (rv < 0) return rv;
}
if (intr & EGPIO_BIT_EVE_INT) {
- eos_eve_handle_intr();
+ rv = eos_eve_handle_intr();
+ if (rv < 0) return rv;
}
if (intr & EGPIO_BIT_BTN_WAKE) {
int btn_wake, tdelta;
@@ -89,27 +100,29 @@ static int handle_egpio_intr(uint8_t chip_id, uint8_t intr) {
} else {
tdelta = eos_tdelta_ms(wake_start);
}
- if (egpio_intr_handler) egpio_intr_handler(EGPIO_INT_TYPE_WAKE, btn_wake, btn_wake ? tdelta : 0);
+ if (egpio_intr_handler) egpio_intr_handler(EOS_EGPIO_INT_TYPE_WAKE, btn_wake, btn_wake ? tdelta : 0);
}
- if (intr & EGPIO_BIT_SDCARD_DET) {
- int sdc_det = eos_egpio_get_val(EGPIO_PIN_SDCARD_DET);
+ if (intr & EGPIO_BIT_SDCARD_NDET) {
+ int sdc_det;
- eos_sdc_insert(sdc_det);
- if (egpio_intr_handler) egpio_intr_handler(EGPIO_INT_TYPE_SDCARD, sdc_det, 0);
+ sdc_det = !eos_egpio_get_val(EGPIO_PIN_SDCARD_NDET);
+ rv = eos_sdc_insert(sdc_det, 0);
+ if (rv) EOS_LOG(EOS_LOG_ERR, "SDC INSERT ERR:%d\n", rv);
+ if (egpio_intr_handler) egpio_intr_handler(EOS_EGPIO_INT_TYPE_SDCARD, sdc_det, rv);
}
break;
}
- case 1: {
+ case EGPIO_CHIP_FXL1: {
if (intr & EGPIO_BIT_MIC_MUTE) {
- if (egpio_intr_handler) egpio_intr_handler(EGPIO_INT_TYPE_MUTE, eos_egpio_get_val(EGPIO_PIN_MIC_MUTE), 0);
+ if (egpio_intr_handler) egpio_intr_handler(EOS_EGPIO_INT_TYPE_MUTE, eos_egpio_get_val(EGPIO_PIN_MIC_MUTE), 0);
}
if (intr & EGPIO_BIT_HP_NDET) {
int hp_det, i2s_running, app_audio;
hp_det = !eos_egpio_get_val(EGPIO_PIN_HP_NDET);
i2s_running = eos_i2s_running();
- app_audio = !_eos_egpio_get_val(EGPIO_PIN_AUDIO_SEL);
+ app_audio = !egpio_get_val(EGPIO_PIN_AUDIO_SEL);
if (i2s_running || app_audio) {
if (i2s_running) {
eos_i2s_hp_change(hp_det);
@@ -125,7 +138,7 @@ static int handle_egpio_intr(uint8_t chip_id, uint8_t intr) {
PINSWITCH(EGPIO_PIN_EVEAUDIO_DIS, EGPIO_PIN_LSGAIN_SEL);
}
}
- if (egpio_intr_handler) egpio_intr_handler(EGPIO_INT_TYPE_HP, hp_det, 0);
+ if (egpio_intr_handler) egpio_intr_handler(EOS_EGPIO_INT_TYPE_HP, hp_det, 0);
}
break;
}
@@ -135,14 +148,18 @@ static int handle_egpio_intr(uint8_t chip_id, uint8_t intr) {
}
static int handle_egpio_evt(uint8_t chip_id) {
- uint8_t intr_reg, def_reg;
+ uint8_t intr_reg, mask_reg;
int rv;
rv = fxl6408_reg_read(chip_id, FXL6408_REG_INT_STATE, &intr_reg);
- if (rv) return rv;;
- if (!intr_reg) return 0;
+ if (rv) return rv;
+
+ intr_reg &= ~egpio_intmask[chip_id];
+ if (!intr_reg) return EOS_OK;
if (intr_reg & egpio_switch[chip_id]) {
+ uint8_t def_reg;
+
rv = fxl6408_reg_read(chip_id, FXL6408_REG_I_DEFAULT, &def_reg);
if (rv) return rv;
@@ -157,47 +174,47 @@ static int handle_egpio_evt(uint8_t chip_id) {
rv = handle_egpio_intr(chip_id, intr_reg);
if (rv) return rv;
- return 1;
+ return EOS_OK;
}
static void handle_evt(unsigned char type, unsigned char *buffer, uint16_t len) {
+ int rv;
+
type &= ~EOS_EVT_MASK;
switch (type) {
- case EGPIO_ETYPE_INT: {
- int rv;
-
- rv = handle_egpio_evt(0);
- if (rv < 0) goto handle_evt_fin;
+ case EOS_EGPIO_ETYPE_INT: {
+ rv = handle_egpio_evt(EGPIO_CHIP_FXL0);
+ if (rv) goto handle_evt_fin;
if (GPIO_REG(GPIO_INPUT_VAL) & (1 << EGPIO_PIN_INT)) goto handle_evt_fin;
- rv = handle_egpio_evt(1);
- if (rv < 0) goto handle_evt_fin;
+ rv = handle_egpio_evt(EGPIO_CHIP_FXL1);
+ if (rv) goto handle_evt_fin;
if (GPIO_REG(GPIO_INPUT_VAL) & (1 << EGPIO_PIN_INT)) goto handle_evt_fin;
if (egpio_ext_handler) rv = egpio_ext_handler();
handle_evt_fin:
- clear_csr(mstatus, MSTATUS_MIE);
GPIO_REG(GPIO_LOW_IP) = (1 << EGPIO_PIN_INT);
+ clear_csr(mstatus, MSTATUS_MIE);
GPIO_REG(GPIO_LOW_IE) |= (1 << EGPIO_PIN_INT);
set_csr(mstatus, MSTATUS_MIE);
+ if (rv) EOS_LOG(EOS_LOG_ERR, "EGPIO HANDLE INTR ERR:%d\n", rv);
break;
}
- case EGPIO_ETYPE_INT_CTP:
- case EGPIO_ETYPE_INT_EVE: {
+ case EOS_EGPIO_ETYPE_INT_CTP: {
if (eos_egpio_get_val(EGPIO_PIN_CTP_SEL)) {
- eos_ctp_handle_intr();
+ rv = eos_ctp_handle_intr();
} else {
- eos_eve_handle_intr();
+ rv = eos_eve_handle_intr();
}
-handle_evt_eve_fin:
+ GPIO_REG(GPIO_LOW_IP) = (1 << CTP_PIN_INT);
clear_csr(mstatus, MSTATUS_MIE);
- GPIO_REG(GPIO_LOW_IP) = (1 << EVE_PIN_INT);
- GPIO_REG(GPIO_LOW_IE) |= (1 << EVE_PIN_INT);
+ GPIO_REG(GPIO_LOW_IE) |= (1 << CTP_PIN_INT);
set_csr(mstatus, MSTATUS_MIE);
+ if (rv < 0) EOS_LOG(EOS_LOG_ERR, "CTP/EVE HANDLE INTR ERR:%d\n", rv);
break;
}
}
@@ -205,16 +222,12 @@ handle_evt_eve_fin:
static void handle_intr(void) {
GPIO_REG(GPIO_LOW_IE) &= ~(1 << EGPIO_PIN_INT);
- eos_evtq_push_isr(EOS_EVT_EGPIO | EGPIO_ETYPE_INT, NULL, 0);
+ eos_evtq_push_isr(EOS_EVT_EGPIO | EOS_EGPIO_ETYPE_INT, NULL, 0);
}
-static void handle_intr_eve(void) {
- GPIO_REG(GPIO_LOW_IE) &= ~(1 << EVE_PIN_INT);
- if (egpio_pinval[EGPIO_CHIP_FXL0] & EGPIO_PIN2BIT(EGPIO0_PIN_CTP_SEL)) {
- eos_evtq_push_isr(EOS_EVT_EGPIO | EGPIO_ETYPE_INT_CTP, NULL, 0);
- } else {
- eos_evtq_push_isr(EOS_EVT_EGPIO | EGPIO_ETYPE_INT_EVE, NULL, 0);
- }
+static void handle_intr_ctp(void) {
+ GPIO_REG(GPIO_LOW_IE) &= ~(1 << CTP_PIN_INT);
+ eos_evtq_push_isr(EOS_EVT_EGPIO | EOS_EGPIO_ETYPE_INT_CTP, NULL, 0);
}
int eos_egpio_init(void) {
@@ -224,83 +237,98 @@ int eos_egpio_init(void) {
wakeup_cause = eos_pwr_wakeup_cause();
rst = (wakeup_cause == EOS_PWR_WAKE_RST);
if (rst) {
- rv = fxl6408_reg_read(0, FXL6408_REG_ID_CTRL, &data);
+ rv = fxl6408_reg_read(EGPIO_CHIP_FXL0, FXL6408_REG_ID_CTRL, &data);
+ if (rv) return rv;
+ rv = fxl6408_reg_read(EGPIO_CHIP_FXL1, FXL6408_REG_ID_CTRL, &data);
if (rv) return rv;
- rv = fxl6408_reg_read(1, FXL6408_REG_ID_CTRL, &data);
+
+ rv = egpio_fxl_set_mask(EGPIO_CHIP_FXL0, 0xff);
+ if (rv) return rv;
+ rv = egpio_fxl_set_mask(EGPIO_CHIP_FXL1, 0xff);
if (rv) return rv;
- rv = fxl6408_reg_write(0, FXL6408_REG_INT_MASK, 0xff);
+ /* clear interrupts */
+ rv = fxl6408_reg_read(EGPIO_CHIP_FXL0, FXL6408_REG_INT_STATE, &data);
if (rv) return rv;
- rv = fxl6408_reg_write(1, FXL6408_REG_INT_MASK, 0xff);
+ rv = fxl6408_reg_read(EGPIO_CHIP_FXL1, FXL6408_REG_INT_STATE, &data);
if (rv) return rv;
/* 1st chip */
data = EGPIO_BIT_CTP_SEL | EGPIO_BIT_EXP_IO0 | EGPIO_BIT_EXP_IO1;
- rv = fxl6408_reg_write(0, FXL6408_REG_IO_DIR, data);
+ rv = fxl6408_reg_write(EGPIO_CHIP_FXL0, FXL6408_REG_IO_DIR, data);
if (rv) return rv;
data = EGPIO_BIT_CTP_SEL;
- rv = fxl6408_reg_write(0, FXL6408_REG_O_STATE, data);
+ rv = fxl6408_reg_write(EGPIO_CHIP_FXL0, FXL6408_REG_O_STATE, data);
if (rv) return rv;
data = EGPIO_BIT_EXP_IO0 | EGPIO_BIT_EXP_IO1;
- rv = fxl6408_reg_write(0, FXL6408_REG_O_HIZ, data);
+ rv = fxl6408_reg_write(EGPIO_CHIP_FXL0, FXL6408_REG_O_HIZ, data);
if (rv) return rv;
- data = EGPIO_BIT_EVE_INT | EGPIO_BIT_SDCARD_DET | EGPIO_BIT_BTN_WAKE | EGPIO_BIT_BAT_INT | EGPIO_BIT_CTP_INT;
- rv = fxl6408_reg_write(0, FXL6408_REG_PULL_ENA, data);
+ data = EGPIO_BIT_EVE_INT | EGPIO_BIT_SDCARD_NDET | EGPIO_BIT_BTN_WAKE | EGPIO_BIT_BAT_INT | EGPIO_BIT_CTP_INT;
+ rv = fxl6408_reg_write(EGPIO_CHIP_FXL0, FXL6408_REG_PULL_ENA, data);
if (rv) return rv;
- data = EGPIO_BIT_EVE_INT | EGPIO_BIT_SDCARD_DET | EGPIO_BIT_BTN_WAKE | EGPIO_BIT_BAT_INT | EGPIO_BIT_CTP_INT;
- rv = fxl6408_reg_write(0, FXL6408_REG_PULL_DIR, data);
+ data = EGPIO_BIT_EVE_INT | EGPIO_BIT_SDCARD_NDET | EGPIO_BIT_BTN_WAKE | EGPIO_BIT_BAT_INT | EGPIO_BIT_CTP_INT;
+ rv = fxl6408_reg_write(EGPIO_CHIP_FXL0, FXL6408_REG_PULL_DIR, data);
if (rv) return rv;
/* 2nd chip */
data = EGPIO_BIT_HPAMP_CS | EGPIO_BIT_AUDIO_SEL | EGPIO_BIT_USR0 | EGPIO_BIT_USR1 | EGPIO_BIT_USR2 | EGPIO_BIT_USR3;
- rv = fxl6408_reg_write(1, FXL6408_REG_IO_DIR, data);
+ rv = fxl6408_reg_write(EGPIO_CHIP_FXL1, FXL6408_REG_IO_DIR, data);
if (rv) return rv;
data = EGPIO_BIT_HPAMP_CS | EGPIO_BIT_AUDIO_SEL;
- rv = fxl6408_reg_write(1, FXL6408_REG_O_STATE, data);
+ rv = fxl6408_reg_write(EGPIO_CHIP_FXL1, FXL6408_REG_O_STATE, data);
if (rv) return rv;
data = EGPIO_BIT_USR0 | EGPIO_BIT_USR1 | EGPIO_BIT_USR2 | EGPIO_BIT_USR3;
- rv = fxl6408_reg_write(1, FXL6408_REG_O_HIZ, data);
+ rv = fxl6408_reg_write(EGPIO_CHIP_FXL1, FXL6408_REG_O_HIZ, data);
if (rv) return rv;
data = 0;
- rv = fxl6408_reg_write(1, FXL6408_REG_PULL_ENA, data);
+ rv = fxl6408_reg_write(EGPIO_CHIP_FXL1, FXL6408_REG_PULL_ENA, data);
if (rv) return rv;
data = 0;
- rv = fxl6408_reg_write(1, FXL6408_REG_PULL_DIR, data);
+ rv = fxl6408_reg_write(EGPIO_CHIP_FXL1, FXL6408_REG_PULL_DIR, data);
+ if (rv) return rv;
+ } else {
+ /* read interrupt mask */
+ rv = fxl6408_reg_read(EGPIO_CHIP_FXL0, FXL6408_REG_INT_MASK, &data);
+ if (rv) return rv;
+ egpio_intmask[EGPIO_CHIP_FXL0] = data;
+
+ rv = fxl6408_reg_read(EGPIO_CHIP_FXL1, FXL6408_REG_INT_MASK, &data);
if (rv) return rv;
+ egpio_intmask[EGPIO_CHIP_FXL1] = data;
}
- rv = fxl6408_reg_read(0, FXL6408_REG_I_STATE, &data);
+ rv = fxl6408_reg_read(EGPIO_CHIP_FXL0, FXL6408_REG_I_STATE, &data);
if (rv) return rv;
- data &= egpio_switch[0];
+ data &= egpio_switch[EGPIO_CHIP_FXL0];
egpio_pinval[EGPIO_CHIP_FXL0] = data;
data |= EGPIO_BIT_EVE_INT | EGPIO_BIT_BAT_INT | EGPIO_BIT_CTP_INT;
- rv = fxl6408_reg_write(0, FXL6408_REG_I_DEFAULT, data);
+ rv = fxl6408_reg_write(EGPIO_CHIP_FXL0, FXL6408_REG_I_DEFAULT, data);
if (rv) return rv;
- rv = fxl6408_reg_read(0, FXL6408_REG_IO_DIR, &data_dir);
+ rv = fxl6408_reg_read(EGPIO_CHIP_FXL0, FXL6408_REG_IO_DIR, &data_dir);
if (rv) return rv;
- rv = fxl6408_reg_read(0, FXL6408_REG_O_STATE, &data);
+ rv = fxl6408_reg_read(EGPIO_CHIP_FXL0, FXL6408_REG_O_STATE, &data);
if (rv) return rv;
egpio_pinval[EGPIO_CHIP_FXL0] |= (data & data_dir);
- rv = fxl6408_reg_read(1, FXL6408_REG_I_STATE, &data);
+ rv = fxl6408_reg_read(EGPIO_CHIP_FXL1, FXL6408_REG_I_STATE, &data);
if (rv) return rv;
- data &= egpio_switch[1];
+ data &= egpio_switch[EGPIO_CHIP_FXL1];
egpio_pinval[EGPIO_CHIP_FXL1] = data;
- rv = fxl6408_reg_write(1, FXL6408_REG_I_DEFAULT, data);
+ rv = fxl6408_reg_write(EGPIO_CHIP_FXL1, FXL6408_REG_I_DEFAULT, data);
if (rv) return rv;
- rv = fxl6408_reg_read(1, FXL6408_REG_IO_DIR, &data_dir);
+ rv = fxl6408_reg_read(EGPIO_CHIP_FXL1, FXL6408_REG_IO_DIR, &data_dir);
if (rv) return rv;
- rv = fxl6408_reg_read(1, FXL6408_REG_O_STATE, &data);
+ rv = fxl6408_reg_read(EGPIO_CHIP_FXL1, FXL6408_REG_O_STATE, &data);
if (rv) return rv;
egpio_pinval[EGPIO_CHIP_FXL1] |= (data & data_dir);
@@ -313,31 +341,31 @@ int eos_egpio_run(void) {
eos_evtq_set_handler(EOS_EVT_EGPIO, handle_evt);
- GPIO_REG(GPIO_INPUT_EN) |= (1 << EGPIO_PIN_INT);
- clear_csr(mstatus, MSTATUS_MIE);
- GPIO_REG(GPIO_LOW_IE) |= (1 << EGPIO_PIN_INT);
- set_csr(mstatus, MSTATUS_MIE);
- eos_intr_set(INT_GPIO_BASE + EGPIO_PIN_INT, IRQ_PRIORITY_EGPIO, handle_intr);
-
- /* EVE_PIN_INT will be set in intr_set() below */
- eos_intr_set(INT_GPIO_BASE + EVE_PIN_INT, IRQ_PRIORITY_EVE, handle_intr_eve);
-
wakeup_cause = eos_pwr_wakeup_cause();
rst = (wakeup_cause == EOS_PWR_WAKE_RST);
if (rst) {
- /* turn on interrupts when all is configured */
- data = ~(EGPIO_BIT_SDCARD_DET | EGPIO_BIT_BTN_WAKE | EGPIO_BIT_BAT_INT);
- rv = fxl6408_reg_write(0, FXL6408_REG_INT_MASK, data);
+ /* enable interrupts when all is configured */
+ data = ~(EGPIO_BIT_SDCARD_NDET | EGPIO_BIT_BTN_WAKE | EGPIO_BIT_BAT_INT);
+ rv = egpio_fxl_set_mask(EGPIO_CHIP_FXL0, data);
if (rv) return rv;
data = ~(EGPIO_BIT_MIC_MUTE | EGPIO_BIT_HP_NDET);
- rv = fxl6408_reg_write(1, FXL6408_REG_INT_MASK, data);
+ rv = egpio_fxl_set_mask(EGPIO_CHIP_FXL1, data);
if (rv) return rv;
}
rv = eos_egpio_intr_set();
if (rv) return rv;
+ /* CTP_PIN_INT is configured in intr_set() above */
+ eos_intr_set(INT_GPIO_BASE + CTP_PIN_INT, IRQ_PRIORITY_CTP, handle_intr_ctp);
+
+ GPIO_REG(GPIO_INPUT_EN) |= (1 << EGPIO_PIN_INT);
+ clear_csr(mstatus, MSTATUS_MIE);
+ GPIO_REG(GPIO_LOW_IE) |= (1 << EGPIO_PIN_INT);
+ set_csr(mstatus, MSTATUS_MIE);
+ eos_intr_set(INT_GPIO_BASE + EGPIO_PIN_INT, IRQ_PRIORITY_EGPIO, handle_intr);
+
return EOS_OK;
}
@@ -346,33 +374,32 @@ void eos_egpio_eve_set(uint16_t gpio_reg) {
if (gpio_reg & (1 << EVE_GPIO_DISP)) egpio_pinval[EGPIO_CHIP_EVE] |= EGPIO_PIN2BIT(EGPIO_PIN_DISP_SEL);
}
-int _eos_egpio_intr_set(int i2s_running, int app_disp) {
- uint8_t data;
+static int egpio_intr_set(int i2s_running, int app_disp) {
+ uint8_t mask;
int rv;
- rv = fxl6408_reg_read(0, FXL6408_REG_INT_MASK, &data);
- if (rv) return rv;
+ mask = egpio_intmask[EGPIO_CHIP_FXL0];
+ mask |= EGPIO_BIT_EVE_INT | EGPIO_BIT_CTP_INT;
- data &= ~(EGPIO_BIT_EVE_INT | EGPIO_BIT_CTP_INT);
- if (app_disp) {
- data |= (EGPIO_BIT_EVE_INT | EGPIO_BIT_CTP_INT);
- } else if (!i2s_running) {
- if (eos_egpio_get_val(EGPIO_PIN_CTP_SEL)) {
- data |= EGPIO_BIT_CTP_INT;
+ if (!app_disp) {
+ if (i2s_running) {
+ mask &= ~(EGPIO_BIT_EVE_INT | EGPIO_BIT_CTP_INT);
+ } else if (eos_egpio_get_val(EGPIO_PIN_CTP_SEL)) {
+ mask &= ~EGPIO_BIT_EVE_INT;
} else {
- data |= EGPIO_BIT_EVE_INT;
+ mask &= ~EGPIO_BIT_CTP_INT;
}
}
- rv = fxl6408_reg_write(0, FXL6408_REG_INT_MASK, data);
+ rv = egpio_fxl_set_mask(EGPIO_CHIP_FXL0, mask);
if (rv) return rv;
- GPIO_REG(GPIO_INPUT_EN) |= (1 << EVE_PIN_INT);
+ GPIO_REG(GPIO_INPUT_EN) |= (1 << CTP_PIN_INT);
clear_csr(mstatus, MSTATUS_MIE);
if (app_disp || i2s_running) {
- GPIO_REG(GPIO_LOW_IE) &= ~(1 << EVE_PIN_INT);
+ GPIO_REG(GPIO_LOW_IE) &= ~(1 << CTP_PIN_INT);
} else {
- GPIO_REG(GPIO_LOW_IE) |= (1 << EVE_PIN_INT);
+ GPIO_REG(GPIO_LOW_IE) |= (1 << CTP_PIN_INT);
}
set_csr(mstatus, MSTATUS_MIE);
@@ -380,25 +407,23 @@ int _eos_egpio_intr_set(int i2s_running, int app_disp) {
}
int eos_egpio_intr_set(void) {
- return _eos_egpio_intr_set(eos_i2s_running(), !eos_egpio_get_val(EGPIO_PIN_DISP_SEL));
+ return egpio_intr_set(eos_i2s_running(), !eos_egpio_get_val(EGPIO_PIN_DISP_SEL));
}
int eos_egpio_intr_disable(void) {
- uint8_t data;
+ uint8_t mask;
int rv;
- rv = fxl6408_reg_read(0, FXL6408_REG_INT_MASK, &data);
- if (rv) return rv;
-
- data |= (EGPIO_BIT_EVE_INT | EGPIO_BIT_CTP_INT);
+ mask = egpio_intmask[EGPIO_CHIP_FXL0];
+ mask |= (EGPIO_BIT_EVE_INT | EGPIO_BIT_CTP_INT);
- rv = fxl6408_reg_write(0, FXL6408_REG_INT_MASK, data);
+ rv = egpio_fxl_set_mask(EGPIO_CHIP_FXL0, mask);
if (rv) return rv;
clear_csr(mstatus, MSTATUS_MIE);
- GPIO_REG(GPIO_LOW_IE) &= ~(1 << EVE_PIN_INT);
+ GPIO_REG(GPIO_LOW_IE) &= ~(1 << CTP_PIN_INT);
set_csr(mstatus, MSTATUS_MIE);
- GPIO_REG(GPIO_INPUT_EN) &= ~(1 << EVE_PIN_INT);
+ GPIO_REG(GPIO_INPUT_EN) &= ~(1 << CTP_PIN_INT);
return EOS_OK;
}
@@ -435,7 +460,17 @@ int eos_egpio_fxl_set_pin(uint8_t reg, uint8_t pin, uint8_t val) {
return EOS_OK;
}
-int _eos_egpio_get_val(uint8_t pin) {
+static int egpio_fxl_set_mask(uint8_t chip_id, uint8_t mask) {
+ int rv;
+
+ rv = fxl6408_reg_write(chip_id, FXL6408_REG_INT_MASK, mask);
+ if (rv) return rv;
+
+ egpio_intmask[chip_id] = mask;
+ return EOS_OK;
+}
+
+static int egpio_get_val(uint8_t pin) {
uint8_t chip_id;
chip_id = EGPIO_PIN2CHIP(pin);
@@ -443,7 +478,7 @@ int _eos_egpio_get_val(uint8_t pin) {
return !!(egpio_pinval[chip_id] & EGPIO_PIN2BIT(pin));
}
-int _eos_egpio_set_val(uint8_t pin, int val) {
+static int egpio_set_val(uint8_t pin, int val) {
uint8_t chip_id;
int rv;
@@ -485,7 +520,7 @@ int eos_egpio_get_val(uint8_t pin) {
case EGPIO_PIN_EVEAUDIO_DIS:
case EGPIO_PIN_LSGAIN_SEL: {
- int lspk_on = (eos_i2s_running() || !_eos_egpio_get_val(EGPIO_PIN_AUDIO_SEL)) && eos_egpio_get_val(EGPIO_PIN_HP_NDET);
+ int lspk_on = (eos_i2s_running() || !egpio_get_val(EGPIO_PIN_AUDIO_SEL)) && eos_egpio_get_val(EGPIO_PIN_HP_NDET);
if ((pin == EGPIO_PIN_EVEAUDIO_DIS) && lspk_on) {
return !!(egpio_alt_pin & pin2alt_bit(pin));
@@ -498,7 +533,7 @@ int eos_egpio_get_val(uint8_t pin) {
}
}
- return _eos_egpio_get_val(pin);
+ return egpio_get_val(pin);
}
int eos_egpio_set_val(uint8_t pin, int val) {
@@ -520,7 +555,7 @@ int eos_egpio_set_val(uint8_t pin, int val) {
return EOS_OK;
}
- if ((val != _eos_egpio_get_val(EGPIO_PIN_AUDIO_SEL)) && eos_egpio_get_val(EGPIO_PIN_HP_NDET)) {
+ if ((val != egpio_get_val(EGPIO_PIN_AUDIO_SEL)) && eos_egpio_get_val(EGPIO_PIN_HP_NDET)) {
if (val) {
/* store LSGAIN_SEL pin and set EVEAUDIO_DIS pin */
PINSWITCH(EGPIO_PIN_LSGAIN_SEL, EGPIO_PIN_EVEAUDIO_DIS);
@@ -534,7 +569,7 @@ int eos_egpio_set_val(uint8_t pin, int val) {
case EGPIO_PIN_EVEAUDIO_DIS:
case EGPIO_PIN_LSGAIN_SEL: {
- int lspk_on = (eos_i2s_running() || !_eos_egpio_get_val(EGPIO_PIN_AUDIO_SEL)) && eos_egpio_get_val(EGPIO_PIN_HP_NDET);
+ int lspk_on = (eos_i2s_running() || !egpio_get_val(EGPIO_PIN_AUDIO_SEL)) && eos_egpio_get_val(EGPIO_PIN_HP_NDET);
if ((pin == EGPIO_PIN_EVEAUDIO_DIS) && lspk_on) {
BITSET(egpio_alt_pin, pin2alt_bit(pin), val);
@@ -549,7 +584,7 @@ int eos_egpio_set_val(uint8_t pin, int val) {
}
}
- rv = _eos_egpio_set_val(pin, val);
+ rv = egpio_set_val(pin, val);
if (rv) return rv;
return EOS_OK;
@@ -559,13 +594,13 @@ int eos_egpio_i2s_start(void) {
uint8_t data;
int rv, audio_sel;
- rv = _eos_egpio_intr_set(1, !eos_egpio_get_val(EGPIO_PIN_DISP_SEL));
+ rv = egpio_intr_set(1, !eos_egpio_get_val(EGPIO_PIN_DISP_SEL));
if (rv) return rv;
- audio_sel = _eos_egpio_get_val(EGPIO_PIN_AUDIO_SEL);
+ audio_sel = egpio_get_val(EGPIO_PIN_AUDIO_SEL);
BITSET(egpio_alt_pin, pin2alt_bit(EGPIO_PIN_AUDIO_SEL), audio_sel);
- rv = _eos_egpio_set_val(EGPIO_PIN_AUDIO_SEL, 1);
+ rv = egpio_set_val(EGPIO_PIN_AUDIO_SEL, 1);
if (rv) return rv;
if (!audio_sel && eos_egpio_get_val(EGPIO_PIN_HP_NDET)) {
@@ -579,7 +614,7 @@ int eos_egpio_i2s_start(void) {
int eos_egpio_i2s_stop(void) {
int rv, audio_sel;
- rv = _eos_egpio_intr_set(0, !eos_egpio_get_val(EGPIO_PIN_DISP_SEL));
+ rv = egpio_intr_set(0, !eos_egpio_get_val(EGPIO_PIN_DISP_SEL));
if (rv) return rv;
audio_sel = (egpio_alt_pin & pin2alt_bit(EGPIO_PIN_AUDIO_SEL));
@@ -588,7 +623,7 @@ int eos_egpio_i2s_stop(void) {
PINSWITCH(EGPIO_PIN_LSGAIN_SEL, EGPIO_PIN_EVEAUDIO_DIS);
}
- rv = _eos_egpio_set_val(EGPIO_PIN_AUDIO_SEL, audio_sel);
+ rv = egpio_set_val(EGPIO_PIN_AUDIO_SEL, audio_sel);
if (rv) return rv;
return EOS_OK;
diff --git a/fw/fe310/eos/dev/egpio.h b/fw/fe310/eos/dev/egpio.h
index 7d20443..a916ed5 100644
--- a/fw/fe310/eos/dev/egpio.h
+++ b/fw/fe310/eos/dev/egpio.h
@@ -1,93 +1,13 @@
#include <stdint.h>
-#define EGPIO_ETYPE_INT 1
-#define EGPIO_ETYPE_INT_CTP 2
-#define EGPIO_ETYPE_INT_EVE 3
+#define EOS_EGPIO_ETYPE_INT 1
+#define EOS_EGPIO_ETYPE_INT_CTP 2 /* EGPIO_PIN_CTP_SEL is on: CTP int; EGPIO_PIN_CTP_SEL is off: EVE int */
-#define EGPIO_INT_TYPE_BAT 1
-#define EGPIO_INT_TYPE_WAKE 2
-#define EGPIO_INT_TYPE_SDCARD 3
-#define EGPIO_INT_TYPE_MUTE 4
-#define EGPIO_INT_TYPE_HP 5
-
-#define EGPIO_CHIP_FXL0 0x00
-#define EGPIO_CHIP_FXL1 0x01
-#define EGPIO_CHIP_EVE 0x02
-
-#define EGPIO_MAX_CHIP 3
-
-#define EGPIO_PIN_MASK 0x07
-#define EGPIO_PIN_MASK_CHIP 0x30
-
-#define EGPIO_PIN2BIT(X) (1 << ((X) & EGPIO_PIN_MASK))
-#define EGPIO_PIN2CHIP(X) (((X) & EGPIO_PIN_MASK_CHIP) >> 4)
-#define EGPIO_PIN(C,P) (((C) << 4) | (P))
-
-#define EGPIO0_PIN_EVE_INT 0x00 /* EVE interrrupt */
-#define EGPIO0_PIN_SDCARD_DET 0x01 /* SD Card detect */
-#define EGPIO0_PIN_EXP_IO0 0x02 /* expansion io 0 */
-#define EGPIO0_PIN_EXP_IO1 0x03 /* expansion io 1 */
-#define EGPIO0_PIN_BTN_WAKE 0x04 /* wake button */
-#define EGPIO0_PIN_BAT_INT 0x05 /* battery charger IC inetrrupt */
-#define EGPIO0_PIN_CTP_SEL 0x06 /* switch CTP connection: EVE_DISP:1 and CTP_SEL:0 - connected to EVE chip, EVE_DISP:X and CTP_SEL:1 - connected to fe310 chip, EVE_DISP:0 and CTP_SEL:0 - connected to app module */
-#define EGPIO0_PIN_CTP_INT 0x07 /* CTP interrupt */
-
-#define EGPIO1_PIN_MIC_MUTE 0x00 /* microphone disable */
-#define EGPIO1_PIN_HPAMP_CS 0x01 /* SPI chip select for headphone amplifier (pcm1770) */
-#define EGPIO1_PIN_AUDIO_SEL 0x02 /* switch audio connection: 0 - connected to app module, 1 - connected to fe310 chip (only when i2s is off) */
-#define EGPIO1_PIN_HP_NDET 0x03 /* headphone detect: 0 - inserted, 1 - not inserted */
-#define EGPIO1_PIN_USR0 0x04 /* user IO */
-#define EGPIO1_PIN_USR1 0x05
-#define EGPIO1_PIN_USR2 0x06
-#define EGPIO1_PIN_USR3 0x07
-
-#define EGPIOE_PIN_DISP 0x07 /* EVE DISP GPIO */
-
-#define EGPIO_PIN_ALT 0x08
-
-#define EGPIO_PIN_EVE_INT EGPIO_PIN(EGPIO_CHIP_FXL0, EGPIO0_PIN_EVE_INT)
-#define EGPIO_PIN_SDCARD_DET EGPIO_PIN(EGPIO_CHIP_FXL0, EGPIO0_PIN_SDCARD_DET)
-#define EGPIO_PIN_EXP_IO0 EGPIO_PIN(EGPIO_CHIP_FXL0, EGPIO0_PIN_EXP_IO0)
-#define EGPIO_PIN_EXP_IO1 EGPIO_PIN(EGPIO_CHIP_FXL0, EGPIO0_PIN_EXP_IO1)
-#define EGPIO_PIN_BTN_WAKE EGPIO_PIN(EGPIO_CHIP_FXL0, EGPIO0_PIN_BTN_WAKE)
-#define EGPIO_PIN_BAT_INT EGPIO_PIN(EGPIO_CHIP_FXL0, EGPIO0_PIN_BAT_INT)
-#define EGPIO_PIN_CTP_SEL EGPIO_PIN(EGPIO_CHIP_FXL0, EGPIO0_PIN_CTP_SEL)
-#define EGPIO_PIN_CTP_INT EGPIO_PIN(EGPIO_CHIP_FXL0, EGPIO0_PIN_CTP_INT)
-
-#define EGPIO_PIN_MIC_MUTE EGPIO_PIN(EGPIO_CHIP_FXL1, EGPIO1_PIN_MIC_MUTE)
-#define EGPIO_PIN_HPAMP_CS EGPIO_PIN(EGPIO_CHIP_FXL1, EGPIO1_PIN_HPAMP_CS)
-#define EGPIO_PIN_AUDIO_SEL EGPIO_PIN(EGPIO_CHIP_FXL1, EGPIO1_PIN_AUDIO_SEL)
-#define EGPIO_PIN_HP_NDET EGPIO_PIN(EGPIO_CHIP_FXL1, EGPIO1_PIN_HP_NDET)
-#define EGPIO_PIN_USR0 EGPIO_PIN(EGPIO_CHIP_FXL1, EGPIO1_PIN_USR0)
-#define EGPIO_PIN_USR1 EGPIO_PIN(EGPIO_CHIP_FXL1, EGPIO1_PIN_USR1)
-#define EGPIO_PIN_USR2 EGPIO_PIN(EGPIO_CHIP_FXL1, EGPIO1_PIN_USR2)
-#define EGPIO_PIN_USR3 EGPIO_PIN(EGPIO_CHIP_FXL1, EGPIO1_PIN_USR3)
-
-/* EVE pins defined in eve.h */
-#define EGPIO_PIN_USR4 EGPIO_PIN(EGPIO_CHIP_EVE, EVE_GPIO_USR)
-#define EGPIO_PIN_EVEAUDIO_DIS EGPIO_PIN(EGPIO_CHIP_EVE, EVE_GPIO_EVEAUDIO_DIS)
-#define EGPIO_PIN_LSGAIN_SEL EGPIO_PIN(EGPIO_CHIP_EVE, EVE_GPIO_LSGAIN_SEL | EGPIO_PIN_ALT)
-#define EGPIO_PIN_LCD_EN EGPIO_PIN(EGPIO_CHIP_EVE, EVE_GPIO_LCD_EN)
-#define EGPIO_PIN_CAM_EN EGPIO_PIN(EGPIO_CHIP_EVE, EVE_GPIO_CAM_EN)
-#define EGPIO_PIN_DISP_SEL EGPIO_PIN(EGPIO_CHIP_EVE, EGPIOE_PIN_DISP)
-
-#define EGPIO_BIT_EVE_INT EGPIO_PIN2BIT(EGPIO0_PIN_EVE_INT)
-#define EGPIO_BIT_SDCARD_DET EGPIO_PIN2BIT(EGPIO0_PIN_SDCARD_DET)
-#define EGPIO_BIT_EXP_IO0 EGPIO_PIN2BIT(EGPIO0_PIN_EXP_IO0)
-#define EGPIO_BIT_EXP_IO1 EGPIO_PIN2BIT(EGPIO0_PIN_EXP_IO1)
-#define EGPIO_BIT_BTN_WAKE EGPIO_PIN2BIT(EGPIO0_PIN_BTN_WAKE)
-#define EGPIO_BIT_BAT_INT EGPIO_PIN2BIT(EGPIO0_PIN_BAT_INT)
-#define EGPIO_BIT_CTP_SEL EGPIO_PIN2BIT(EGPIO0_PIN_CTP_SEL)
-#define EGPIO_BIT_CTP_INT EGPIO_PIN2BIT(EGPIO0_PIN_CTP_INT)
-
-#define EGPIO_BIT_MIC_MUTE EGPIO_PIN2BIT(EGPIO1_PIN_MIC_MUTE)
-#define EGPIO_BIT_HPAMP_CS EGPIO_PIN2BIT(EGPIO1_PIN_HPAMP_CS)
-#define EGPIO_BIT_AUDIO_SEL EGPIO_PIN2BIT(EGPIO1_PIN_AUDIO_SEL)
-#define EGPIO_BIT_HP_NDET EGPIO_PIN2BIT(EGPIO1_PIN_HP_NDET)
-#define EGPIO_BIT_USR0 EGPIO_PIN2BIT(EGPIO1_PIN_USR0)
-#define EGPIO_BIT_USR1 EGPIO_PIN2BIT(EGPIO1_PIN_USR1)
-#define EGPIO_BIT_USR2 EGPIO_PIN2BIT(EGPIO1_PIN_USR2)
-#define EGPIO_BIT_USR3 EGPIO_PIN2BIT(EGPIO1_PIN_USR3)
+#define EOS_EGPIO_INT_TYPE_BAT 1
+#define EOS_EGPIO_INT_TYPE_WAKE 2
+#define EOS_EGPIO_INT_TYPE_SDCARD 3
+#define EOS_EGPIO_INT_TYPE_MUTE 4
+#define EOS_EGPIO_INT_TYPE_HP 5
typedef void (*eos_egpio_intr_handler_t) (uint8_t type, int data0, int data1);
typedef int (*eos_egpio_ext_handler_t) (void);
@@ -95,7 +15,6 @@ typedef int (*eos_egpio_ext_handler_t) (void);
int eos_egpio_init(void);
int eos_egpio_run(void);
void eos_egpio_eve_set(uint16_t gpio_reg);
-int _eos_egpio_intr_set(int i2s_running, int app_running);
int eos_egpio_intr_set(void);
int eos_egpio_intr_enable(void);
int eos_egpio_intr_disable(void);
@@ -106,8 +25,6 @@ void eos_egpio_set_ext_handler(eos_egpio_ext_handler_t handler);
int eos_egpio_fxl_get_pin(uint8_t reg, uint8_t pin, uint8_t *val);
int eos_egpio_fxl_set_pin(uint8_t reg, uint8_t pin, uint8_t val);
-int _eos_egpio_get_val(uint8_t pin);
-int _eos_egpio_set_val(uint8_t pin, int val);
int eos_egpio_get_val(uint8_t pin);
int eos_egpio_set_val(uint8_t pin, int val);
diff --git a/fw/fe310/eos/dev/egpio_priv.h b/fw/fe310/eos/dev/egpio_priv.h
new file mode 100644
index 0000000..04fe271
--- /dev/null
+++ b/fw/fe310/eos/dev/egpio_priv.h
@@ -0,0 +1,81 @@
+#include "eve_priv.h"
+
+#define EGPIO_CHIP_FXL0 0
+#define EGPIO_CHIP_FXL1 1
+#define EGPIO_CHIP_EVE 2
+
+#define EGPIO_MAX_CHIP 3
+#define EGPIO_MAX_FXL_CHIP 2
+
+#define EGPIO_PIN_MASK 0x07
+#define EGPIO_PIN_MASK_CHIP 0x30
+
+#define EGPIO_PIN2BIT(X) (1 << ((X) & EGPIO_PIN_MASK))
+#define EGPIO_PIN2CHIP(X) (((X) & EGPIO_PIN_MASK_CHIP) >> 4)
+#define EGPIO_PIN(C,P) (((C) << 4) | (P))
+
+#define EGPIO0_PIN_EVE_INT 0x00 /* EVE interrrupt */
+#define EGPIO0_PIN_SDCARD_NDET 0x01 /* SD Card detect: 0 - inserted, 1 - not inserted */
+#define EGPIO0_PIN_EXP_IO0 0x02 /* expansion io 0 */
+#define EGPIO0_PIN_EXP_IO1 0x03 /* expansion io 1 */
+#define EGPIO0_PIN_BTN_WAKE 0x04 /* wake button */
+#define EGPIO0_PIN_BAT_INT 0x05 /* battery charger IC inetrrupt */
+#define EGPIO0_PIN_CTP_SEL 0x06 /* switch CTP connection: EVE_DISP:1 and CTP_SEL:0 - connected to EVE chip, EVE_DISP:X and CTP_SEL:1 - connected to fe310 chip, EVE_DISP:0 and CTP_SEL:0 - connected to app module */
+#define EGPIO0_PIN_CTP_INT 0x07 /* CTP interrupt */
+
+#define EGPIO1_PIN_MIC_MUTE 0x00 /* microphone disable */
+#define EGPIO1_PIN_HPAMP_CS 0x01 /* SPI chip select for headphone amplifier (pcm1770) */
+#define EGPIO1_PIN_AUDIO_SEL 0x02 /* switch audio connection: 0 - connected to app module, 1 - connected to fe310 chip (only when i2s is off) */
+#define EGPIO1_PIN_HP_NDET 0x03 /* headphone detect: 0 - inserted, 1 - not inserted */
+#define EGPIO1_PIN_USR0 0x04 /* user IO */
+#define EGPIO1_PIN_USR1 0x05
+#define EGPIO1_PIN_USR2 0x06
+#define EGPIO1_PIN_USR3 0x07
+
+#define EGPIOE_PIN_DISP 0x07 /* EVE DISP GPIO */
+
+#define EGPIO_PIN_ALT 0x08
+
+#define EGPIO_BIT_EVE_INT EGPIO_PIN2BIT(EGPIO0_PIN_EVE_INT)
+#define EGPIO_BIT_SDCARD_NDET EGPIO_PIN2BIT(EGPIO0_PIN_SDCARD_NDET)
+#define EGPIO_BIT_EXP_IO0 EGPIO_PIN2BIT(EGPIO0_PIN_EXP_IO0)
+#define EGPIO_BIT_EXP_IO1 EGPIO_PIN2BIT(EGPIO0_PIN_EXP_IO1)
+#define EGPIO_BIT_BTN_WAKE EGPIO_PIN2BIT(EGPIO0_PIN_BTN_WAKE)
+#define EGPIO_BIT_BAT_INT EGPIO_PIN2BIT(EGPIO0_PIN_BAT_INT)
+#define EGPIO_BIT_CTP_SEL EGPIO_PIN2BIT(EGPIO0_PIN_CTP_SEL)
+#define EGPIO_BIT_CTP_INT EGPIO_PIN2BIT(EGPIO0_PIN_CTP_INT)
+
+#define EGPIO_BIT_MIC_MUTE EGPIO_PIN2BIT(EGPIO1_PIN_MIC_MUTE)
+#define EGPIO_BIT_HPAMP_CS EGPIO_PIN2BIT(EGPIO1_PIN_HPAMP_CS)
+#define EGPIO_BIT_AUDIO_SEL EGPIO_PIN2BIT(EGPIO1_PIN_AUDIO_SEL)
+#define EGPIO_BIT_HP_NDET EGPIO_PIN2BIT(EGPIO1_PIN_HP_NDET)
+#define EGPIO_BIT_USR0 EGPIO_PIN2BIT(EGPIO1_PIN_USR0)
+#define EGPIO_BIT_USR1 EGPIO_PIN2BIT(EGPIO1_PIN_USR1)
+#define EGPIO_BIT_USR2 EGPIO_PIN2BIT(EGPIO1_PIN_USR2)
+#define EGPIO_BIT_USR3 EGPIO_PIN2BIT(EGPIO1_PIN_USR3)
+
+#define EGPIO_PIN_EVE_INT EGPIO_PIN(EGPIO_CHIP_FXL0, EGPIO0_PIN_EVE_INT)
+#define EGPIO_PIN_SDCARD_NDET EGPIO_PIN(EGPIO_CHIP_FXL0, EGPIO0_PIN_SDCARD_NDET)
+#define EGPIO_PIN_EXP_IO0 EGPIO_PIN(EGPIO_CHIP_FXL0, EGPIO0_PIN_EXP_IO0)
+#define EGPIO_PIN_EXP_IO1 EGPIO_PIN(EGPIO_CHIP_FXL0, EGPIO0_PIN_EXP_IO1)
+#define EGPIO_PIN_BTN_WAKE EGPIO_PIN(EGPIO_CHIP_FXL0, EGPIO0_PIN_BTN_WAKE)
+#define EGPIO_PIN_BAT_INT EGPIO_PIN(EGPIO_CHIP_FXL0, EGPIO0_PIN_BAT_INT)
+#define EGPIO_PIN_CTP_SEL EGPIO_PIN(EGPIO_CHIP_FXL0, EGPIO0_PIN_CTP_SEL)
+#define EGPIO_PIN_CTP_INT EGPIO_PIN(EGPIO_CHIP_FXL0, EGPIO0_PIN_CTP_INT)
+
+#define EGPIO_PIN_MIC_MUTE EGPIO_PIN(EGPIO_CHIP_FXL1, EGPIO1_PIN_MIC_MUTE)
+#define EGPIO_PIN_HPAMP_CS EGPIO_PIN(EGPIO_CHIP_FXL1, EGPIO1_PIN_HPAMP_CS)
+#define EGPIO_PIN_AUDIO_SEL EGPIO_PIN(EGPIO_CHIP_FXL1, EGPIO1_PIN_AUDIO_SEL)
+#define EGPIO_PIN_HP_NDET EGPIO_PIN(EGPIO_CHIP_FXL1, EGPIO1_PIN_HP_NDET)
+#define EGPIO_PIN_USR0 EGPIO_PIN(EGPIO_CHIP_FXL1, EGPIO1_PIN_USR0)
+#define EGPIO_PIN_USR1 EGPIO_PIN(EGPIO_CHIP_FXL1, EGPIO1_PIN_USR1)
+#define EGPIO_PIN_USR2 EGPIO_PIN(EGPIO_CHIP_FXL1, EGPIO1_PIN_USR2)
+#define EGPIO_PIN_USR3 EGPIO_PIN(EGPIO_CHIP_FXL1, EGPIO1_PIN_USR3)
+
+/* EVE pins defined in eve.h */
+#define EGPIO_PIN_USR4 EGPIO_PIN(EGPIO_CHIP_EVE, EVE_GPIO_USR)
+#define EGPIO_PIN_EVEAUDIO_DIS EGPIO_PIN(EGPIO_CHIP_EVE, EVE_GPIO_EVEAUDIO_DIS)
+#define EGPIO_PIN_LSGAIN_SEL EGPIO_PIN(EGPIO_CHIP_EVE, EVE_GPIO_LSGAIN_SEL | EGPIO_PIN_ALT)
+#define EGPIO_PIN_LCD_EN EGPIO_PIN(EGPIO_CHIP_EVE, EVE_GPIO_LCD_EN)
+#define EGPIO_PIN_CAM_EN EGPIO_PIN(EGPIO_CHIP_EVE, EVE_GPIO_CAM_EN)
+#define EGPIO_PIN_DISP_SEL EGPIO_PIN(EGPIO_CHIP_EVE, EGPIOE_PIN_DISP)
diff --git a/fw/fe310/eos/dev/eve.c b/fw/fe310/eos/dev/eve.c
index dad7dfe..25a3558 100644
--- a/fw/fe310/eos/dev/eve.c
+++ b/fw/fe310/eos/dev/eve.c
@@ -2,6 +2,7 @@
#include <stdint.h>
#include "eos.h"
+#include "log.h"
#include "event.h"
#include "soc/pwr.h"
@@ -11,15 +12,12 @@
#include "eve/eve_touch_engine.h"
#include "egpio.h"
+#include "egpio_priv.h"
#include "spi.h"
#include "aon.h"
-#include "pwr.h"
#include "eve.h"
-
-#ifdef EOS_DEBUG
-#include <stdio.h>
-#endif
+#include "eve_priv.h"
static void handle_time(unsigned char type) {
int rv;
@@ -36,13 +34,12 @@ int eos_eve_handle_intr(void) {
int rv;
rv = eve_select();
- if (rv) return 0;
+ if (rv) return rv;
intr_flags = eve_handle_intr();
eve_deselect();
- if (intr_flags == 0) return 0;
- return 1;
+ return intr_flags;
}
int eos_eve_init(void) {
@@ -64,15 +61,12 @@ int eos_eve_init(void) {
eve_touch_init_engine(eos_egpio_get_val(EGPIO_PIN_CTP_SEL) ? EVE_TOUCH_ENGINE_HOST : EVE_TOUCH_ENGINE_GOODIX);
gpio_reg = EVE_GPIO_DEFAULT;
} else {
- uint8_t pwr_state;
-
- pwr_state = eos_aon_load4eve();
- eve_pwr_set_state(pwr_state);
+ eve_pwr_set_state(eos_aon_load4eve());
eve_activate();
gpio_reg = eve_gpio_read();
eve_cmd_set_offset();
- if (gpio_reg & EVE_GPIO_DISP) {
+ if (gpio_reg & (1 << EVE_GPIO_DISP)) {
eve_pwr_set_state(EVE_PSTATE_ACTIVE);
}
eve_deactivate();
@@ -92,9 +86,19 @@ eve_init_fin:
}
int eos_eve_run(void) {
- int rv;
+ uint8_t wakeup_cause;
+ int rst, rv;
+
+ wakeup_cause = eos_pwr_wakeup_cause();
+ rst = (wakeup_cause == EOS_PWR_WAKE_RST);
- if (eve_pwr_state() != EVE_PSTATE_ACTIVE) return EOS_ERR_BUSY;
+ if (!rst) {
+ /* was active before sleep */
+ if (eos_aon_load4eve() == EVE_PSTATE_ACTIVE) return EOS_OK;
+
+ /* DISP pin is off */
+ if (eve_pwr_state() != EVE_PSTATE_ACTIVE) return EOS_ERR_BUSY;
+ }
rv = eve_select();
if (rv) return rv;
@@ -111,10 +115,12 @@ int eos_eve_run(void) {
int eos_eve_sleep(void) {
int rv;
+ if (eve_pwr_state() != EVE_PSTATE_ACTIVE) return EOS_ERR;
+
rv = eve_select();
if (rv) return rv;
- eos_aon_save4eve(eve_pwr_state());
+ eve_brightness(0);
eve_clk_stop();
eve_intr_disable();
eve_touch_stop();
@@ -125,16 +131,46 @@ int eos_eve_sleep(void) {
return EOS_OK;
}
+int eos_eve_wake(void) {
+ int disp, rv;
+
+ if (eve_pwr_state() == EVE_PSTATE_ACTIVE) return EOS_ERR;
+
+ rv = eve_select();
+ if (rv) return rv;
+
+ eve_activate();
+ disp = eve_gpio_get(EVE_GPIO_DISP);
+ if (disp) {
+ eve_pwr_set_state(EVE_PSTATE_ACTIVE);
+ }
+ eve_deactivate();
+
+ if (eve_pwr_state() != EVE_PSTATE_ACTIVE) {
+ rv = EOS_ERR_BUSY;
+ goto eve_wake_fin;
+ }
+
+ eve_touch_intr_enable();
+ eve_touch_start();
+ eve_intr_enable();
+ eve_clk_start();
+eve_wake_fin:
+ eve_deselect();
+
+ return rv;
+}
+
+void eos_eve_save2aon(void) {
+ eos_aon_save4eve(eve_pwr_state());
+}
+
void eve_calibrate(void) {
int rv, d;
-#ifdef EOS_DEBUG
uint32_t matrix[6];
-#endif
if (!eve_selected()) {
-#ifdef EOS_DEBUG
- printf("EVE CALIBRATE: NOT SELECTED\n");
-#endif
+ EOS_LOG(EOS_LOG_ERR, "EVE CALIBRATE: NOT SELECTED\n");
return;
}
@@ -155,25 +191,21 @@ void eve_calibrate(void) {
eos_evtq_exec();
rv = eve_select();
if (rv) {
-#ifdef EOS_DEBUG
- printf("EVE CALIBRATE ERR:%d\n", rv);
-#endif
+ EOS_LOG(EOS_LOG_ERR, "EVE CALIBRATE ERR:%d\n", rv);
return;
}
} while (!d);
eve_touch_set_extended(1);
-#ifdef EOS_DEBUG
if (rv) {
- printf("EVE CALIBRATE ERR:%d\n", rv);
+ EOS_LOG(EOS_LOG_ERR, "EVE CALIBRATE ERR:%d\n", rv);
return;
}
eve_touch_get_matrix(matrix);
- printf("TOUCH MATRIX:\n");
- printf("uint32_t touch_matrix[6] = {0x%x,0x%x,0x%x,0x%x,0x%x,0x%x}\n", matrix[0], matrix[1], matrix[2], matrix[3], matrix[4], matrix[5]);
-#endif
+ EOS_LOG(EOS_LOG_INFO, "TOUCH MATRIX:\n");
+ EOS_LOG(EOS_LOG_INFO, "uint32_t touch_matrix[6] = {0x%x,0x%x,0x%x,0x%x,0x%x,0x%x}\n", matrix[0], matrix[1], matrix[2], matrix[3], matrix[4], matrix[5]);
}
int eve_select(void) {
diff --git a/fw/fe310/eos/dev/eve.h b/fw/fe310/eos/dev/eve.h
index 441cd5a..564e8c1 100644
--- a/fw/fe310/eos/dev/eve.h
+++ b/fw/fe310/eos/dev/eve.h
@@ -1,22 +1,12 @@
#include <stdint.h>
-#define EVE_GPIO_DIR 0x800f
-#define EVE_GPIO_DEFAULT 0x2 /* EVEAUDIO_DIS */
-#define EVE_GPIO_MASK 0x800f
-
-#define EVE_GPIO_USR 0
-#define EVE_GPIO_EVEAUDIO_DIS 1 /* only when lspk is off */
-#define EVE_GPIO_LSGAIN_SEL 1 /* only when lspk is on */
-#define EVE_GPIO_LCD_EN 2
-#define EVE_GPIO_CAM_EN 3
-#define EVE_GPIO_DISP 15
-
int eos_eve_handle_intr(void);
int eos_eve_init(void);
int eos_eve_run(void);
int eos_eve_sleep(void);
int eos_eve_wake(void);
+void eos_eve_save2aon(void);
void eve_calibrate(void);
int eve_select(void);
diff --git a/fw/fe310/eos/dev/eve_priv.h b/fw/fe310/eos/dev/eve_priv.h
new file mode 100644
index 0000000..3863f5d
--- /dev/null
+++ b/fw/fe310/eos/dev/eve_priv.h
@@ -0,0 +1,10 @@
+#define EVE_GPIO_DIR 0x800f
+#define EVE_GPIO_DEFAULT 0x8002 /* DISP on, EVEAUDIO_DIS */
+#define EVE_GPIO_MASK 0x800f
+
+#define EVE_GPIO_USR 0
+#define EVE_GPIO_EVEAUDIO_DIS 1 /* only when lspk is off */
+#define EVE_GPIO_LSGAIN_SEL 1 /* only when lspk is on */
+#define EVE_GPIO_LCD_EN 2
+#define EVE_GPIO_CAM_EN 3
+#define EVE_GPIO_DISP 15
diff --git a/fw/fe310/eos/dev/flash.c b/fw/fe310/eos/dev/flash.c
index c8f4c98..15811a2 100644
--- a/fw/fe310/eos/dev/flash.c
+++ b/fw/fe310/eos/dev/flash.c
@@ -9,6 +9,21 @@
#include "flash.h"
+#define FLASH_RDSR 0x05
+
+#define FLASH_NORD 0x03
+#define FLASH_FRD 0x0b
+
+#define FLASH_WREN 0x06
+#define FLASH_SER 0x20
+#define FLASH_PP 0x02
+
+#define FLASH_QPIEN 0x35
+#define FLASH_QPIDI 0xF5
+
+#define FLASH_WIP 0x01
+#define FLASH_WEL 0x02
+
#define IDLE_TICKS 10
__attribute__ ((section (".itim.flash")))
@@ -42,7 +57,7 @@ void eos_flash_norm(void) {
SPI0_REG(SPI_REG_SCKDIV) = 3;
if (SPI0_REG(SPI_REG_FMT) & SPI_FMT_PROTO(SPI_PROTO_Q)) {
- send(EOS_FLASH_QPIDI);
+ send(FLASH_QPIDI);
while (!(SPI0_REG(SPI_REG_IP) & SPI_IP_TXWM));
}
@@ -59,7 +74,7 @@ void eos_flash_norm(void) {
SPI_INSN_CMD_PROTO(SPI_PROTO_S) |
SPI_INSN_ADDR_PROTO(SPI_PROTO_S) |
SPI_INSN_DATA_PROTO(SPI_PROTO_S) |
- SPI_INSN_CMD_CODE(EOS_FLASH_NORD) |
+ SPI_INSN_CMD_CODE(FLASH_NORD) |
SPI_INSN_PAD_CODE(0x00);
mtime0 = *mtime;
@@ -79,7 +94,7 @@ void eos_flash_fast(void) {
SPI0_REG(SPI_REG_SCKDIV) = 2;
if (!(SPI0_REG(SPI_REG_FMT) & SPI_FMT_PROTO(SPI_PROTO_Q))) {
- send(EOS_FLASH_QPIEN);
+ send(FLASH_QPIEN);
while (!(SPI0_REG(SPI_REG_IP) & SPI_IP_TXWM));
}
@@ -96,7 +111,7 @@ void eos_flash_fast(void) {
SPI_INSN_CMD_PROTO(SPI_PROTO_Q) |
SPI_INSN_ADDR_PROTO(SPI_PROTO_Q) |
SPI_INSN_DATA_PROTO(SPI_PROTO_Q) |
- SPI_INSN_CMD_CODE(EOS_FLASH_FRD) |
+ SPI_INSN_CMD_CODE(FLASH_FRD) |
SPI_INSN_PAD_CODE(0x00);
mtime0 = *mtime;
@@ -112,31 +127,31 @@ void eos_flash_wip(void) {
do {
SPI0_REG(SPI_REG_CSMODE) = SPI_CSMODE_HOLD;
- xfer(EOS_FLASH_RDSR);
+ xfer(FLASH_RDSR);
status = xfer(0);
SPI0_REG(SPI_REG_CSMODE) = SPI_CSMODE_AUTO;
- } while (status & EOS_FLASH_WIP);
+ } while (status & FLASH_WIP);
}
__attribute__ ((section (".itim.flash")))
void eos_flash_wren(void) {
uint8_t status;
- xfer(EOS_FLASH_WREN);
+ xfer(FLASH_WREN);
#if 0
do {
SPI0_REG(SPI_REG_CSMODE) = SPI_CSMODE_HOLD;
- xfer(EOS_FLASH_RDSR);
+ xfer(FLASH_RDSR);
status = xfer(0);
SPI0_REG(SPI_REG_CSMODE) = SPI_CSMODE_AUTO;
- } while (!(status & EOS_FLASH_WEL));
+ } while (!(status & FLASH_WEL));
#endif
}
__attribute__ ((section (".itim.flash")))
void eos_flash_ser(uint32_t addr) {
SPI0_REG(SPI_REG_CSMODE) = SPI_CSMODE_HOLD;
- xfer(EOS_FLASH_SER);
+ xfer(FLASH_SER);
xfer(addr >> 16);
xfer(addr >> 8);
xfer(addr);
@@ -149,7 +164,7 @@ void eos_flash_pp(uint32_t addr, uint8_t *buf) {
SPI0_REG(SPI_REG_FMT) |= SPI_FMT_DIR(SPI_DIR_TX);
SPI0_REG(SPI_REG_CSMODE) = SPI_CSMODE_HOLD;
- send(EOS_FLASH_PP);
+ send(FLASH_PP);
send(addr >> 16);
send(addr >> 8);
send(addr);
diff --git a/fw/fe310/eos/dev/flash.h b/fw/fe310/eos/dev/flash.h
index 6f792cb..714e9bc 100644
--- a/fw/fe310/eos/dev/flash.h
+++ b/fw/fe310/eos/dev/flash.h
@@ -1,20 +1,5 @@
#include <stdint.h>
-#define EOS_FLASH_RDSR 0x05
-
-#define EOS_FLASH_NORD 0x03
-#define EOS_FLASH_FRD 0x0b
-
-#define EOS_FLASH_WREN 0x06
-#define EOS_FLASH_SER 0x20
-#define EOS_FLASH_PP 0x02
-
-#define EOS_FLASH_QPIEN 0x35
-#define EOS_FLASH_QPIDI 0xF5
-
-#define EOS_FLASH_WIP 0x01
-#define EOS_FLASH_WEL 0x02
-
void eos_flash_init(void);
void eos_flash_norm(void);
void eos_flash_fast(void);
diff --git a/fw/fe310/eos/dev/lcd.c b/fw/fe310/eos/dev/lcd.c
index 6c005b9..01d86e9 100644
--- a/fw/fe310/eos/dev/lcd.c
+++ b/fw/fe310/eos/dev/lcd.c
@@ -13,9 +13,8 @@
#include "eve/eve.h"
#include "egpio.h"
+#include "egpio_priv.h"
#include "spi.h"
-#include "eve.h"
-#include "pwr.h"
#include "drv/ili9806e.h"
#include "lcd.h"
@@ -38,6 +37,10 @@ static int lcd_disable(void) {
return rv;
}
+static int lcd_enabled(void) {
+ return eos_egpio_get_val(EGPIO_PIN_LCD_EN);
+}
+
static int lcd_select(void) {
int rv;
@@ -52,6 +55,7 @@ static int lcd_select(void) {
GPIO_REG(GPIO_OUTPUT_EN) &= ~(1 << SPI_CSPIN_LCD);
GPIO_REG(GPIO_OUTPUT_XOR) &= ~(1 << SPI_CSPIN_LCD);
GPIO_REG(GPIO_OUTPUT_VAL) &= ~(1 << SPI_CSPIN_LCD);
+
return rv;
}
@@ -60,6 +64,7 @@ static int lcd_select(void) {
static void lcd_deselect(void) {
eos_spi_deselect();
+
GPIO_REG(GPIO_OUTPUT_EN) &= ~(1 << SPI_CSPIN_LCD);
GPIO_REG(GPIO_OUTPUT_XOR) &= ~(1 << SPI_CSPIN_LCD);
GPIO_REG(GPIO_OUTPUT_VAL) &= ~(1 << SPI_CSPIN_LCD);
@@ -118,6 +123,8 @@ int eos_lcd_init(void) {
int eos_lcd_sleep(void) {
int rv;
+ if (!lcd_enabled()) return EOS_ERR;
+
rv = lcd_sleep();
return rv;
}
@@ -125,6 +132,8 @@ int eos_lcd_sleep(void) {
int eos_lcd_wake(void) {
int rv;
+ if (lcd_enabled()) return EOS_ERR;
+
rv = lcd_init();
return rv;
}
diff --git a/fw/fe310/eos/dev/net.c b/fw/fe310/eos/dev/net.c
index d340e29..c1fd9b5 100644
--- a/fw/fe310/eos/dev/net.c
+++ b/fw/fe310/eos/dev/net.c
@@ -3,13 +3,13 @@
#include "encoding.h"
#include "platform.h"
+#include "board.h"
#include "eos.h"
+#include "log.h"
#include "msgq.h"
#include "event.h"
-#include "board.h"
-
#include "soc/interrupt.h"
#include "soc/timer.h"
#include "soc/pwr.h"
@@ -17,17 +17,27 @@
#include "soc/spi_priv.h"
#include "spi.h"
+#include "aon.h"
#include "net.h"
-#define NET_SIZE_HDR 3
-#define NET_STATE_FLAG_RUN 0x01
-#define NET_STATE_FLAG_INIT 0x02
-#define NET_STATE_FLAG_XCHG 0x04
-#define NET_STATE_FLAG_ONEW 0x10
-#define NET_STATE_FLAG_SYNC 0x20
-#define NET_STATE_FLAG_RTS 0x40
-#define NET_STATE_FLAG_CTS 0x80
+#define NET_DETECT_TIMEOUT 1000
+
+#define NET_SIZE_HDR 3
+#define NET_STATE_FLAG_RUN 0x0001
+#define NET_STATE_FLAG_INIT 0x0002
+#define NET_STATE_FLAG_XCHG 0x0004
+#define NET_STATE_FLAG_ONEW 0x0010
+#define NET_STATE_FLAG_SYNC 0x0020
+#define NET_STATE_FLAG_RTS 0x0040
+#define NET_STATE_FLAG_CTS 0x0080
+#define NET_STATE_FLAG_SLEEP 0x0100
+#define NET_STATE_FLAG_SLEEP_REQ 0x0200
+#define NET_STATE_FLAG_ABSENT 0x0400
+
+#define NET_FLAG_MORE 0x01
+#define NET_FLAG_SYNC 0x02
+#define NET_FLAG_REPL 0x04
#define MIN(X, Y) (((X) < (Y)) ? (X) : (Y))
#define MAX(X, Y) (((X) > (Y)) ? (X) : (Y))
@@ -39,7 +49,7 @@ static unsigned char net_bufq_buffer[EOS_NET_SIZE_BUFQ][EOS_NET_SIZE_BUF] __attr
static EOSMsgQ net_send_q;
static EOSMsgItem net_sndq_array[EOS_NET_SIZE_BUFQ];
-static volatile uint8_t net_state_flags = 0;
+static volatile uint16_t net_state_flags = 0;
static volatile unsigned char net_state_type = 0;
static uint32_t net_state_len_tx = 0;
static volatile uint32_t net_state_len_rx = 0;
@@ -49,40 +59,35 @@ static volatile uint8_t net_state_next_cnt = 0;
static unsigned char * volatile net_state_next_buf = NULL;
static eos_evt_handler_t net_handler[EOS_NET_MAX_MTYPE];
-static uint16_t net_wrapper_acq[EOS_EVT_MAX_EVT];
-static uint16_t net_flags_acq[EOS_EVT_MAX_EVT];
+static uint16_t net_wrapper_acq;
+static uint16_t net_flags_acq[EOS_EVT_MAX];
-static int net_xchg_sleep(void) {
- int i;
- int rv = EOS_OK;
+static void net_xchg_reset(void) {
volatile uint32_t x = 0;
+
net_state_flags &= ~NET_STATE_FLAG_CTS;
SPI1_REG(SPI_REG_CSMODE) = SPI_CSMODE_HOLD;
- SPI1_REG(SPI_REG_TXFIFO) = 0xFF;
+ SPI1_REG(SPI_REG_TXFIFO) = 0;
while ((x = SPI1_REG(SPI_REG_RXFIFO)) & SPI_RXFIFO_EMPTY);
- if (x & 0xFF) rv = EOS_ERR_BUSY;
-
- for (i=0; i<7; i++) {
- while (SPI1_REG(SPI_REG_TXFIFO) & SPI_TXFIFO_FULL);
- SPI1_REG(SPI_REG_TXFIFO) = 0;
- while ((x = SPI1_REG(SPI_REG_RXFIFO)) & SPI_RXFIFO_EMPTY);
- }
SPI1_REG(SPI_REG_CSMODE) = SPI_CSMODE_AUTO;
-
- return rv;
}
-static void net_xchg_wake(void) {
- int i;
+static void net_xchg_sleep_req(void) {
volatile uint32_t x = 0;
+ int i;
+
net_state_flags &= ~NET_STATE_FLAG_CTS;
SPI1_REG(SPI_REG_CSMODE) = SPI_CSMODE_HOLD;
- for (i=0; i<8; i++) {
+ SPI1_REG(SPI_REG_TXFIFO) = EOS_NET_MTYPE_SLEEP | EOS_NET_MTYPE_FLAG_ONEW;
+ while ((x = SPI1_REG(SPI_REG_RXFIFO)) & SPI_RXFIFO_EMPTY);
+
+ /* minimum 8 bytes for esp32 */
+ for (i=0; i<7; i++) {
while (SPI1_REG(SPI_REG_TXFIFO) & SPI_TXFIFO_FULL);
SPI1_REG(SPI_REG_TXFIFO) = 0;
while ((x = SPI1_REG(SPI_REG_RXFIFO)) & SPI_RXFIFO_EMPTY);
@@ -91,18 +96,6 @@ static void net_xchg_wake(void) {
SPI1_REG(SPI_REG_CSMODE) = SPI_CSMODE_AUTO;
}
-static void net_xchg_reset(void) {
- volatile uint32_t x = 0;
- net_state_flags &= ~NET_STATE_FLAG_CTS;
-
- SPI1_REG(SPI_REG_CSMODE) = SPI_CSMODE_HOLD;
-
- SPI1_REG(SPI_REG_TXFIFO) = 0;
- while ((x = SPI1_REG(SPI_REG_RXFIFO)) & SPI_RXFIFO_EMPTY);
-
- SPI1_REG(SPI_REG_CSMODE) = SPI_CSMODE_AUTO;
-}
-
static void net_xchg_start(unsigned char type, unsigned char *buffer, uint16_t len) {
net_state_flags &= ~NET_STATE_FLAG_CTS;
net_state_flags |= (NET_STATE_FLAG_INIT | NET_STATE_FLAG_XCHG);
@@ -127,7 +120,7 @@ static int net_xchg_next(unsigned char *_buffer) {
unsigned char type;
unsigned char *buffer = NULL;
uint16_t len;
- int ret = _buffer ? 1 : 0;
+ int do_release = _buffer ? 1 : 0;
eos_msgq_pop(&net_send_q, &type, &buffer, &len);
if (type) {
@@ -135,14 +128,14 @@ static int net_xchg_next(unsigned char *_buffer) {
} else if (net_state_flags & NET_STATE_FLAG_RTS) {
if (_buffer) {
buffer = _buffer;
- ret = 0;
+ do_release = 0;
} else {
buffer = eos_bufq_pop(&net_buf_q);
}
if (buffer) net_xchg_start(0, buffer, 0);
}
- return ret;
+ return do_release;
}
static void net_handle_xchg(void) {
@@ -162,7 +155,7 @@ static void net_handle_xchg(void) {
r3 = 0;
}
- net_state_type = (r1 & 0xFF);
+ net_state_type = (r1 & EOS_NET_MTYPE_MASK);
net_state_len_rx = (r2 & 0xFF) << 8;
net_state_len_rx |= (r3 & 0xFF);
len = MAX(net_state_len_tx, net_state_len_rx);
@@ -191,8 +184,18 @@ static void net_handle_xchg(void) {
if (SPI1_REG(SPI_REG_CSMODE) == SPI_CSMODE_AUTO) { // exchange done
if (!(net_state_flags & NET_STATE_FLAG_SYNC)) {
if (net_state_type) {
- int r = eos_evtq_push_isr(EOS_EVT_NET | (net_state_type & ~EOS_NET_MTYPE_FLAG_MASK), net_state_buf, net_state_len_rx);
- if (r) eos_bufq_push(&net_buf_q, net_state_buf);
+ if (net_state_type == EOS_NET_MTYPE_SLEEP) {
+ net_state_flags |= NET_STATE_FLAG_SLEEP;
+ eos_bufq_push(&net_buf_q, net_state_buf);
+ } else {
+ int rv;
+
+ rv = eos_evtq_push_isr(EOS_EVT_NET | (net_state_type & ~EOS_EVT_MASK), net_state_buf, net_state_len_rx);
+ if (rv) {
+ EOS_LOG(EOS_LOG_ERR, "NET XCHG EVTQ PUSH ERR:%d\n", rv);
+ eos_bufq_push(&net_buf_q, net_state_buf);
+ }
+ }
} else if (((net_state_flags & NET_STATE_FLAG_ONEW) || net_state_next_cnt) && (net_state_next_buf == NULL)) {
net_state_next_buf = net_state_buf;
} else {
@@ -204,8 +207,9 @@ static void net_handle_xchg(void) {
}
static void net_handle_cts(void) {
- GPIO_REG(GPIO_RISE_IP) = (1 << NET_PIN_CTS);
+ GPIO_REG(GPIO_FALL_IP) = (1 << NET_PIN_CTS);
net_state_flags |= NET_STATE_FLAG_CTS;
+ net_state_flags &= ~NET_STATE_FLAG_SLEEP;
if (net_state_flags & NET_STATE_FLAG_RUN) {
net_xchg_next(NULL);
@@ -215,23 +219,24 @@ static void net_handle_cts(void) {
static void net_handle_rts(void) {
uint32_t rts_offset = (1 << NET_PIN_RTS);
- if (GPIO_REG(GPIO_RISE_IP) & rts_offset) {
- GPIO_REG(GPIO_RISE_IP) = rts_offset;
+ if (GPIO_REG(GPIO_FALL_IP) & rts_offset) {
+ GPIO_REG(GPIO_FALL_IP) = rts_offset;
net_state_flags |= NET_STATE_FLAG_RTS;
if ((net_state_flags & NET_STATE_FLAG_RUN) && (net_state_flags & NET_STATE_FLAG_CTS)) {
net_xchg_reset();
}
- } else if (GPIO_REG(GPIO_FALL_IP) & rts_offset) {
- GPIO_REG(GPIO_FALL_IP) = rts_offset;
+ }
+ if (GPIO_REG(GPIO_RISE_IP) & rts_offset) {
+ GPIO_REG(GPIO_RISE_IP) = rts_offset;
net_state_flags &= ~NET_STATE_FLAG_RTS;
}
}
static void net_handle_evt(unsigned char type, unsigned char *buffer, uint16_t len) {
- unsigned char idx = (type & ~EOS_EVT_MASK) - 1;
+ unsigned char idx = (type & ~EOS_EVT_MASK);
- if (idx < EOS_NET_MAX_MTYPE) {
- net_handler[idx](type, buffer, len);
+ if (idx && (idx <= EOS_NET_MAX_MTYPE)) {
+ net_handler[idx - 1](type, buffer, len);
} else {
eos_net_bad_handler(type, buffer, len);
}
@@ -263,29 +268,35 @@ static int net_acquire(unsigned char reserved) {
return ret;
}
-static void evt_handler_wrapper(unsigned char type, unsigned char *buffer, uint16_t len, unsigned char idx, uint16_t flag) {
- int ok;
+static void evt_handler_wrapper(unsigned char type, unsigned char *buffer, uint16_t len, uint8_t idx) {
+ uint16_t flag = (uint16_t)1 << idx;
+ int rv;
- ok = net_acquire(net_wrapper_acq[idx] & flag);
- if (ok) {
+ rv = net_acquire(net_wrapper_acq & flag);
+ if (rv) {
eos_evtq_get_handler(type)(type, buffer, len);
eos_net_release();
- net_wrapper_acq[idx] &= ~flag;
+ net_wrapper_acq &= ~flag;
} else {
- net_wrapper_acq[idx] |= flag;
- eos_evtq_push(type, buffer, len);
+ rv = eos_evtq_push_widx(type, buffer, len, &idx);
+ if (rv) {
+ EOS_LOG(EOS_LOG_ERR, "NET WRAPPER EVTQ PUSH ERR:%d\n", rv);
+ return;
+ }
+ flag = (uint16_t)1 << idx;
+ net_wrapper_acq |= flag;
}
}
-static void evt_handler(unsigned char type, unsigned char *buffer, uint16_t len) {
+static void evt_handler(unsigned char type, unsigned char *buffer, uint16_t len, uint8_t _idx) {
unsigned char idx = (type & EOS_EVT_MASK) >> 4;
- if (idx && (idx <= EOS_EVT_MAX_EVT)) {
+ if (idx && (idx <= EOS_EVT_MAX)) {
uint16_t flag = (uint16_t)1 << (type & ~EOS_EVT_MASK);
idx--;
if (flag & net_flags_acq[idx]) {
- evt_handler_wrapper(type, buffer, len, idx, flag);
+ evt_handler_wrapper(type, buffer, len, _idx);
} else {
eos_evtq_get_handler(type)(type, buffer, len);
}
@@ -294,6 +305,14 @@ static void evt_handler(unsigned char type, unsigned char *buffer, uint16_t len)
}
}
+static void net_flushq(void) {
+ while (eos_msgq_len(&net_send_q)) {
+ asm volatile ("wfi");
+ set_csr(mstatus, MSTATUS_MIE);
+ clear_csr(mstatus, MSTATUS_MIE);
+ }
+}
+
static void net_wait4xchg(void) {
while (net_state_flags & NET_STATE_FLAG_XCHG) {
asm volatile ("wfi");
@@ -310,12 +329,47 @@ static void net_wait4cts(void) {
}
}
+static void net_wake(void) {
+ while (net_state_flags & NET_STATE_FLAG_SLEEP) {
+ net_xchg_reset();
+ eos_sleep(10);
+ set_csr(mstatus, MSTATUS_MIE);
+ clear_csr(mstatus, MSTATUS_MIE);
+ }
+}
+
+static int net_select(int *dsel) {
+ *dsel = 0;
+ if (net_state_flags & NET_STATE_FLAG_ABSENT) return EOS_ERR_NOTFOUND;
+ if (net_state_flags & NET_STATE_FLAG_SLEEP_REQ) return EOS_ERR_BUSY;
+
+ if (!(net_state_flags & NET_STATE_FLAG_RUN)) {
+ int rv;
+
+ set_csr(mstatus, MSTATUS_MIE);
+ rv = eos_spi_select(EOS_SPI_DEV_NET);
+ clear_csr(mstatus, MSTATUS_MIE);
+ if (rv) return rv;
+ *dsel = 1;
+ }
+ /* wake up remote if sleeping */
+ net_wake();
+
+ return EOS_OK;
+}
+
+static void net_deselect(void) {
+ eos_spi_deselect();
+}
+
static void net_pause(void) {
net_state_flags &= ~NET_STATE_FLAG_RUN;
net_wait4xchg();
}
static void net_resume(void) {
+ if (net_state_flags & NET_STATE_FLAG_ABSENT) return;
+
net_state_flags |= NET_STATE_FLAG_RUN;
if (net_state_flags & NET_STATE_FLAG_CTS) {
net_xchg_next(NULL);
@@ -331,7 +385,7 @@ static void net_stop(void) {
eos_intr_set_handler(INT_SPI1_BASE, NULL);
}
-int eos_net_init(uint8_t wakeup_cause) {
+int eos_net_init(void) {
int i;
eos_msgq_init(&net_send_q, net_sndq_array, EOS_NET_SIZE_BUFQ);
@@ -343,47 +397,69 @@ int eos_net_init(uint8_t wakeup_cause) {
for (i=0; i<EOS_NET_MAX_MTYPE; i++) {
net_handler[i] = eos_net_bad_handler;
}
- eos_evtq_set_handler(0, evt_handler);
+ eos_evtq_set_handler_global(evt_handler);
eos_evtq_set_handler(EOS_EVT_NET, net_handle_evt);
+ GPIO_REG(GPIO_PULLUP_EN) |= (1 << NET_PIN_CTS);
GPIO_REG(GPIO_INPUT_EN) |= (1 << NET_PIN_CTS);
- GPIO_REG(GPIO_RISE_IE) |= (1 << NET_PIN_CTS);
+ GPIO_REG(GPIO_FALL_IE) |= (1 << NET_PIN_CTS);
eos_intr_set(INT_GPIO_BASE + NET_PIN_CTS, IRQ_PRIORITY_NET_CTS, net_handle_cts);
+ /* XXX: pull-up not needed for new board */
+ GPIO_REG(GPIO_PULLUP_EN) |= (1 << NET_PIN_RTS);
GPIO_REG(GPIO_INPUT_EN) |= (1 << NET_PIN_RTS);
GPIO_REG(GPIO_RISE_IE) |= (1 << NET_PIN_RTS);
GPIO_REG(GPIO_FALL_IE) |= (1 << NET_PIN_RTS);
eos_intr_set(INT_GPIO_BASE + NET_PIN_RTS, IRQ_PRIORITY_NET_RTS, net_handle_rts);
- /* set initial state */
- clear_csr(mstatus, MSTATUS_MIE);
- if (GPIO_REG(GPIO_INPUT_VAL) & (1 << NET_PIN_CTS)) net_state_flags |= NET_STATE_FLAG_CTS;
- if (GPIO_REG(GPIO_INPUT_VAL) & (1 << NET_PIN_RTS)) net_state_flags |= NET_STATE_FLAG_RTS;
- set_csr(mstatus, MSTATUS_MIE);
-
return EOS_OK;
}
-int eos_net_run(uint8_t wakeup_cause) {
+int eos_net_run(void) {
+ uint8_t wakeup_cause;
+ int rv;
+
+ rv = EOS_OK;
net_start();
+ wakeup_cause = eos_pwr_wakeup_cause();
+
clear_csr(mstatus, MSTATUS_MIE);
- if (wakeup_cause != EOS_PWR_WAKE_RST) {
- if (wakeup_cause != EOS_PWR_WAKE_BTN) {
- net_xchg_wake();
- }
- if (!(net_state_flags & NET_STATE_FLAG_CTS)) {
- while (!(GPIO_REG(GPIO_RISE_IP) & (1 << NET_PIN_CTS))) {
- asm volatile ("wfi");
+ if (wakeup_cause == EOS_PWR_WAKE_RST) {
+ uint32_t start, timeout;
+
+ start = eos_get_tick();
+ timeout = NET_DETECT_TIMEOUT;
+ while (GPIO_REG(GPIO_INPUT_VAL) & (1 << NET_PIN_CTS)) {
+ if (timeout && (eos_tdelta_ms(start) > timeout)) {
+ rv = EOS_ERR_NOTFOUND;
+ break;
}
- GPIO_REG(GPIO_RISE_IP) = (1 << NET_PIN_CTS);
}
- net_xchg_reset();
+ if (!rv) {
+ GPIO_REG(GPIO_PULLUP_EN) &= ~(1 << NET_PIN_CTS);
+ } else {
+ net_state_flags |= NET_STATE_FLAG_ABSENT;
+ EOS_LOG(EOS_LOG_ERR, "NET DEVICE ABSENT\n");
+ }
+ } else {
+ if (eos_aon_load4net()) {
+ /* device previously declared as absent */
+ net_state_flags |= NET_STATE_FLAG_ABSENT;
+ } else if (!(net_state_flags & NET_STATE_FLAG_CTS)) {
+ /* will assume that remote device is sleeping */
+ net_state_flags |= NET_STATE_FLAG_SLEEP;
+ }
+ }
+ if (!rv) {
+ /* set initial state */
+ if (!(GPIO_REG(GPIO_INPUT_VAL) & (1 << NET_PIN_CTS))) net_state_flags |= NET_STATE_FLAG_CTS;
+ if (!(GPIO_REG(GPIO_INPUT_VAL) & (1 << NET_PIN_RTS))) net_state_flags |= NET_STATE_FLAG_RTS;
+ net_resume();
}
- net_resume();
set_csr(mstatus, MSTATUS_MIE);
- return EOS_OK;
+ return rv;
}
void eos_net_start(void) {
@@ -402,47 +478,51 @@ void eos_net_stop(void) {
net_stop();
}
-int eos_net_sleep(uint32_t timeout) {
- uint32_t start;
- uint8_t done = 0;
- int rv = EOS_OK;
+int eos_net_sleep(void) {
+ int dsel = 0;
+ int rv;
clear_csr(mstatus, MSTATUS_MIE);
- if (!(net_state_flags & NET_STATE_FLAG_RUN)) rv = EOS_ERR;
+ rv = net_select(&dsel);
+ if (rv) {
+ set_csr(mstatus, MSTATUS_MIE);
+ return rv;
+ }
+ net_state_flags |= NET_STATE_FLAG_SLEEP_REQ;
+ net_flushq();
+ net_pause();
+ net_wait4cts();
+ net_xchg_sleep_req();
+ net_resume();
set_csr(mstatus, MSTATUS_MIE);
+ if (dsel) net_deselect();
- if (rv) return rv;
+ return EOS_OK;
+}
- start = eos_time_get_tick();
- do {
- if (eos_time_delta_ms(start) > timeout) return EOS_ERR_TIMEOUT;
- clear_csr(mstatus, MSTATUS_MIE);
- eos_evtq_flush_isr();
- done = (eos_msgq_len(&net_send_q) == 0);
- done = done && (!(net_state_flags & NET_STATE_FLAG_RTS) && (net_state_flags & NET_STATE_FLAG_CTS));
- if (done) done = (net_xchg_sleep() == EOS_OK);
- if (!done) {
- asm volatile ("wfi");
- set_csr(mstatus, MSTATUS_MIE);
- }
- } while (!done);
+int eos_net_sleep_rdy(void) {
+ int rv;
- while (!(GPIO_REG(GPIO_RISE_IP) & (1 << NET_PIN_CTS))) {
- if (eos_time_delta_ms(start) > timeout) {
- rv = EOS_ERR_TIMEOUT;
- break;
- }
- asm volatile ("wfi");
- }
+ clear_csr(mstatus, MSTATUS_MIE);
+ rv = !!(net_state_flags & NET_STATE_FLAG_SLEEP);
+ set_csr(mstatus, MSTATUS_MIE);
- if (!rv) {
- GPIO_REG(GPIO_RISE_IP) = (1 << NET_PIN_CTS);
- net_state_flags &= ~NET_STATE_FLAG_RUN;
- }
+ return rv;
+}
+void eos_net_wake(void) {
+ clear_csr(mstatus, MSTATUS_MIE);
+ net_state_flags &= ~NET_STATE_FLAG_SLEEP_REQ;
set_csr(mstatus, MSTATUS_MIE);
+}
- return rv;
+void eos_net_save2aon(void) {
+ int absent;
+
+ clear_csr(mstatus, MSTATUS_MIE);
+ absent = !!(net_state_flags & NET_STATE_FLAG_ABSENT);
+ set_csr(mstatus, MSTATUS_MIE);
+ eos_aon_save4net(absent);
}
void eos_net_bad_handler(unsigned char type, unsigned char *buffer, uint16_t len) {
@@ -459,7 +539,7 @@ void eos_net_acquire_for_evt(unsigned char type, char acq) {
unsigned char idx = (type & EOS_EVT_MASK) >> 4;
uint16_t flag = type & ~EOS_EVT_MASK ? (uint16_t)1 << (type & ~EOS_EVT_MASK) : 0xFFFF;
- if (idx && (idx <= EOS_EVT_MAX_EVT)) {
+ if (idx && (idx <= EOS_EVT_MAX)) {
idx--;
net_flags_acq[idx] &= ~flag;
if (acq) net_flags_acq[idx] |= flag;
@@ -481,12 +561,12 @@ void eos_net_release(void) {
}
unsigned char *eos_net_alloc(void) {
- unsigned char *ret = NULL;
+ unsigned char *rv = NULL;
- while (ret == NULL) {
+ while (rv == NULL) {
clear_csr(mstatus, MSTATUS_MIE);
if (net_state_next_buf) {
- ret = net_state_next_buf;
+ rv = net_state_next_buf;
net_state_next_buf = NULL;
} else {
asm volatile ("wfi");
@@ -494,7 +574,7 @@ unsigned char *eos_net_alloc(void) {
set_csr(mstatus, MSTATUS_MIE);
}
- return ret;
+ return rv;
}
void eos_net_free(unsigned char *buffer, unsigned char more) {
@@ -516,81 +596,72 @@ void eos_net_free(unsigned char *buffer, unsigned char more) {
static int net_xchg(unsigned char *type, unsigned char *buffer, uint16_t *len, unsigned char flags) {
int rv = EOS_OK;
- int _sync = 0;
- unsigned char _type = *type;
+ int sync = 0, dsel = 0;
+ unsigned char _type = *type & EOS_NET_MTYPE_MASK;
uint16_t _len = *len;
- uint8_t spi_dev = EOS_SPI_DEV_NET;
- if (flags & EOS_NET_FLAG_ONEW) _type |= EOS_NET_MTYPE_FLAG_ONEW;
- if (flags & EOS_NET_FLAG_REPL) _type |= EOS_NET_MTYPE_FLAG_REPL;
- if (flags & EOS_NET_FLAG_SYNC) _sync = 1;
+ if (flags & NET_FLAG_MORE) _type |= EOS_NET_MTYPE_FLAG_ONEW;
+ if (flags & NET_FLAG_REPL) _type |= EOS_NET_MTYPE_FLAG_REPL;
+ if (flags & NET_FLAG_SYNC) sync = 1;
clear_csr(mstatus, MSTATUS_MIE);
- if ((flags & EOS_NET_FLAG_ONEW) && !(net_state_flags & NET_STATE_FLAG_RUN)) _sync = 1;
-
- if (_sync && !(net_state_flags & NET_STATE_FLAG_RUN)) {
- int _rv;
-
+ rv = net_select(&dsel);
+ if (rv) {
set_csr(mstatus, MSTATUS_MIE);
- spi_dev = eos_spi_dev();
- _rv = eos_spi_deselect();
- if (_rv) return _rv;
- clear_csr(mstatus, MSTATUS_MIE);
+ return rv;
}
- if (_sync) {
+ if (dsel) sync = 1;
+ if (sync) {
+ _type |= EOS_NET_MTYPE_FLAG_ONEW;
net_pause();
net_wait4cts();
- if (flags & EOS_NET_FLAG_SYNC) {
- net_state_flags |= NET_STATE_FLAG_SYNC;
- }
+ net_state_flags |= NET_STATE_FLAG_SYNC;
net_xchg_start(_type, buffer, _len);
- if (flags & EOS_NET_FLAG_SYNC) {
- if (flags & EOS_NET_FLAG_REPL) {
- net_wait4cts();
- net_xchg_start(0, buffer, 0);
- }
- net_wait4xchg();
- net_state_flags &= ~NET_STATE_FLAG_SYNC;
- *type = (net_state_type & ~EOS_NET_MTYPE_FLAG_MASK);
- *len = net_state_len_rx;
+ if (flags & NET_FLAG_REPL) {
+ net_wait4cts();
+ net_xchg_start(0, buffer, 0);
}
+ net_wait4xchg();
+ net_state_flags &= ~NET_STATE_FLAG_SYNC;
+ *type = net_state_type & EOS_NET_MTYPE_MASK;
+ *len = net_state_len_rx;
net_resume();
} else {
if ((net_state_flags & NET_STATE_FLAG_RUN) && (net_state_flags & NET_STATE_FLAG_CTS)) {
net_xchg_start(_type, buffer, _len);
} else {
rv = eos_msgq_push(&net_send_q, _type, buffer, _len);
- if (rv) eos_bufq_push(&net_buf_q, buffer);
}
}
set_csr(mstatus, MSTATUS_MIE);
- if (spi_dev != EOS_SPI_DEV_NET) eos_spi_select(spi_dev);
+ if (sync && !(flags & NET_FLAG_SYNC)) eos_net_free(buffer, !!(flags & NET_FLAG_MORE));
+ if (dsel) net_deselect();
return rv;
}
-int eos_net_xchg(unsigned char *type, unsigned char *buffer, uint16_t *len) {
- return net_xchg(type, buffer, len, (EOS_NET_FLAG_ONEW | EOS_NET_FLAG_SYNC | EOS_NET_FLAG_REPL));
-}
-
-int eos_net_send(unsigned char type, unsigned char *buffer, uint16_t len) {
- return net_xchg(&type, buffer, &len, (EOS_NET_FLAG_ONEW | EOS_NET_FLAG_SYNC));
-}
-
-int eos_net_send_async(unsigned char type, unsigned char *buffer, uint16_t len, unsigned char more) {
+int eos_net_send(unsigned char type, unsigned char *buffer, uint16_t len, unsigned char more) {
int rv;
- rv = net_xchg(&type, buffer, &len, more ? EOS_NET_FLAG_ONEW : 0);
+ rv = net_xchg(&type, buffer, &len, more ? NET_FLAG_MORE : 0);
if (rv) eos_net_free(buffer, more);
return rv;
}
+int eos_net_send_sync(unsigned char type, unsigned char *buffer, uint16_t len) {
+ return net_xchg(&type, buffer, &len, NET_FLAG_SYNC);
+}
+
+int eos_net_xchg(unsigned char *type, unsigned char *buffer, uint16_t *len) {
+ return net_xchg(type, buffer, len, (NET_FLAG_SYNC | NET_FLAG_REPL));
+}
+
int _eos_net_send(unsigned char type, unsigned char *buffer, uint16_t len, unsigned char async, unsigned char more) {
if (async) {
- return eos_net_send_async(type, buffer, len, more);
+ return eos_net_send(type, buffer, len, more);
} else {
- return eos_net_send(type, buffer, len);
+ return eos_net_send_sync(type, buffer, len);
}
}
diff --git a/fw/fe310/eos/dev/net.h b/fw/fe310/eos/dev/net.h
index 2482a32..12b4d14 100644
--- a/fw/fe310/eos/dev/net.h
+++ b/fw/fe310/eos/dev/net.h
@@ -1,4 +1,5 @@
#include <stdint.h>
+
#include "../event.h"
/* common */
@@ -6,32 +7,30 @@
#define EOS_NET_SIZE_BUF EOS_NET_MTU
#define EOS_NET_MTYPE_SOCK 1
-#define EOS_NET_MTYPE_RNG 3
-#define EOS_NET_MTYPE_POWER 4
+#define EOS_NET_MTYPE_WIFI 2
+#define EOS_NET_MTYPE_CELL 3
+#define EOS_NET_MTYPE_APP 4
+#define EOS_NET_MTYPE_RNG 5
-#define EOS_NET_MTYPE_WIFI 5
-#define EOS_NET_MTYPE_CELL 6
-#define EOS_NET_MTYPE_SIP 7
-#define EOS_NET_MTYPE_APP 8
+#define EOS_NET_MAX_MTYPE 5
-#define EOS_NET_MAX_MTYPE 8
+#define EOS_NET_MTYPE_SLEEP 0x10 /* does not have net handler */
#define EOS_NET_MTYPE_FLAG_ONEW 0x40
#define EOS_NET_MTYPE_FLAG_REPL 0x80
-#define EOS_NET_MTYPE_FLAG_MASK 0xc0
+#define EOS_NET_MTYPE_MASK 0x3F /* 0x0F if mtype is handled by evtq */
/* fe310 specific */
#define EOS_NET_SIZE_BUFQ 2
-#define EOS_NET_FLAG_ONEW 0x1
-#define EOS_NET_FLAG_SYNC 0x2
-#define EOS_NET_FLAG_REPL 0x4
-
-int eos_net_init(uint8_t wakeup_cause);
-int eos_net_run(uint8_t wakeup_cause);
+int eos_net_init(void);
+int eos_net_run(void);
void eos_net_start(void);
void eos_net_stop(void);
-int eos_net_sleep(uint32_t timeout);
+int eos_net_sleep(void);
+int eos_net_sleep_rdy(void);
+void eos_net_wake(void);
+void eos_net_save2aon(void);
void eos_net_bad_handler(unsigned char type, unsigned char *buffer, uint16_t len);
void eos_net_set_handler(unsigned char type, eos_evt_handler_t handler);
@@ -41,7 +40,7 @@ void eos_net_acquire(void);
void eos_net_release(void);
unsigned char *eos_net_alloc(void);
void eos_net_free(unsigned char *buffer, unsigned char more);
+int eos_net_send(unsigned char type, unsigned char *buffer, uint16_t len, unsigned char more);
+int eos_net_send_sync(unsigned char type, unsigned char *buffer, uint16_t len);
int eos_net_xchg(unsigned char *type, unsigned char *buffer, uint16_t *len);
-int eos_net_send(unsigned char type, unsigned char *buffer, uint16_t len);
-int eos_net_send_async(unsigned char type, unsigned char *buffer, uint16_t len, unsigned char more);
int _eos_net_send(unsigned char type, unsigned char *buffer, uint16_t len, unsigned char async, unsigned char more);
diff --git a/fw/fe310/eos/dev/pwr.c b/fw/fe310/eos/dev/pwr.c
new file mode 100644
index 0000000..06a76d8
--- /dev/null
+++ b/fw/fe310/eos/dev/pwr.c
@@ -0,0 +1,49 @@
+#include <stdlib.h>
+#include <stdint.h>
+
+#include "eos.h"
+#include "log.h"
+#include "event.h"
+#include "soc/pwr.h"
+#include "eve/eve.h"
+#include "eve/eve_touch_engine.h"
+
+#include "eve.h"
+#include "lcd.h"
+#include "ctp.h"
+#include "net.h"
+#include "flash.h"
+#include "aon.h"
+
+#include "pwr.h"
+
+static void pwr_sleep_rdy(void) {
+ if ((eos_evtq_len() == 0) && eos_net_sleep_rdy()) {
+ eos_eve_save2aon();
+ eos_net_save2aon();
+ eos_flash_norm();
+#ifdef EOS_DEBUG
+ EOS_LOG(EOS_LOG_INFO, "PWR SLEEP\n");
+ eos_sleep(100);
+#endif
+ eos_pwr_sleep();
+ }
+}
+
+void eos_pwr_sys_sleep(void) {
+ int rv;
+
+ rv = eos_lcd_sleep();
+ if (rv) EOS_LOG(EOS_LOG_ERR, "PWR SLEEP: LCD SLEEP ERR:%d\n", rv);
+
+ rv = eos_ctp_sleep();
+ if (rv) EOS_LOG(EOS_LOG_ERR, "PWR SLEEP: CTP SLEEP ERR:%d\n", rv);
+
+ rv = eos_eve_sleep();
+ if (rv) EOS_LOG(EOS_LOG_ERR, "PWR SLEEP: EVE SLEEP ERR:%d\n", rv);
+
+ eos_evtq_set_loopf(pwr_sleep_rdy);
+
+ rv = eos_net_sleep();
+ if (rv) EOS_LOG(EOS_LOG_ERR, "PWR SLEEP: NET SLEEP REQ ERR:%d\n", rv);
+}
diff --git a/fw/fe310/eos/dev/pwr.h b/fw/fe310/eos/dev/pwr.h
new file mode 100644
index 0000000..d3125f4
--- /dev/null
+++ b/fw/fe310/eos/dev/pwr.h
@@ -0,0 +1 @@
+void eos_pwr_sys_sleep(void);
diff --git a/fw/fe310/eos/dev/sdc_crypto.c b/fw/fe310/eos/dev/sdc_crypto.c
index f0e935d..0cb7a78 100644
--- a/fw/fe310/eos/dev/sdc_crypto.c
+++ b/fw/fe310/eos/dev/sdc_crypto.c
@@ -9,9 +9,9 @@
#define SDC_CRYPTO_BLK_SIZE 16
#define SDC_CRYPTO_HASH_SIZE 20
-EOSSDCCrypto *sdc_crypto;
+static EOSSDCCrypto *sdc_crypto;
-void eos_sdcc_init(EOSSDCCrypto *crypto, uint8_t *key, void *ctx, eve_sdcc_init_t init, eve_sdcc_crypt_t enc, eve_sdcc_crypt_t dec, void *ctx_essiv, eve_sdcc_init_t init_essiv, eve_sdcc_essiv_t enc_essiv) {
+void eos_sdcc_init(EOSSDCCrypto *crypto, uint8_t *key, void *ctx, eos_sdcc_init_t init, eos_sdcc_crypt_t enc, eos_sdcc_crypt_t dec, void *ctx_essiv, eos_sdcc_init_t init_essiv, eos_sdcc_essiv_t enc_essiv) {
char key_essiv[SDC_CRYPTO_HASH_SIZE];
sdc_crypto = crypto;
@@ -28,7 +28,7 @@ void eos_sdcc_init(EOSSDCCrypto *crypto, uint8_t *key, void *ctx, eve_sdcc_init_
sdc_crypto->enc_essiv = enc_essiv;
}
-void eos_sdcc_encrypt(uint32_t sect, uint8_t *buffer) {
+void eos_sdc_encrypt(uint32_t sect, uint8_t *buffer) {
uint8_t iv[SDC_CRYPTO_BLK_SIZE];
if (sdc_crypto == NULL) return;
@@ -39,7 +39,7 @@ void eos_sdcc_encrypt(uint32_t sect, uint8_t *buffer) {
sdc_crypto->enc(sdc_crypto->ctx, iv, buffer, 512);
}
-void eos_sdcc_decrypt(uint32_t sect, uint8_t *buffer) {
+void eos_sdc_decrypt(uint32_t sect, uint8_t *buffer) {
uint8_t iv[SDC_CRYPTO_BLK_SIZE];
if (sdc_crypto == NULL) return;
diff --git a/fw/fe310/eos/dev/sdc_crypto.h b/fw/fe310/eos/dev/sdc_crypto.h
index 6442547..176483a 100644
--- a/fw/fe310/eos/dev/sdc_crypto.h
+++ b/fw/fe310/eos/dev/sdc_crypto.h
@@ -1,18 +1,18 @@
#include <stddef.h>
#include <stdint.h>
-typedef void (*eve_sdcc_init_t) (void *, uint8_t *);
-typedef void (*eve_sdcc_crypt_t) (void *, uint8_t *, uint8_t *, size_t);
-typedef void (*eve_sdcc_essiv_t) (void *, uint8_t *);
+typedef void (*eos_sdcc_init_t) (void *, uint8_t *);
+typedef void (*eos_sdcc_crypt_t) (void *, uint8_t *, uint8_t *, size_t);
+typedef void (*eos_sdcc_essiv_t) (void *, uint8_t *);
typedef struct EOSSDCCrypto {
void *ctx;
- eve_sdcc_crypt_t enc;
- eve_sdcc_crypt_t dec;
+ eos_sdcc_crypt_t enc;
+ eos_sdcc_crypt_t dec;
void *ctx_essiv;
- eve_sdcc_essiv_t enc_essiv;
+ eos_sdcc_essiv_t enc_essiv;
} EOSSDCCrypto;
-void eos_sdcc_init(EOSSDCCrypto *crypto, uint8_t *key, void *ctx, eve_sdcc_init_t init, eve_sdcc_crypt_t enc, eve_sdcc_crypt_t dec, void *ctx_essiv, eve_sdcc_init_t init_essiv, eve_sdcc_essiv_t enc_essiv);
-void eos_sdcc_encrypt(uint32_t sect, uint8_t *buffer);
-void eos_sdcc_decrypt(uint32_t sect, uint8_t *buffer);
+void eos_sdcc_init(EOSSDCCrypto *crypto, uint8_t *key, void *ctx, eos_sdcc_init_t init, eos_sdcc_crypt_t enc, eos_sdcc_crypt_t dec, void *ctx_essiv, eos_sdcc_init_t init_essiv, eos_sdcc_essiv_t enc_essiv);
+void eos_sdc_encrypt(uint32_t sect, uint8_t *buffer);
+void eos_sdc_decrypt(uint32_t sect, uint8_t *buffer);
diff --git a/fw/fe310/eos/dev/sdcard.c b/fw/fe310/eos/dev/sdcard.c
new file mode 100644
index 0000000..ebdc883
--- /dev/null
+++ b/fw/fe310/eos/dev/sdcard.c
@@ -0,0 +1,48 @@
+#include <stdlib.h>
+#include <stdint.h>
+
+#include "encoding.h"
+#include "platform.h"
+#include "board.h"
+
+#include "eos.h"
+
+#include "spi.h"
+
+#include "drv/sdcard.h"
+#include "sdcard.h"
+
+#define SDC_DETECT_TIMEOUT 1000
+
+int eos_sdc_init(void) {
+ clear_csr(mstatus, MSTATUS_MIE);
+ GPIO_REG(GPIO_OUTPUT_VAL) |= (1 << SPI_CSPIN_SDC);
+ set_csr(mstatus, MSTATUS_MIE);
+ GPIO_REG(GPIO_OUTPUT_EN) |= (1 << SPI_CSPIN_SDC);
+
+ return EOS_OK;
+}
+
+int eos_sdc_insert(int sdc_det, uint32_t timeout) {
+ if (timeout == 0) timeout = SDC_DETECT_TIMEOUT;
+ if (sdc_det) {
+ int rv;
+
+ eos_spi_set_div(EOS_SPI_DEV_SDC, 1024); // 100 - 400 kHz
+
+ rv = eos_spi_select(EOS_SPI_DEV_SDC);
+ if (rv) goto sdc_insert_fin;
+
+ rv = sdc_init(timeout);
+ if (rv) rv = EOS_ERR_NOTFOUND;
+ eos_spi_deselect();
+
+sdc_insert_fin:
+ eos_spi_set_div(EOS_SPI_DEV_SDC, SPI_DIV_SDC);
+ if (rv) return rv;
+ } else {
+ sdc_clear();
+ }
+
+ return EOS_OK;
+}
diff --git a/fw/fe310/eos/dev/sdcard.h b/fw/fe310/eos/dev/sdcard.h
new file mode 100644
index 0000000..4b338ea
--- /dev/null
+++ b/fw/fe310/eos/dev/sdcard.h
@@ -0,0 +1,4 @@
+#include <stdint.h>
+
+int eos_sdc_init(void);
+int eos_sdc_insert(int sdc_det, uint32_t timeout);
diff --git a/fw/fe310/eos/dev/spi.c b/fw/fe310/eos/dev/spi.c
index fef00e1..319816d 100644
--- a/fw/fe310/eos/dev/spi.c
+++ b/fw/fe310/eos/dev/spi.c
@@ -5,6 +5,7 @@
#include "platform.h"
#include "eos.h"
+#include "log.h"
#include "msgq.h"
#include "event.h"
@@ -13,33 +14,36 @@
#include "soc/interrupt.h"
#include "soc/spi.h"
#include "soc/spi_priv.h"
+#include "soc/spi9bit.h"
#include "net.h"
#include "egpio.h"
+#include "egpio_priv.h"
#include "spi.h"
#include "spi_cfg.h"
-#ifdef EOS_DEBUG
-#include <stdio.h>
-#endif
-
static unsigned char spi_dstack[EOS_SPI_MAX_DSTACK];
static unsigned char spi_dstack_len;
-static uint16_t spi_div[EOS_SPI_MAX_DEV];
+static uint16_t spi_div[SPI_MAX_DEV];
static uint8_t spi_dev(void) {
return spi_dstack_len ? spi_dstack[spi_dstack_len - 1] : EOS_SPI_DEV_NET;
}
-static void spi_stop(unsigned char dev) {
+static int spi_stop(unsigned char dev) {
if (dev == EOS_SPI_DEV_NET) {
eos_net_stop();
- } else if (spi_cfg[dev].flags & SPI_DEV_FLAG_9BIT) {
- eos_spi_enable();
} else {
- eos_spi_stop();
+ if (eos_spi_get_cs()) return EOS_ERR_BUSY;
+ if (spi_cfg[dev].flags & SPI_DEV_FLAG_9BIT) {
+ eos_spi9bit_stop();
+ eos_spi_enable();
+ } else {
+ eos_spi_stop();
+ }
}
+ return EOS_OK;
}
static void spi_start(unsigned char dev) {
@@ -48,6 +52,7 @@ static void spi_start(unsigned char dev) {
} else if (spi_cfg[dev].flags & SPI_DEV_FLAG_9BIT) {
eos_spi_configure(spi_div[dev], spi_cfg[dev].csid, spi_cfg[dev].cspin, spi_cfg[dev].evt);
eos_spi_disable();
+ eos_spi9bit_start();
} else {
eos_spi_start(spi_div[dev], spi_cfg[dev].csid, spi_cfg[dev].cspin, spi_cfg[dev].evt);
}
@@ -56,7 +61,8 @@ static void spi_start(unsigned char dev) {
int eos_spi_dev_init(void) {
int i;
- for (i=0; i<EOS_SPI_MAX_DEV; i++) {
+ /* dev modules are responsibile for configuring cs gpio */
+ for (i=0; i<SPI_MAX_DEV; i++) {
spi_div[i] = spi_cfg[i].div;
}
@@ -71,14 +77,10 @@ int eos_spi_select(unsigned char dev) {
int rv;
int dsel;
- if (eos_spi_cs_get()) rv = EOS_ERR_BUSY;
- if (!rv && (spi_dstack_len == EOS_SPI_MAX_DSTACK)) rv = EOS_ERR_FULL;
-
- if (rv) {
-#ifdef EOS_DEBUG
- printf("SPI SELECT DEV:%d ERR:%d\n", dev, rv);
-#endif
- return rv;
+ rv = EOS_OK;
+ if (spi_dstack_len == EOS_SPI_MAX_DSTACK) {
+ rv = EOS_ERR_FULL;
+ goto spi_select_fin;
}
dsel = 1;
@@ -87,13 +89,21 @@ int eos_spi_select(unsigned char dev) {
dsel = 0;
}
- if (dsel) spi_stop(spi_dev());
+ if (dsel) {
+ rv = spi_stop(spi_dev());
+ if (rv) goto spi_select_fin;
+ }
spi_dstack[spi_dstack_len] = dev;
spi_dstack_len++;
if (dsel) spi_start(dev);
+spi_select_fin:
+ if (rv) {
+ EOS_LOG(EOS_LOG_ERR, "SPI SELECT DEV:%d ERR:%d\n", dev, rv);
+ return rv;
+ }
return EOS_OK;
}
@@ -101,23 +111,25 @@ void eos_spi_deselect(void) {
int rv;
int dsel;
- if (eos_spi_cs_get()) rv = EOS_ERR_BUSY;
- if (!rv && (spi_dstack_len == 0)) rv = EOS_ERR_EMPTY;
-
- if (rv) {
-#ifdef EOS_DEBUG
- printf("SPI DESELECT ERR:%d\n", rv);
-#endif
- return;
+ rv = EOS_OK;
+ if (spi_dstack_len == 0) {
+ rv = EOS_ERR_EMPTY;
+ goto spi_deselect_fin;
}
dsel = !(spi_dev() & EOS_SPI_DEV_FLAG_NDSEL);
- if (dsel) spi_stop(spi_dev());
+ if (dsel) {
+ rv = spi_stop(spi_dev());
+ if (rv) goto spi_deselect_fin;
+ }
spi_dstack_len--;
spi_dstack[spi_dstack_len] = 0xff;
if (dsel) spi_start(spi_dev());
+
+spi_deselect_fin:
+ if (rv) EOS_LOG(EOS_LOG_ERR, "SPI DESELECT ERR:%d\n", rv);
}
void eos_spi_dev_configure(unsigned char dev) {
diff --git a/fw/fe310/eos/dev/spi_cfg.h b/fw/fe310/eos/dev/spi_cfg.h
index 6ef92aa..0320aa6 100644
--- a/fw/fe310/eos/dev/spi_cfg.h
+++ b/fw/fe310/eos/dev/spi_cfg.h
@@ -10,9 +10,9 @@ typedef struct {
#define SPI_DEV_FLAG_9BIT 0x01
-#define EOS_SPI_MAX_DEV 6
+#define SPI_MAX_DEV 6
-static const SPIConfig spi_cfg[EOS_SPI_MAX_DEV] = {
+static const SPIConfig spi_cfg[SPI_MAX_DEV] = {
{ // DEV_NET
.div = SPI_DIV_NET,
.csid = SPI_CSID_NET,
diff --git a/fw/fe310/eos/eos.c b/fw/fe310/eos/eos.c
index 6df8700..73ab29c 100644
--- a/fw/fe310/eos/eos.c
+++ b/fw/fe310/eos/eos.c
@@ -3,10 +3,12 @@
#include "encoding.h"
#include "platform.h"
#include "prci_driver.h"
+#include "board.h"
#include "event.h"
#include "soc/interrupt.h"
#include "soc/timer.h"
+#include "soc/aon.h"
#include "soc/pwr.h"
#include "soc/i2s.h"
#include "soc/i2c.h"
@@ -16,18 +18,20 @@
#include "dev/flash.h"
#include "dev/spi.h"
#include "dev/net.h"
+#include "dev/egpio.h"
+#include "dev/egpio_priv.h"
#include "dev/lcd.h"
+#include "dev/ctp.h"
#include "dev/sdcard.h"
-#include "dev/gt911.h"
-#include "dev/bq25895.h"
+#include "dev/batt.h"
#include "dev/eve.h"
-#include "net/pwr.h"
#include "net/wifi.h"
#include "net/sock.h"
#include "net/cell.h"
#include "eos.h"
+#include "log.h"
uint8_t eos_init(void) {
uint8_t wakeup_cause;
@@ -36,65 +40,94 @@ uint8_t eos_init(void) {
PRCI_use_default_clocks();
PRCI_use_pll(PLL_REFSEL_HFXOSC, 0, 1, 31, 1, -1, -1, -1);
+ /* enable printf */
+ eos_uart_preinit();
+ /* set flash driver */
eos_flash_init();
wakeup_cause = eos_pwr_wakeup_cause();
- eos_evtq_init(wakeup_cause);
- eos_intr_init(wakeup_cause);
- eos_timer_init(wakeup_cause);
- eos_uart_init(wakeup_cause);
+ EOS_LOG(EOS_LOG_INFO, "INIT:%d\n", wakeup_cause);
+ EOS_LOG(EOS_LOG_INFO, "FREQ:%lu\n", PRCI_get_cpu_freq());
- printf("INIT:%d\n", wakeup_cause);
+ rv = eos_evtq_init();
+ if (rv) EOS_LOG(EOS_LOG_ERR, "EVTQ INIT ERR:%d\n", rv);
+ rv = eos_intr_init();
+ if (rv) EOS_LOG(EOS_LOG_ERR, "INTR INIT ERR:%d\n", rv);
+ rv = eos_timer_init();
+ if (rv) EOS_LOG(EOS_LOG_ERR, "TIMER INIT ERR:%d\n", rv);
- rv = eos_pwr_init(wakeup_cause);
- if (rv) printf("PWR INIT ERR:%d\n", rv);
- rv = eos_i2s_init(wakeup_cause);
- if (rv) printf("I2S INIT ERR:%d\n", rv);
- rv = eos_i2c_init(wakeup_cause);
- if (rv) printf("I2C INIT ERR:%d\n", rv);
- rv = eos_spi_init(wakeup_cause);
- if (rv) printf("SPI INIT ERR:%d\n", rv);
- rv = eos_spi_dev_init(wakeup_cause);
- if (rv) printf("SPI DEV INIT ERR:%d\n", rv);
+ rv = eos_aon_init();
+ if (rv) EOS_LOG(EOS_LOG_ERR, "AON INIT ERR:%d\n", rv);
+ rv = eos_pwr_init();
+ if (rv) EOS_LOG(EOS_LOG_ERR, "PWR INIT ERR:%d\n", rv);
+ rv = eos_uart_init();
+ if (rv) EOS_LOG(EOS_LOG_ERR, "UART INIT ERR:%d\n", rv);
- rv = eos_bq25895_init(wakeup_cause);
- if (rv) printf("BQ25895 INIT ERR:%d\n", rv);
+ rv = eos_i2s_init();
+ if (rv) EOS_LOG(EOS_LOG_ERR, "I2S INIT ERR:%d\n", rv);
+ rv = eos_i2c_init();
+ if (rv) EOS_LOG(EOS_LOG_ERR, "I2C INIT ERR:%d\n", rv);
- rv = eos_net_init(wakeup_cause);
- if (rv) printf("NET INIT ERR:%d\n", rv);
+ rv = eos_egpio_init();
+ if (rv) EOS_LOG(EOS_LOG_ERR, "EGPIO INIT ERR:%d\n", rv);
- rv = eos_sdc_init(wakeup_cause);
- if (rv) printf("SDC INIT ERR:%d\n", rv);
+ rv = eos_batt_init();
+ if (rv) EOS_LOG(EOS_LOG_ERR, "BATT INIT ERR:%d\n", rv);
- rv = eos_eve_init(wakeup_cause);
- if (rv) printf("EVE INIT ERR:%d\n", rv);
+ rv = eos_spi_dev_init();
+ if (rv) EOS_LOG(EOS_LOG_ERR, "SPI DEV INIT ERR:%d\n", rv);
+ rv = eos_spi_init();
+ if (rv) EOS_LOG(EOS_LOG_ERR, "SPI INIT ERR:%d\n", rv);
+ rv = eos_sdc_init();
+ if (rv) EOS_LOG(EOS_LOG_ERR, "SDC INIT ERR:%d\n", rv);
- rv = eos_lcd_init(wakeup_cause);
- if (rv) printf("LCD INIT ERR:%d\n", rv);
+ rv = eos_eve_init();
+ if (rv) EOS_LOG(EOS_LOG_ERR, "EVE INIT ERR:%d\n", rv);
- rv = eos_eve_run(wakeup_cause);
- if (rv) printf("EVE RUN ERR:%d\n", rv);
+ rv = eos_lcd_init();
+ if (rv) EOS_LOG(EOS_LOG_ERR, "LCD INIT ERR:%d\n", rv);
+
+ rv = eos_ctp_init();
+ if (rv) EOS_LOG(EOS_LOG_ERR, "CTP INIT ERR:%d\n", rv);
+
+ rv = eos_net_init();
+ if (rv) EOS_LOG(EOS_LOG_ERR, "NET INIT ERR:%d\n", rv);
- eos_pwr_net_init();
eos_wifi_init();
eos_sock_init();
eos_cell_init();
+ rv = eos_sdc_insert(!eos_egpio_get_val(EGPIO_PIN_SDCARD_NDET), 0);
+ if (rv) EOS_LOG(EOS_LOG_ERR, "SDC INSERT ERR:%d\n", rv);
+
return wakeup_cause;
}
-void eos_run(uint8_t wakeup_cause) {
+void eos_run(void) {
int rv;
- rv = eos_net_run(wakeup_cause);
- if (rv) printf("NET RUN ERR:%d\n", rv);
+ rv = eos_eve_run();
+ if (rv) EOS_LOG(EOS_LOG_ERR, "EVE RUN ERR:%d\n", rv);
+
+ rv = eos_egpio_run();
+ if (rv) EOS_LOG(EOS_LOG_ERR, "EGPIO RUN ERR:%d\n", rv);
+
+ rv = eos_net_run();
+ if (rv) EOS_LOG(EOS_LOG_ERR, "NET RUN ERR:%d\n", rv);
}
-void eos_run_once(void) {
- eos_gt911_cfg_print();
- eos_gt911_configure();
- eos_gt911_cfg_print();
+#include "dev/drv/gt911.h"
+#include "eve/eve.h"
- eos_eve_calibrate();
+void eos_run_once(void) {
+ gt911_cfg_print();
+ gt911_configure();
+ gt911_cfg_print();
+
+ eve_select();
+ eve_brightness(0x40);
+ eve_calibrate();
+ eve_brightness(0);
+ eve_deselect();
}
diff --git a/fw/fe310/eos/eos.h b/fw/fe310/eos/eos.h
index 5158acd..75cd0cd 100644
--- a/fw/fe310/eos/eos.h
+++ b/fw/fe310/eos/eos.h
@@ -14,6 +14,8 @@
#define EOS_ERR_NET -20
+#define EOS_DEBUG 1
+
uint8_t eos_init(void);
-void eos_run(uint8_t wakeup_cause);
+void eos_run(void);
void eos_run_once(void); \ No newline at end of file
diff --git a/fw/fe310/eos/eve/eve.c b/fw/fe310/eos/eve/eve.c
index 45ac886..e5c5f80 100644
--- a/fw/fe310/eos/eve/eve.c
+++ b/fw/fe310/eos/eve/eve.c
@@ -12,86 +12,86 @@ static uint16_t cmd_offset;
static char dl_burst;
static uint32_t dl_addr;
-static uint8_t power_state;
+static uint8_t power_state = EVE_PSTATE_ACTIVE;
static int lcd_absent = 0;
void eve_command(uint8_t command, uint8_t parameter) {
- eve_spi_cs_set();
+ eve_spi_set_cs();
eve_spi_xchg24(((uint32_t)command << 16) | ((uint32_t)parameter << 8), 0);
- eve_spi_cs_clear();
+ eve_spi_clear_cs();
}
uint8_t eve_read8(uint32_t addr) {
- uint8_t r;
- eve_spi_cs_set();
+ uint8_t rv;
+ eve_spi_set_cs();
eve_spi_xchg32(addr << 8, 0);
- r = eve_spi_xchg8(0, EVE_SPI_FLAG_BSWAP);
- eve_spi_cs_clear();
+ rv = eve_spi_xchg8(0, EVE_SPI_FLAG_BSWAP);
+ eve_spi_clear_cs();
- return r;
+ return rv;
}
uint16_t eve_read16(uint32_t addr) {
- uint16_t r;
- eve_spi_cs_set();
+ uint16_t rv;
+ eve_spi_set_cs();
eve_spi_xchg32(addr << 8, 0);
- r = eve_spi_xchg16(0, EVE_SPI_FLAG_BSWAP);
- eve_spi_cs_clear();
+ rv = eve_spi_xchg16(0, EVE_SPI_FLAG_BSWAP);
+ eve_spi_clear_cs();
- return r;
+ return rv;
}
uint32_t eve_read32(uint32_t addr) {
- uint32_t r;
- eve_spi_cs_set();
+ uint32_t rv;
+ eve_spi_set_cs();
eve_spi_xchg32(addr << 8, 0);
- r = eve_spi_xchg32(0, EVE_SPI_FLAG_BSWAP);
- eve_spi_cs_clear();
+ rv = eve_spi_xchg32(0, EVE_SPI_FLAG_BSWAP);
+ eve_spi_clear_cs();
- return r;
+ return rv;
}
void eve_write8(uint32_t addr, uint8_t data) {
- eve_spi_cs_set();
+ eve_spi_set_cs();
eve_spi_xchg24(addr | EVE_MEM_WRITE, 0);
eve_spi_xchg8(data, EVE_SPI_FLAG_BSWAP);
- eve_spi_cs_clear();
+ eve_spi_clear_cs();
}
void eve_write16(uint32_t addr, uint16_t data) {
- eve_spi_cs_set();
+ eve_spi_set_cs();
eve_spi_xchg24(addr | EVE_MEM_WRITE, 0);
eve_spi_xchg16(data, EVE_SPI_FLAG_BSWAP);
- eve_spi_cs_clear();
+ eve_spi_clear_cs();
}
void eve_write32(uint32_t addr, uint32_t data) {
- eve_spi_cs_set();
+ eve_spi_set_cs();
eve_spi_xchg24(addr | EVE_MEM_WRITE, 0);
eve_spi_xchg32(data, EVE_SPI_FLAG_BSWAP);
- eve_spi_cs_clear();
+ eve_spi_clear_cs();
}
void eve_readb(uint32_t addr, uint8_t *buf, size_t size) {
int i;
- eve_spi_cs_set();
+ eve_spi_set_cs();
eve_spi_xchg32(addr << 8, 0);
for (i=0; i<size; i++) {
buf[i] = eve_spi_xchg8(0, 0);
}
- eve_spi_cs_clear();
+ eve_spi_clear_cs();
}
void eve_writeb(uint32_t addr, uint8_t *buf, size_t size) {
int i;
- eve_spi_cs_set();
+ eve_spi_set_cs();
eve_spi_xchg24(addr | EVE_MEM_WRITE, 0);
for (i=0; i<size; i++) {
eve_spi_xchg8(buf[i], 0);
}
- eve_spi_cs_clear();
+ eve_spi_clear_cs();
}
static void dl_inc(uint32_t i) {
@@ -102,8 +102,7 @@ void eve_dl_start(uint32_t addr, char burst) {
dl_addr = addr;
dl_burst = burst;
if (burst) {
- eve_spi_lock();
- eve_spi_cs_set();
+ eve_spi_set_cs();
eve_spi_xchg24(addr | EVE_MEM_WRITE, EVE_SPI_FLAG_TX);
}
}
@@ -120,8 +119,7 @@ void eve_dl_write(uint32_t dl) {
void eve_dl_end(void) {
if (dl_burst) {
eve_spi_flush();
- eve_spi_cs_clear();
- eve_spi_unlock();
+ eve_spi_clear_cs();
dl_burst = 0;
}
}
@@ -142,7 +140,7 @@ static void cmd_inc(uint16_t i) {
static void cmd_begin(uint32_t command, uint8_t flags) {
if (!cmd_burst) {
uint32_t addr = EVE_RAM_CMD + cmd_offset;
- eve_spi_cs_set();
+ eve_spi_set_cs();
eve_spi_xchg24(addr | EVE_MEM_WRITE, 0);
}
eve_spi_xchg32(command, flags);
@@ -150,7 +148,7 @@ static void cmd_begin(uint32_t command, uint8_t flags) {
}
static void cmd_end(void) {
- if (!cmd_burst) eve_spi_cs_clear();
+ if (!cmd_burst) eve_spi_clear_cs();
}
static void cmd_string(const char *str, uint8_t flags) {
@@ -256,44 +254,51 @@ void eve_cmd_dl(uint32_t dl) {
}
int eve_cmd_done(void) {
- uint16_t r = eve_read16(REG_CMD_READ);
+ uint16_t rd = eve_read16(REG_CMD_READ);
- if (r == 0xfff) {
+ if (rd == 0xfff) {
eve_copro_reset();
return EVE_ERR;
}
- return (r == cmd_offset);
+ return (rd == cmd_offset);
}
int eve_cmd_exec(int w) {
eve_write16(REG_CMD_WRITE, cmd_offset);
if (w) {
- int r;
+ int rv;
+ uint32_t start;
+
+ start = eve_get_tick();
do {
- r = eve_cmd_done();
- if (r < 0) break;
- } while (!r);
- if (r < 0) return EVE_ERR;
+ rv = eve_cmd_done();
+ if (rv < 0) break;
+ if (eve_tdelta_ms(start) > EVE_CMD_EXEC_TO) break;
+ } while (!rv);
+ if (eve_tdelta_ms(start) > EVE_CMD_EXEC_TO) return EVE_ERR_TIMEOUT;
+ if (rv < 0) return EVE_ERR;
}
return EVE_OK;
}
+void eve_cmd_set_offset(void) {
+ cmd_offset = eve_read16(REG_CMD_READ);
+}
+
void eve_cmd_burst_start(void) {
uint32_t addr = EVE_RAM_CMD + cmd_offset;
- eve_spi_lock();
- eve_spi_cs_set();
+ eve_spi_set_cs();
eve_spi_xchg24(addr | EVE_MEM_WRITE, EVE_SPI_FLAG_TX);
cmd_burst = 1;
}
void eve_cmd_burst_end(void) {
eve_spi_flush();
- eve_spi_cs_clear();
- eve_spi_unlock();
+ eve_spi_clear_cs();
cmd_burst = 0;
}
@@ -363,6 +368,7 @@ int eve_init(void) {
eve_write8(REG_VOL_PB, 0x00); /* turn recorded audio volume off */
/* configure interrupts */
+ eve_write8(REG_INT_EN, 0);
eve_write16(REG_INT_MASK, 0);
/* write a basic display-list to get things started */
@@ -378,28 +384,22 @@ int eve_init(void) {
#endif
/* nothing is being displayed yet... the pixel clock is still 0x00 */
+ power_state = EVE_PSTATE_ACTIVE;
+
return EVE_OK;
}
void eve_clk_start(void) {
- uint16_t gpiox;
-
eve_write8(REG_PCLK, EVE_PCLK); /* start clocking data to the LCD panel */
- gpiox = eve_read16(REG_GPIOX) | 0x8000;
- eve_write16(REG_GPIOX, gpiox); /* enable the DISP signal to the LCD panel, it is set to output in REG_GPIOX_DIR */
}
void eve_clk_stop(void) {
- uint16_t gpiox;
-
- gpiox = eve_read16(REG_GPIOX) & ~0x8000;
- eve_write16(REG_GPIOX, gpiox);
eve_write8(REG_PCLK, 0);
}
void eve_intr_enable(void) {
- eve_write8(REG_INT_EN, 0x01);
while(eve_read8(REG_INT_FLAGS));
+ eve_write8(REG_INT_EN, 0x01);
}
void eve_intr_disable(void) {
@@ -408,8 +408,27 @@ void eve_intr_disable(void) {
}
void eve_activate(void) {
+ if (power_state == EVE_PSTATE_ACTIVE) return;
+
eve_command(EVE_ACTIVE, 0);
- eve_sleep(40);
+ if (power_state == EVE_PSTATE_SLEEP) {
+ eve_sleep(20);
+ }
+}
+
+void eve_deactivate(void) {
+ switch (power_state) {
+ case EVE_PSTATE_ACTIVE:
+ return;
+
+ case EVE_PSTATE_STANDBY:
+ eve_command(EVE_STANDBY, 0);
+ break;
+
+ case EVE_PSTATE_SLEEP:
+ eve_command(EVE_SLEEP, 0);
+ break;
+ }
}
void eve_pwr_standby(void) {
@@ -423,9 +442,6 @@ void eve_pwr_standby(void) {
void eve_pwr_sleep(void) {
if (power_state != EVE_PSTATE_ACTIVE) return;
- eve_clk_stop();
- eve_intr_disable();
-
eve_command(EVE_SLEEP, 0);
power_state = EVE_PSTATE_SLEEP;
@@ -434,14 +450,17 @@ void eve_pwr_sleep(void) {
void eve_pwr_wake(void) {
eve_activate();
- if (power_state == EVE_PSTATE_SLEEP) {
- eve_intr_enable();
- eve_clk_start();
- }
-
power_state = EVE_PSTATE_ACTIVE;
}
+void eve_pwr_set_state(uint8_t state) {
+ power_state = state;
+}
+
+uint8_t eve_pwr_state(void) {
+ return power_state;
+}
+
int eve_gpio_get(int gpio) {
uint16_t reg = eve_read16(REG_GPIOX);
@@ -456,17 +475,33 @@ void eve_gpio_set(int gpio, int val) {
eve_write16(REG_GPIOX, reg);
}
-uint8_t eve_gpio_get_dir(void) {
+uint16_t eve_gpio_read(void) {
+ uint16_t reg = eve_read16(REG_GPIOX);
+
+ return reg & EVE_GPIO_MASK;
+}
+
+void eve_gpio_write(uint16_t gpio) {
+ uint16_t reg = eve_read16(REG_GPIOX);
+
+ gpio &= EVE_GPIO_MASK;
+ reg &= ~EVE_GPIO_MASK;
+ reg |= gpio;
+ eve_write16(REG_GPIOX, reg);
+}
+
+uint16_t eve_gpio_read_dir(void) {
uint16_t reg = eve_read16(REG_GPIOX_DIR);
- return reg & 0x000f;
+ return reg & EVE_GPIO_MASK;
}
-void eve_gpio_set_dir(uint8_t dir) {
+void eve_gpio_write_dir(uint16_t dir) {
uint16_t reg = eve_read16(REG_GPIOX_DIR);
- reg &= 0xfff0;
- reg |= dir & 0x0f;
+ dir &= EVE_GPIO_MASK;
+ reg &= ~EVE_GPIO_MASK;
+ reg |= dir;
eve_write16(REG_GPIOX_DIR, reg);
}
@@ -490,5 +525,8 @@ void eve_copro_reset(void) {
eve_write16(REG_CMD_DL, 0);
eve_write8(REG_CPURESET, 0);
eve_write16(REG_COPRO_PATCH_PTR, ptr);
+ /* From programming guide:
+ To enable coprocessor access flash content, send commands CMD_FLASHATTACH following CMD_FLASHFAST.
+ It will make sure flash enters full speed mode.*/
eve_write8(REG_PCLK, EVE_PCLK);
}
diff --git a/fw/fe310/eos/eve/eve.h b/fw/fe310/eos/eve/eve.h
index ea4ec71..02388bb 100644
--- a/fw/fe310/eos/eve/eve.h
+++ b/fw/fe310/eos/eve/eve.h
@@ -6,17 +6,16 @@
#include "eve_vtrack.h"
#include "eve_platform.h"
-#define EVE_OK 0
-#define EVE_ERR -1
-
-#define EVE_ERR_FULL -10
-#define EVE_ERR_EMPTY -11
-
-#define EVE_ERR_NOMEM -100
+/* defined in eve_platform.h */
+#define EVE_GPIO_MASK 0x800f
+#define EVE_GPIO_DISP 15
#define EVE_PSTATE_ACTIVE 0
#define EVE_PSTATE_STANDBY 1
-#define EVE_PSTATE_SLEEP 3
+#define EVE_PSTATE_SLEEP 2
+#define EVE_PSTATE_PDOWN 3
+
+#define EVE_CMD_EXEC_TO 1000 // 1s
#define COLOR_RGBC(c) ((4UL<<24)|((c)&16777215UL))
#define CLEAR_COLOR_RGBC(c) ((2UL<<24)|((c)&16777215UL))
@@ -53,6 +52,7 @@ uint32_t eve_cmd_result(uint16_t offset);
void eve_cmd_dl(uint32_t dl);
int eve_cmd_done(void);
int eve_cmd_exec(int w);
+void eve_cmd_set_offset(void);
void eve_cmd_burst_start(void);
void eve_cmd_burst_end(void);
@@ -65,14 +65,20 @@ void eve_intr_enable(void);
void eve_intr_disable(void);
void eve_activate(void);
+void eve_deactivate(void);
void eve_pwr_standby(void);
void eve_pwr_sleep(void);
void eve_pwr_wake(void);
+void eve_pwr_set_state(uint8_t state);
+
+uint8_t eve_pwr_state(void);
int eve_gpio_get(int gpio);
void eve_gpio_set(int gpio, int val);
-uint8_t eve_gpio_get_dir(void);
-void eve_gpio_set_dir(uint8_t dir);
+uint16_t eve_gpio_read(void);
+void eve_gpio_write(uint16_t gpio);
+uint16_t eve_gpio_read_dir(void);
+void eve_gpio_write_dir(uint16_t dir);
void eve_brightness(uint8_t b);
void eve_lcd_absent(void);
diff --git a/fw/fe310/eos/eve/eve_font.c b/fw/fe310/eos/eve/eve_font.c
index 8f272bc..803c0d2 100644
--- a/fw/fe310/eos/eve/eve_font.c
+++ b/fw/fe310/eos/eve/eve_font.c
@@ -1,4 +1,5 @@
#include <stdlib.h>
+#include <string.h>
#include "eve.h"
#include "eve_font.h"
@@ -19,57 +20,62 @@ int eve_font_ch_w(EVEFont *font, ucp_t ch) {
return EVE_ERR;
}
-static int font_str_w(EVEFont *font, utf8_t *str, int *_str_w, size_t *_str_len) {
- uint16_t r = 0;
- size_t len = 0;
+static int font_str_w(EVEFont *font, utf8_t *str, int *_str_w, size_t *_str_l) {
+ uint16_t w = 0;
+ size_t l = 0;
ucp_t ch;
int ch_w;
int ch_l;
- while (str[len]) {
- ch_l = utf8_dec(str + len, &ch);
+ while (str[l]) {
+ ch_l = utf8_dec(str + l, &ch);
ch_w = eve_font_ch_w(font, ch);
if (ch_w < 0) {
- if (_str_w) *_str_w = r;
- if (_str_len) *_str_len = len;
+ if (_str_w) *_str_w = w;
+ if (_str_l) *_str_l = l;
return EVE_ERR;
}
- r += ch_w;
- len += ch_l;
+ w += ch_w;
+ l += ch_l;
}
- if (_str_w) *_str_w = r;
- if (_str_len) *_str_len = len;
+ if (_str_w) *_str_w = w;
+ if (_str_l) *_str_l = l;
return EVE_OK;
}
-static int font_buf_w(EVEFont *font, utf8_t *buf, size_t buf_len, int *_buf_w, size_t *_buf_len) {
- uint16_t r = 0;
- size_t len = 0;
+static int font_buf_w(EVEFont *font, utf8_t *buf, size_t buf_len, int *_buf_w, size_t *_buf_l) {
+ uint16_t w = 0;
+ size_t l = 0;
ucp_t ch;
int ch_w;
int ch_l;
- while (len < buf_len) {
- ch_l = utf8_dec(buf + len, &ch);
+ while (l < buf_len) {
+ ch_l = utf8_dec(buf + l, &ch);
ch_w = eve_font_ch_w(font, ch);
if (ch_w < 0) {
- if (_buf_w) *_buf_w = r;
- if (_buf_len) *_buf_len = len;
+ if (_buf_w) *_buf_w = w;
+ if (_buf_l) *_buf_l = l;
return EVE_ERR;
}
- r += ch_w;
- len += ch_l;
+ w += ch_w;
+ l += ch_l;
}
- if (_buf_w) *_buf_w = r;
- if (_buf_len) *_buf_len = len;
+ if (_buf_w) *_buf_w = w;
+ if (_buf_l) *_buf_l = l;
return EVE_OK;
}
-int eve_font_verify(EVEFont *font, utf8_t *str, int *str_w, size_t *str_len) {
+int eve_font_verify(EVEFont *font, utf8_t *str, size_t str_size, int *str_w, size_t *str_len) {
int rv;
+ if (str_size == 0) str_size = strlen(str) + 1;
+
+ rv = utf8_verify(str, str_size, str_len);
+ if (rv) return EVE_ERR;
+
rv = font_str_w(font, str, str_w, str_len);
return rv;
}
diff --git a/fw/fe310/eos/eve/eve_font.h b/fw/fe310/eos/eve/eve_font.h
index 7629106..57715ac 100644
--- a/fw/fe310/eos/eve/eve_font.h
+++ b/fw/fe310/eos/eve/eve_font.h
@@ -11,7 +11,7 @@ typedef struct EVEFont {
void eve_font_init(EVEFont *font, uint8_t font_id);
int eve_font_ch_w(EVEFont *font, ucp_t ch);
-int eve_font_verify(EVEFont *font, utf8_t *str, int *str_w, size_t *str_len);
+int eve_font_verify(EVEFont *font, utf8_t *str, size_t str_size, int *str_w, size_t *str_len);
int eve_font_str_w(EVEFont *font, utf8_t *str);
int eve_font_buf_w(EVEFont *font, utf8_t *buf, size_t buf_len);
uint8_t eve_font_h(EVEFont *font);
diff --git a/fw/fe310/eos/eve/eve_kbd.c b/fw/fe310/eos/eve/eve_kbd.c
index c8c1362..787e941 100644
--- a/fw/fe310/eos/eve/eve_kbd.c
+++ b/fw/fe310/eos/eve/eve_kbd.c
@@ -61,10 +61,10 @@ void eve_kbd_set_handler(EVEKbd *kbd, eve_kbd_input_handler_t putc, void *param)
kbd->param = param;
}
-int eve_kbd_touch(EVEKbd *kbd, EVETouch *touch, uint16_t evt, uint8_t tag0) {
- int ret;
+int eve_kbd_touch(EVEKbd *kbd, EVETouch *touch, uint16_t evt) {
+ int rv;
- evt = eve_touch_evt(touch, evt, tag0, 1, 126);
+ evt = eve_touch_evt(touch, evt, 1, 126);
if (touch && evt) {
int8_t touch_idx = eve_touch_get_idx(touch);
@@ -118,12 +118,12 @@ int eve_kbd_touch(EVEKbd *kbd, EVETouch *touch, uint16_t evt, uint8_t tag0) {
}
}
}
- ret = 1;
+ rv = 1;
} else {
- ret = 0;
+ rv = 0;
}
- return ret;
+ return rv;
}
uint8_t eve_kbd_draw(EVEKbd *kbd) {
diff --git a/fw/fe310/eos/eve/eve_kbd.h b/fw/fe310/eos/eve/eve_kbd.h
index b4f9874..a1f8abc 100644
--- a/fw/fe310/eos/eve/eve_kbd.h
+++ b/fw/fe310/eos/eve/eve_kbd.h
@@ -19,5 +19,5 @@ typedef struct EVEKbd {
void eve_kbd_init(EVEKbd *kbd, EVERect *g, uint32_t mem_addr, uint32_t *mem_next);
void eve_kbd_close(EVEKbd *kbd);
void eve_kbd_set_handler(EVEKbd *kbd, eve_kbd_input_handler_t putc, void *param);
-int eve_kbd_touch(EVEKbd *kbd, EVETouch *touch, uint16_t evt, uint8_t tag0);
+int eve_kbd_touch(EVEKbd *kbd, EVETouch *touch, uint16_t evt);
uint8_t eve_kbd_draw(EVEKbd *kbd);
diff --git a/fw/fe310/eos/eve/eve_phy.c b/fw/fe310/eos/eve/eve_phy.c
index cfddc80..8f170ba 100644
--- a/fw/fe310/eos/eve/eve_phy.c
+++ b/fw/fe310/eos/eve/eve_phy.c
@@ -11,69 +11,67 @@ void eve_phy_acc_init(EVEPhyAcc *param, int a) {
int eve_phy_acc_start(EVEPhyAcc *param, int x0, int y0, uint32_t t0, int v0x, int v0y) {
double v0;
- uint32_t dt = eve_get_tick() - t0;
v0 = sqrt(v0x * v0x + v0y * v0y);
param->k = 2 * v0 / param->a * EVE_RTC_FREQ;
- if ((param->k < 0) && (dt >= -param->k / 2)) {
+ if (param->k == 0) {
return 0;
}
param->x0 = x0;
param->y0 = y0;
+ param->t0 = t0;
param->v0x = v0x;
param->v0y = v0y;
return 1;
}
-int eve_phy_acc_tick(EVEPhyAcc *param, uint32_t dt, int *x, int *y) {
+int eve_phy_acc_tick(void *_param, int *x, int *y) {
+ EVEPhyAcc *param = (EVEPhyAcc *)_param;
int k = param->k;
int x0 = param->x0;
int y0 = param->y0;
int v0x = param->v0x;
int v0y = param->v0y;
- int _dt = dt;
+ uint32_t dt = eve_get_tick() - param->t0;
int more = 1;
- if (k == 0) {
- if (x) *x = x0;
- if (y) *y = y0;
- return 0;
- }
-
if ((k < 0) && (dt >= -k / 2)) {
dt = -k / 2;
more = 0;
}
- if (x) *x = x0 + (v0x * _dt + v0x * _dt / k * _dt) / EVE_RTC_FREQ;
- if (y) *y = y0 + (v0y * _dt + v0y * _dt / k * _dt) / EVE_RTC_FREQ;
+ if (x) *x = x0 + (v0x * (int)dt + v0x * (int)dt / k * (int)dt) / EVE_RTC_FREQ;
+ if (y) *y = y0 + (v0y * (int)dt + v0y * (int)dt / k * (int)dt) / EVE_RTC_FREQ;
return more;
}
/* Linear harmonic oscillator */
-void eve_phy_lho_init(EVEPhyLHO *param, int x, int y, uint32_t T, double d, uint32_t t_max) {
+void eve_phy_lho_init(EVEPhyLHO *param, uint32_t T, double d, uint32_t t_max) {
double f0 = 2 * M_PI / (T * EVE_RTC_FREQ / 1000);
if (d < 0) d = 0;
if (d > 1) d = 1;
- param->x = x;
- param->y = y;
param->f = f0 * sqrt(1 - d * d);
param->a = -d * f0;
param->t_max = t_max * EVE_RTC_FREQ / 1000;
}
-int eve_phy_lho_start(EVEPhyLHO *param, int x0, int y0) {
+int eve_phy_lho_start(EVEPhyLHO *param, int pivot_x, int pivot_y, int x0, int y0, uint32_t t0) {
+ param->pivot_x = pivot_x;
+ param->pivot_y = pivot_y;
param->x0 = x0;
param->y0 = y0;
+ param->t0 = t0;
return 1;
}
-int eve_phy_lho_tick(EVEPhyLHO *param, uint32_t dt, int *x, int *y) {
- int ax = param->x0 - param->x;
- int ay = param->y0 - param->y;
+int eve_phy_lho_tick(void *_param, int *x, int *y) {
+ EVEPhyLHO *param = (EVEPhyLHO *)_param;
+ int ax = param->x0 - param->pivot_x;
+ int ay = param->y0 - param->pivot_y;
+ uint32_t dt = eve_get_tick() - param->t0;
int more = 1;
if (param->t_max && (dt >= param->t_max)) {
@@ -86,8 +84,8 @@ int eve_phy_lho_tick(EVEPhyLHO *param, uint32_t dt, int *x, int *y) {
ay = ay * e;
if ((ax == 0) && (ay == 0)) more = 0;
}
- if (x) *x = param->x + ax * cos(param->f * dt);
- if (y) *y = param->y + ay * cos(param->f * dt);
+ if (x) *x = param->pivot_x + ax * cos(param->f * dt);
+ if (y) *y = param->pivot_y + ay * cos(param->f * dt);
return more;
}
diff --git a/fw/fe310/eos/eve/eve_phy.h b/fw/fe310/eos/eve/eve_phy.h
index e747b44..59f6299 100644
--- a/fw/fe310/eos/eve/eve_phy.h
+++ b/fw/fe310/eos/eve/eve_phy.h
@@ -5,24 +5,26 @@ typedef struct EVEPhyAcc {
int k;
int x0;
int y0;
+ uint32_t t0;
int v0x;
int v0y;
} EVEPhyAcc;
void eve_phy_acc_init(EVEPhyAcc *param, int a);
int eve_phy_acc_start(EVEPhyAcc *param, int x0, int y0, uint32_t t0, int v0x, int v0y);
-int eve_phy_acc_tick(EVEPhyAcc *param, uint32_t dt, int *x, int *y);
+int eve_phy_acc_tick(void *_param, int *x, int *y);
typedef struct EVEPhyLHO {
- int x;
- int y;
double f;
double a;
uint32_t t_max;
+ int pivot_x;
+ int pivot_y;
int x0;
int y0;
+ uint32_t t0;
} EVEPhyLHO;
-void eve_phy_lho_init(EVEPhyLHO *param, int x, int y, uint32_t T, double d, uint32_t t_max);
-int eve_phy_lho_start(EVEPhyLHO *param, int x0, int y0);
-int eve_phy_lho_tick(EVEPhyLHO *param, uint32_t dt, int *x, int *y); \ No newline at end of file
+void eve_phy_lho_init(EVEPhyLHO *param, uint32_t T, double d, uint32_t t_max);
+int eve_phy_lho_start(EVEPhyLHO *param, int x, int y, int x0, int y0, uint32_t t0);
+int eve_phy_lho_tick(void *_param, int *x, int *y); \ No newline at end of file
diff --git a/fw/fe310/eos/eve/eve_platform.c b/fw/fe310/eos/eve/eve_platform.c
index 4c0d551..916b132 100644
--- a/fw/fe310/eos/eve/eve_platform.c
+++ b/fw/fe310/eos/eve/eve_platform.c
@@ -1,46 +1,35 @@
#include <stdlib.h>
-#include <stdio.h>
-#include "eos.h"
-
-#include "eve.h"
#include "eve_platform.h"
+// #ifdef EVE_DEBUG
+#if 0
+
void *eve_malloc(size_t size) {
void *p = malloc(size);
- printf("MALLOC:%p %d\n", p, size);
+ EVE_LOG(EVE_LOG_INFO, "MALLOC:%p %d\n", p, size);
return p;
}
void eve_free(void *p) {
- printf("FREE:%p\n", p);
+ EVE_LOG(EVE_LOG_INFO, "FREE:%p\n", p);
free(p);
}
+#endif
+
void eve_sleep(uint32_t ms) {
- eos_time_sleep(ms);
+ eos_sleep(ms);
}
uint32_t eve_get_tick(void) {
- return eos_time_get_tick();
+ return eos_get_tick();
}
-void eve_sys_timer_set(uint32_t ms) {
+void eve_ostimer_set(uint32_t ms) {
eos_timer_set(EOS_TIMER_ETYPE_UI, ms);
}
-void eve_sys_timer_clear(void) {
+void eve_ostimer_clear(void) {
eos_timer_clear(EOS_TIMER_ETYPE_UI);
}
-
-void eve_select(void) {
- eos_spi_select(EOS_SPI_DEV_EVE);
-}
-
-void eve_deselect(void) {
- eos_spi_deselect();
-}
-
-int eve_selected(void) {
- return (eos_spi_dev() == EOS_SPI_DEV_EVE);
-}
diff --git a/fw/fe310/eos/eve/eve_platform.h b/fw/fe310/eos/eve/eve_platform.h
index cae7222..6f34b81 100644
--- a/fw/fe310/eos/eve/eve_platform.h
+++ b/fw/fe310/eos/eve/eve_platform.h
@@ -1,38 +1,56 @@
#include <stdint.h>
#include <stdlib.h>
+/* included from eve.h - needs relative includes */
+#include "../eos.h"
+#include "../log.h"
#include "../soc/timer.h"
#include "../soc/spi.h"
-#include "../dev/spi.h"
-#define EVE_ETYPE_INTR 1
+#ifdef EOS_DEBUG
+#define EVE_DEBUG 1
+#endif
#define EVE_RTC_FREQ EOS_TIMER_RTC_FREQ
#define EVE_SPI_FLAG_BSWAP EOS_SPI_FLAG_BSWAP
#define EVE_SPI_FLAG_TX EOS_SPI_FLAG_TX
-void *eve_malloc(size_t);
-void eve_free(void *);
+#define EVE_OK EOS_OK
+#define EVE_ERR EOS_ERR
+#define EVE_ERR_TIMEOUT EOS_ERR_TIMEOUT
+
+#define EVE_ERR_FULL EOS_ERR_FULL
+#define EVE_ERR_EMPTY EOS_ERR_EMPTY
-//#define eve_malloc malloc
-//#define eve_free free
+#define EVE_ERR_NOMEM EOS_ERR_NOMEM
-void eve_select(void);
-void eve_deselect(void);
-int eve_selected(void);
+#define EVE_LOG_DEBUG EOS_LOG_DEBUG
+#define EVE_LOG_INFO EOS_LOG_INFO
+#define EVE_LOG_ERR EOS_LOG_ERR
+#define EVE_LOG_NONE EOS_LOG_NONE
+#define EVE_LOG_LEVEL EOS_LOG_LEVEL
+#define EVE_LOG(l, ...) EOS_LOG(l, __VA_ARGS__)
-#define eve_spi_cs_set eos_spi_cs_set
-#define eve_spi_cs_clear eos_spi_cs_clear
+// #ifdef EVE_DEBUG
+#if 0
+void *eve_malloc(size_t);
+void eve_free(void *);
+#else
+#define eve_malloc malloc
+#define eve_free free
+#endif
+
+#define eve_tdelta_ms eos_tdelta_ms
+#define eve_spi_set_cs eos_spi_set_cs
+#define eve_spi_clear_cs eos_spi_clear_cs
#define eve_spi_flush eos_spi_flush
#define eve_spi_xchg8 eos_spi_xchg8
#define eve_spi_xchg16 eos_spi_xchg16
#define eve_spi_xchg24 eos_spi_xchg24
#define eve_spi_xchg32 eos_spi_xchg32
-#define eve_spi_lock eos_spi_lock
-#define eve_spi_unlock eos_spi_unlock
void eve_sleep(uint32_t ms);
uint32_t eve_get_tick(void);
-void eve_sys_timer_set(uint32_t ms);
-void eve_sys_timer_clear(void);
+void eve_ostimer_set(uint32_t ms);
+void eve_ostimer_clear(void);
diff --git a/fw/fe310/eos/eve/eve_text.c b/fw/fe310/eos/eve/eve_text.c
index b52678d..e31195a 100644
--- a/fw/fe310/eos/eve/eve_text.c
+++ b/fw/fe310/eos/eve/eve_text.c
@@ -119,8 +119,8 @@ void eve_text_scroll0(EVEText *box) {
}
}
-int eve_text_touch(EVEText *box, EVETouch *touch, uint16_t evt, uint8_t tag0) {
- evt = eve_touch_evt(touch, evt, tag0, box->tag, 1);
+int eve_text_touch(EVEText *box, EVETouch *touch, uint16_t evt) {
+ evt = eve_touch_evt(touch, evt, box->tag, 1);
if (touch && evt) {
if ((evt & EVE_TOUCH_ETYPE_TRACK_START) && (box->line_top < 0)) {
box->line_top = box->line0;
@@ -148,7 +148,7 @@ uint8_t eve_text_draw(EVEText *box, uint8_t tag) {
box->tag = tag;
if (tag != EVE_NOTAG) {
eve_cmd_dl(TAG(tag));
- eve_touch_set_opt(tag, EVE_TOUCH_OPT_TRACK | EVE_TOUCH_OPT_TRACK_EXT_Y);
+ eve_tag_set_opt(tag, EVE_TOUCH_OPT_TRACK_Y | EVE_TOUCH_OPT_TRACK_EXT_Y);
tag++;
}
eve_cmd(CMD_APPEND, "ww", box->mem_addr + box->w * 2 * box->line_size, box->dl_size * 4);
@@ -161,14 +161,18 @@ void eve_text_putc(EVEText *box, int c) {
int line_c, line_n;
switch (c) {
- case '\b':
+ case '\b': {
eve_text_backspace(box);
break;
+ }
+
case '\r':
- case '\n':
+ case '\n': {
eve_text_newline(box);
break;
- default:
+ }
+
+ default: {
line_c = box->ch_idx / 2 / box->w;
eve_write16(box->mem_addr + box->ch_idx, 0x0200 | (c & 0xff));
@@ -178,6 +182,7 @@ void eve_text_putc(EVEText *box, int c) {
line_n = box->ch_idx / 2 / box->w;
if ((line_c != line_n) && (LINE_IDX_DIFF(line_n, box->line0, box->line_size) == box->h)) scroll1(box);
break;
+ }
}
}
diff --git a/fw/fe310/eos/eve/eve_text.h b/fw/fe310/eos/eve/eve_text.h
index 3b282c9..6a160ad 100644
--- a/fw/fe310/eos/eve/eve_text.h
+++ b/fw/fe310/eos/eve/eve_text.h
@@ -23,7 +23,7 @@ void eve_text_init(EVEText *box, EVERect *g, uint16_t w, uint16_t h, uint16_t li
void eve_text_update(EVEText *box);
void eve_text_scroll0(EVEText *box);
-int eve_text_touch(EVEText *box, EVETouch *touch, uint16_t evt, uint8_t tag0);
+int eve_text_touch(EVEText *box, EVETouch *touch, uint16_t evt);
uint8_t eve_text_draw(EVEText *box, uint8_t tag);
void eve_text_putc(EVEText *box, int c);
diff --git a/fw/fe310/eos/eve/eve_touch.c b/fw/fe310/eos/eve/eve_touch.c
index a729346..d4e5cea 100644
--- a/fw/fe310/eos/eve/eve_touch.c
+++ b/fw/fe310/eos/eve/eve_touch.c
@@ -4,10 +4,9 @@
#include "eve.h"
#include "eve_touch_engine.h"
-static uint8_t touch_tag0;
-
static EVETouch touch_obj[EVE_MAX_TOUCH];
static EVETouchTimer touch_timer;
+static EVEPhyAcc touch_acc;
static eve_touch_handler_t touch_handler;
static void *touch_handler_param;
@@ -16,7 +15,6 @@ static uint8_t touch_tag_opt[256];
void eve_touch_init(void) {
int i;
- touch_tag0 = 0;
memset(&touch_timer, 0, sizeof(touch_timer));
for (i=0; i<EVE_MAX_TOUCH; i++) {
EVETouch *touch = &touch_obj[i];
@@ -24,7 +22,7 @@ void eve_touch_init(void) {
memset(&touch_obj[i], 0, sizeof(EVETouch));
touch->eevt |= EVE_TOUCH_EETYPE_NOTOUCH;
}
- eve_vtrack_init();
+ eve_phy_acc_init(&touch_acc, -EVE_TOUCH_ACC_A);
}
void eve_handle_touch(uint16_t intr_flags) {
@@ -68,23 +66,17 @@ void eve_handle_touch(uint16_t intr_flags) {
}
}
if (timer_evt & EVE_TOUCH_ETYPE_TRACK) {
- EVEVTrack *vtrack = eve_vtrack_get();
-
_eevt |= EVE_TOUCH_EETYPE_TRACK_ABORT;
_touch_evt |= (EVE_TOUCH_ETYPE_TRACK_STOP | EVE_TOUCH_ETYPE_TRACK_ABORT);
- if (vtrack->stop) vtrack->stop(touch, vtrack->param);
- }
- if (timer_evt & EVE_TOUCH_ETYPE_TIMER) {
- _eevt |= EVE_TOUCH_EETYPE_TIMER_ABORT;
- _touch_evt |= EVE_TOUCH_ETYPE_TIMER_ABORT;
+ eve_vtrack_stop();
}
if (touch_handler && _touch_evt) {
- touch_handler(touch_timer.touch, _touch_evt, touch_timer.tag0, touch_handler_param);
+ touch_handler(touch_timer.touch, _touch_evt, touch_handler_param);
}
eve_timer_clear(touch);
}
- touch_evt |= EVE_TOUCH_ETYPE_POINT | _evt;
+ touch_evt = EVE_TOUCH_ETYPE_POINT0 | _evt;
touch->eevt = _eevt;
touch->tag0 = 0;
touch->tag = 0;
@@ -104,10 +96,10 @@ void eve_handle_touch(uint16_t intr_flags) {
touch->vx = vx;
touch->vy = vy;
- touch->t = now;
}
touch->x = touch_x;
touch->y = touch_y;
+ touch->t = now;
timer_evt = eve_timer_get_evt(touch);
check_track = touch->tracker.tag && !touch->tracker.track;
@@ -120,38 +112,31 @@ void eve_handle_touch(uint16_t intr_flags) {
dx = dx < 0 ? -dx : dx;
dy = dy < 0 ? -dy : dy;
if (check_track) {
- if ((dx > EVE_TOUCH_THRESHOLD_X) && !(touch_tag_opt[touch->tracker.tag] & EVE_TOUCH_OPT_TRACK_X)) {
- touch->tracker.tag = 0;
- }
- if ((dy > EVE_TOUCH_THRESHOLD_Y) && !(touch_tag_opt[touch->tracker.tag] & EVE_TOUCH_OPT_TRACK_Y)) {
+ if (((dx > EVE_TOUCH_THRESHOLD_X) && !(touch_tag_opt[touch->tracker.tag] & EVE_TOUCH_OPT_TRACK_X)) ||
+ ((dy > EVE_TOUCH_THRESHOLD_Y) && !(touch_tag_opt[touch->tracker.tag] & EVE_TOUCH_OPT_TRACK_Y))) {
touch->tracker.tag = 0;
}
if (touch->tracker.tag && ((dx > EVE_TOUCH_THRESHOLD_X) || (dy > EVE_TOUCH_THRESHOLD_Y))) {
- int track_x = 0;
-
- if ((dx > EVE_TOUCH_THRESHOLD_X) && (dx > EVE_TOUCH_THRESHOLD_Y) && ((touch_tag_opt[touch->tracker.tag] & EVE_TOUCH_OPT_TRACK_XY) == EVE_TOUCH_OPT_TRACK_XY)) {
- if (dx > dy) {
- track_x = 1;
- }
- } else if (dx > EVE_TOUCH_THRESHOLD_X) {
- track_x = 1;
- }
- if (track_x) {
- touch->eevt |= touch->x > touch->x0 ? EVE_TOUCH_EETYPE_TRACK_RIGHT : EVE_TOUCH_EETYPE_TRACK_LEFT;
- } else {
- touch->eevt |= touch->y > touch->y0 ? EVE_TOUCH_EETYPE_TRACK_DOWN : EVE_TOUCH_EETYPE_TRACK_UP;
- }
+ int track_x, track_y;
+
+ track_x = 0;
+ track_y = 0;
+ if ((touch_tag_opt[touch->tracker.tag] & EVE_TOUCH_OPT_TRACK_X) && (dx > EVE_TOUCH_THRESHOLD_X)) track_x = 1;
+ if ((touch_tag_opt[touch->tracker.tag] & EVE_TOUCH_OPT_TRACK_Y) && (dy > EVE_TOUCH_THRESHOLD_Y)) track_y = 1;
+
+ if (track_x) touch->eevt |= touch->x > touch->x0 ? EVE_TOUCH_EETYPE_TRACK_RIGHT : EVE_TOUCH_EETYPE_TRACK_LEFT;
+ if (track_y) touch->eevt |= touch->y > touch->y0 ? EVE_TOUCH_EETYPE_TRACK_DOWN : EVE_TOUCH_EETYPE_TRACK_UP;
+
touch_evt |= EVE_TOUCH_ETYPE_TRACK_START;
touch->tracker.track = 1;
- touch->t = now;
}
}
if (check_timer && ((dx > EVE_TOUCH_THRESHOLD_X) || (dy > EVE_TOUCH_THRESHOLD_Y))) {
eve_timer_set_evt(touch, timer_evt & ~(EVE_TOUCH_ETYPE_LPRESS | EVE_TOUCH_ETYPE_TAP2));
}
}
- if (touch->tracker.tag && touch->tracker.track) {
- if (touch_tag_opt[touch->tracker.tag] & EVE_TOUCH_OPT_TRACK) touch_evt |= EVE_TOUCH_ETYPE_TRACK;
+ if (touch->tracker.track) {
+ if (touch_tag_opt[touch->tracker.tag] & EVE_TOUCH_OPT_TRACK_XY) touch_evt |= EVE_TOUCH_ETYPE_TRACK;
if (touch_tag_opt[touch->tracker.tag] & EVE_TOUCH_OPT_TRACK_REG) touch_evt |= EVE_TOUCH_ETYPE_TRACK_REG;
}
if (touch_evt & EVE_TOUCH_ETYPE_TRACK_REG) {
@@ -171,19 +156,17 @@ void eve_handle_touch(uint16_t intr_flags) {
if (timer_evt & EVE_TOUCH_ETYPE_LPRESS) {
eve_timer_set_evt(touch, timer_evt & ~EVE_TOUCH_ETYPE_LPRESS);
}
- if (touch->tracker.tag && touch->tracker.track) {
+ if (touch->tracker.track) {
int start = 0;
uint8_t opt = touch_tag_opt[touch->tracker.tag];
uint8_t track_ext = ((opt & EVE_TOUCH_OPT_TRACK_EXT_X) && (touch->eevt & EVE_TOUCH_EETYPE_TRACK_X)) ||
((opt & EVE_TOUCH_OPT_TRACK_EXT_Y) && (touch->eevt & EVE_TOUCH_EETYPE_TRACK_Y));
if (!eve_timer_get_evt(NULL) && track_ext) {
- EVEVTrack *vtrack = eve_vtrack_get();
-
- if (vtrack->start) start = vtrack->start(touch, vtrack->param);
+ start = eve_phy_acc_start(&touch_acc, touch->x, touch->y, touch->t, touch->vx, touch->vy);
}
if (start) {
- eve_timer_set(touch, EVE_TOUCH_ETYPE_TRACK, touch_tag0, EVE_TOUCH_TIMEOUT_TRACK);
+ eos_vtrack_cont(&touch_acc, eve_phy_acc_tick, EVE_TOUCH_TIMEOUT_TRACK, touch);
} else {
touch_evt |= EVE_TOUCH_ETYPE_TRACK_STOP;
}
@@ -196,23 +179,22 @@ void eve_handle_touch(uint16_t intr_flags) {
if (touch_tag != touch->tag) {
if (touch_tag) {
- if (!touch_tag0) touch_tag0 = touch_tag;
if (!touch->tag0) {
+ touch_evt |= EVE_TOUCH_ETYPE_POINT;
touch->tag0 = touch_tag;
- if (touch_tag_opt[touch_tag] & (EVE_TOUCH_OPT_TRACK | EVE_TOUCH_OPT_TRACK_REG)) {
+ if (touch_tag_opt[touch_tag] & (EVE_TOUCH_OPT_TRACK_XY | EVE_TOUCH_OPT_TRACK_REG)) {
touch->tracker.tag = touch_tag;
}
if (touch->tracker.tag && !(touch_tag_opt[touch->tracker.tag] & EVE_TOUCH_OPT_TRACK_XY)) {
touch_evt |= EVE_TOUCH_ETYPE_TRACK_START;
touch->tracker.track = 1;
- touch->t = now;
}
if (!eve_timer_get_evt(NULL) && (touch_tag_opt[touch_tag] & (EVE_TOUCH_OPT_LPRESS | EVE_TOUCH_OPT_TAP2))) {
uint16_t _evt = 0;
if (touch_tag_opt[touch_tag] & EVE_TOUCH_OPT_LPRESS) _evt |= EVE_TOUCH_ETYPE_LPRESS;
if (touch_tag_opt[touch_tag] & EVE_TOUCH_OPT_TAP2) _evt |= EVE_TOUCH_ETYPE_TAP2;
- eve_timer_set(touch, _evt, touch_tag0, EVE_TOUCH_TIMEOUT_TAP);
+ eve_timer_set(touch, _evt, EVE_TOUCH_TIMEOUT_TAP);
}
}
}
@@ -224,7 +206,7 @@ void eve_handle_touch(uint16_t intr_flags) {
}
if (touch_handler && touch_evt) {
- touch_handler(touch, touch_evt, touch_tag0, touch_handler_param);
+ touch_handler(touch, touch_evt, touch_handler_param);
}
}
}
@@ -244,30 +226,19 @@ void eve_handle_time(void) {
touch_evt |= EVE_TOUCH_ETYPE_TAP1;
}
if (touch_timer.evt & EVE_TOUCH_ETYPE_TRACK) {
- EVEVTrack *vtrack = eve_vtrack_get();
-
- if (vtrack->tick) {
- touch_evt |= EVE_TOUCH_ETYPE_TRACK;
- more = vtrack->tick(touch, vtrack->param);
- }
+ touch_evt |= EVE_TOUCH_ETYPE_TRACK;
+ more = eve_vtrack_tick(&touch_evt);
if (!more) {
touch_evt |= EVE_TOUCH_ETYPE_TRACK_STOP;
- if (vtrack->stop) vtrack->stop(touch, vtrack->param);
}
}
- if (touch_timer.evt & EVE_TOUCH_ETYPE_TIMER) {
- touch_evt |= EVE_TOUCH_ETYPE_TIMER;
- more = 1;
- }
- if (more) {
- eve_sys_timer_set(touch_timer.to);
- } else {
- touch_timer.evt = 0;
+ if (!more) {
+ eve_timer_reset();
}
if (touch_handler && touch_evt) {
- touch_handler(touch, touch_evt, touch_timer.tag0, touch_handler_param);
+ touch_handler(touch, touch_evt, touch_handler_param);
}
}
}
@@ -286,20 +257,17 @@ int8_t eve_touch_get_idx(EVETouch *touch) {
return touch - touch_obj;
}
-uint16_t eve_touch_evt(EVETouch *touch, uint16_t evt, uint8_t tag0, uint8_t tag_min, uint8_t tag_n) {
+uint16_t eve_touch_evt(EVETouch *touch, uint16_t evt, uint8_t tag_min, uint8_t tag_n) {
int tag_max;
uint8_t _tag;
uint16_t _evt;
if (tag_min == EVE_NOTAG) return 0;
+ if (evt & EVE_TOUCH_ETYPE_EXT) return 0;
tag_max = tag_min + tag_n;
- if ((tag0 < tag_min) || (tag0 >= tag_max)) return 0;
+ if ((touch->tag0 < tag_min) || (touch->tag0 >= tag_max)) return 0;
- _evt = evt & (EVE_TOUCH_ETYPE_TIMER_MASK | EVE_TOUCH_ETYPE_USR_MASK);
- if (touch == NULL) return _evt;
-
- _evt |= evt & EVE_TOUCH_ETYPE_POINT_MASK;
if (evt & EVE_TOUCH_ETYPE_TAG) {
_tag = touch->tag;
if ((_tag >= tag_min) && (_tag < tag_max)) _evt |= EVE_TOUCH_ETYPE_TAG;
@@ -312,79 +280,57 @@ uint16_t eve_touch_evt(EVETouch *touch, uint16_t evt, uint8_t tag0, uint8_t tag_
_tag = touch->tracker.tag;
if ((_tag >= tag_min) && (_tag < tag_max)) _evt |= evt & EVE_TOUCH_ETYPE_TRACK_MASK;
}
- if (evt & (EVE_TOUCH_ETYPE_LPRESS | EVE_TOUCH_ETYPE_TAP1 | EVE_TOUCH_ETYPE_TAP2)) {
- _tag = touch->tag0;
- if ((_tag >= tag_min) && (_tag < tag_max)) _evt |= evt & (EVE_TOUCH_ETYPE_LPRESS | EVE_TOUCH_ETYPE_TAP1 | EVE_TOUCH_ETYPE_TAP2);
+ if (evt & (EVE_TOUCH_ETYPE_POINT_MASK | EVE_TOUCH_ETYPE_LPRESS | EVE_TOUCH_ETYPE_TAP1 | EVE_TOUCH_ETYPE_TAP2 | EVE_TOUCH_ETYPE_USR_MASK)) {
+ _evt |= evt & (EVE_TOUCH_ETYPE_POINT_MASK | EVE_TOUCH_ETYPE_LPRESS | EVE_TOUCH_ETYPE_TAP1 | EVE_TOUCH_ETYPE_TAP2 | EVE_TOUCH_ETYPE_USR_MASK);
}
return _evt;
}
-void eve_touch_set_opt(uint8_t tag, uint8_t opt) {
+void eve_tag_set_opt(uint8_t tag, uint8_t opt) {
+ if (tag == EVE_NOTAG) return;
touch_tag_opt[tag] = opt;
}
-uint8_t eve_touch_get_opt(uint8_t tag) {
+uint8_t eve_tag_get_opt(uint8_t tag) {
+ if (tag == EVE_NOTAG) return 0;
return touch_tag_opt[tag];
}
-void eve_touch_clear_opt(void) {
+void eve_tag_clear_opt(void) {
memset(touch_tag_opt, 0, sizeof(touch_tag_opt));
}
-void eve_timer_set(EVETouch *touch, uint16_t evt, uint8_t tag0, uint32_t to) {
+void eve_timer_set(EVETouch *touch, uint16_t evt, uint32_t tick_ms) {
touch_timer.touch = touch;
touch_timer.evt = evt;
- touch_timer.tag0 = tag0;
- touch_timer.to = to;
- eve_sys_timer_set(to);
+ eve_ostimer_set(tick_ms);
}
void eve_timer_clear(EVETouch *touch) {
eve_timer_set_evt(touch, 0);
}
+void eve_timer_reset(void) {
+ touch_timer.touch = NULL;
+ touch_timer.evt = 0;
+}
+
void eve_timer_set_evt(EVETouch *touch, uint16_t evt) {
if ((touch == NULL) || (touch == touch_timer.touch)) {
touch_timer.evt = evt;
- } else if (touch_timer.touch == NULL) {
- touch_timer.evt = evt;
}
if (!touch_timer.evt) {
- eve_sys_timer_clear();
+ eve_ostimer_clear();
touch_timer.touch = NULL;
- touch_timer.tag0 = 0;
- touch_timer.to = 0;
}
}
uint16_t eve_timer_get_evt(EVETouch *touch) {
- uint16_t ret = 0;
+ uint16_t rv = 0;
if ((touch == NULL) || (touch_timer.touch == touch)) {
- ret = touch_timer.evt;
- } else if (touch_timer.touch == NULL) {
- ret = touch_timer.evt;
+ rv = touch_timer.evt;
}
- return ret;
-}
-
-EVETouchTimer *eve_timer_get_obj(void) {
- return &touch_timer;
-}
-
-void eve_timer_start(uint8_t tag0, uint32_t to) {
- if (!touch_timer.evt) eve_timer_set(NULL, EVE_TOUCH_ETYPE_TIMER, tag0, to);
-}
-
-void eve_timer_stop(void) {
- if (touch_timer.touch == NULL) eve_timer_clear(NULL);
-}
-
-int eve_timer_running(void) {
- return (touch_timer.evt == EVE_TOUCH_ETYPE_TIMER);
-}
-
-void eve_touch_clear_tag0(void) {
- touch_tag0 = 0;
+ return rv;
}
diff --git a/fw/fe310/eos/eve/eve_touch.h b/fw/fe310/eos/eve/eve_touch.h
index 8ec6e0e..1f639b3 100644
--- a/fw/fe310/eos/eve/eve_touch.h
+++ b/fw/fe310/eos/eve/eve_touch.h
@@ -1,5 +1,7 @@
#include <stdint.h>
+#define EVE_TOUCH_ACC_A 10000
+
#define EVE_TOUCH_TIMEOUT_TAP 1000
#define EVE_TOUCH_TIMEOUT_TRACK 20
@@ -13,23 +15,22 @@
/* events */
#define EVE_TOUCH_ETYPE_TAG 0x0001
#define EVE_TOUCH_ETYPE_TAG_UP 0x0002
-#define EVE_TOUCH_ETYPE_POINT 0x0004
-#define EVE_TOUCH_ETYPE_POINT_UP 0x0008
-#define EVE_TOUCH_ETYPE_TRACK 0x0010
-#define EVE_TOUCH_ETYPE_TRACK_START 0x0020
-#define EVE_TOUCH_ETYPE_TRACK_STOP 0x0040
-#define EVE_TOUCH_ETYPE_TRACK_ABORT 0x0080
-#define EVE_TOUCH_ETYPE_TIMER 0x0100
-#define EVE_TOUCH_ETYPE_TIMER_ABORT 0x0200
-#define EVE_TOUCH_ETYPE_TRACK_REG 0x0400
-#define EVE_TOUCH_ETYPE_LPRESS 0x0800
-#define EVE_TOUCH_ETYPE_TAP1 0x1000
-#define EVE_TOUCH_ETYPE_TAP2 0x2000
-#define EVE_TOUCH_ETYPE_USR 0x4000
-#define EVE_TOUCH_ETYPE_USR1 0x8000
+#define EVE_TOUCH_ETYPE_POINT0 0x0004 /* emitted without tag0, possibly useless */
+#define EVE_TOUCH_ETYPE_POINT 0x0008
+#define EVE_TOUCH_ETYPE_POINT_UP 0x0010
+#define EVE_TOUCH_ETYPE_TRACK 0x0020
+#define EVE_TOUCH_ETYPE_TRACK_START 0x0040
+#define EVE_TOUCH_ETYPE_TRACK_STOP 0x0080
+#define EVE_TOUCH_ETYPE_TRACK_ABORT 0x0100
+#define EVE_TOUCH_ETYPE_TRACK_REG 0x0200
+#define EVE_TOUCH_ETYPE_LPRESS 0x0400
+#define EVE_TOUCH_ETYPE_TAP1 0x0800
+#define EVE_TOUCH_ETYPE_TAP2 0x1000
+#define EVE_TOUCH_ETYPE_USR 0x2000
+#define EVE_TOUCH_ETYPE_USR1 0x4000
+#define EVE_TOUCH_ETYPE_EXT 0x8000 /* events emitted outside of eve_touch scope */
#define EVE_TOUCH_ETYPE_TRACK_MASK (EVE_TOUCH_ETYPE_TRACK | EVE_TOUCH_ETYPE_TRACK_START | EVE_TOUCH_ETYPE_TRACK_STOP | EVE_TOUCH_ETYPE_TRACK_ABORT | EVE_TOUCH_ETYPE_TRACK_REG)
-#define EVE_TOUCH_ETYPE_TIMER_MASK (EVE_TOUCH_ETYPE_TIMER | EVE_TOUCH_ETYPE_TIMER_ABORT)
#define EVE_TOUCH_ETYPE_POINT_MASK (EVE_TOUCH_ETYPE_POINT | EVE_TOUCH_ETYPE_POINT_UP)
#define EVE_TOUCH_ETYPE_USR_MASK (EVE_TOUCH_ETYPE_USR | EVE_TOUCH_ETYPE_USR1)
@@ -44,7 +45,6 @@
#define EVE_TOUCH_EETYPE_TRACK_DOWN 0x0080
#define EVE_TOUCH_EETYPE_TRACK_ABORT 0x0100
-#define EVE_TOUCH_EETYPE_TIMER_ABORT 0x0200
#define EVE_TOUCH_EETYPE_USR 0x1000
#define EVE_TOUCH_EETYPE_USR1 0x2000
@@ -54,11 +54,9 @@
#define EVE_TOUCH_EETYPE_TRACK_X (EVE_TOUCH_EETYPE_TRACK_LEFT | EVE_TOUCH_EETYPE_TRACK_RIGHT)
#define EVE_TOUCH_EETYPE_TRACK_Y (EVE_TOUCH_EETYPE_TRACK_UP | EVE_TOUCH_EETYPE_TRACK_DOWN)
#define EVE_TOUCH_EETYPE_TRACK_XY (EVE_TOUCH_EETYPE_TRACK_X | EVE_TOUCH_EETYPE_TRACK_Y)
-#define EVE_TOUCH_EETYPE_ABORT (EVE_TOUCH_EETYPE_TRACK_ABORT | EVE_TOUCH_EETYPE_TIMER_ABORT)
/* tag options */
-#define EVE_TOUCH_OPT_TRACK 0x01
-#define EVE_TOUCH_OPT_TRACK_REG 0x02
+#define EVE_TOUCH_OPT_TRACK_REG 0x01
#define EVE_TOUCH_OPT_TRACK_X 0x04
#define EVE_TOUCH_OPT_TRACK_Y 0x08
#define EVE_TOUCH_OPT_TRACK_EXT_X 0x10
@@ -90,12 +88,10 @@ typedef struct EVETouch {
typedef struct EVETouchTimer {
EVETouch *touch;
- uint32_t to;
uint16_t evt;
- uint8_t tag0;
} EVETouchTimer;
-typedef void (*eve_touch_handler_t) (EVETouch *, uint16_t, uint8_t, void *);
+typedef void (*eve_touch_handler_t) (EVETouch *, uint16_t, void *);
void eve_touch_init(void);
void eve_handle_touch(uint16_t intr_flags);
@@ -104,19 +100,14 @@ void eve_handle_time(void);
void eve_touch_set_handler(eve_touch_handler_t handler, void *handler_param);
EVETouch *eve_touch_get_obj(int i);
int8_t eve_touch_get_idx(EVETouch *touch);
-uint16_t eve_touch_evt(EVETouch *touch, uint16_t evt, uint8_t tag0, uint8_t tag_min, uint8_t tag_n);
+uint16_t eve_touch_evt(EVETouch *touch, uint16_t evt, uint8_t tag_min, uint8_t tag_n);
-void eve_touch_set_opt(uint8_t tag, uint8_t opt);
-uint8_t eve_touch_get_opt(uint8_t tag);
-void eve_touch_clear_opt(void);
+void eve_tag_set_opt(uint8_t tag, uint8_t opt);
+uint8_t eve_tag_get_opt(uint8_t tag);
+void eve_tag_clear_opt(void);
-void eve_timer_set(EVETouch *touch, uint16_t evt, uint8_t tag0, uint32_t to);
+void eve_timer_set(EVETouch *touch, uint16_t evt, uint32_t to);
void eve_timer_clear(EVETouch *touch);
+void eve_timer_reset(void);
void eve_timer_set_evt(EVETouch *touch, uint16_t evt);
uint16_t eve_timer_get_evt(EVETouch *touch);
-EVETouchTimer *eve_timer_get_obj(void);
-
-void eve_timer_start(uint8_t tag0, uint32_t to);
-void eve_timer_stop(void);
-int eve_timer_running(void);
-void eve_touch_clear_tag0(void);
diff --git a/fw/fe310/eos/eve/eve_touch_engine.c b/fw/fe310/eos/eve/eve_touch_engine.c
index 2c75ca0..7c5b39f 100644
--- a/fw/fe310/eos/eve/eve_touch_engine.c
+++ b/fw/fe310/eos/eve/eve_touch_engine.c
@@ -26,36 +26,66 @@ static const uint32_t _reg_track[] = {
REG_TRACKER_4
};
-void eve_touch_init_engine(void) {
+void eve_touch_init_engine(uint16_t engine) {
/* configure touch */
eve_write8(REG_CPURESET, 2); /* touch engine reset */
- eve_write16(REG_TOUCH_CONFIG, 0x4000); /* host mode multi touch */
+ eve_write16(REG_TOUCH_CONFIG, engine); /* set touch engine */
eve_write8(REG_CTOUCH_EXTENDED, 0x00); /* set extended mode */
eve_write8(REG_CPURESET, 0); /* clear reset */
- eve_touch_ehost_enter(0, 0x8000, 0x8000);
- eve_touch_ehost_end();
+ if (engine == EVE_TOUCH_ENGINE_HOST) {
+ eve_touch_ehost_enter(0, 0x8000, 0x8000);
+ eve_touch_ehost_end();
+ }
}
-void eve_touch_start(void) {
+uint16_t eve_touch_get_engine(void) {
+ return (eve_read16(REG_TOUCH_CONFIG) & EVE_TOUCH_ENGINE_MASK);
+}
+
+void eve_touch_set_engine(uint16_t engine) {
+ uint16_t reg = eve_read16(REG_TOUCH_CONFIG);
+
+ reg &= ~EVE_TOUCH_ENGINE_MASK;
+ reg |= engine;
+
+ eve_write8(REG_CPURESET, 2); /* touch engine reset */
+ eve_write8(REG_TOUCH_CONFIG, reg); /* set touch engine */
+ eve_write8(REG_CPURESET, 0); /* clear reset */
+
+ if (engine == EVE_TOUCH_ENGINE_HOST) {
+ eve_touch_ehost_enter(0, 0x8000, 0x8000);
+ eve_touch_ehost_end();
+ }
+}
+
+void eve_touch_intr_enable(void) {
uint16_t intr_mask;
intr_mask = eve_read16(REG_INT_MASK);
eve_write16(REG_INT_MASK, intr_mask | (EVE_INT_CONVCOMPLETE | EVE_INT_TAG));
-
- eve_write8(REG_TOUCH_MODE, EVE_TMODE_CONTINUOUS);
}
-void eve_touch_stop(void) {
+void eve_touch_intr_disable(void) {
uint16_t intr_mask;
intr_mask = eve_read16(REG_INT_MASK);
eve_write16(REG_INT_MASK, intr_mask & ~(EVE_INT_CONVCOMPLETE | EVE_INT_TAG));
- eve_timer_clear(NULL);
+}
+void eve_touch_start(void) {
+ eve_write8(REG_TOUCH_MODE, EVE_TMODE_CONTINUOUS);
+}
+
+void eve_touch_stop(void) {
+ eve_timer_clear(NULL);
eve_write8(REG_TOUCH_MODE, EVE_TMODE_OFF);
}
+int eve_touch_get_extended(void) {
+ return !eve_read8(REG_CTOUCH_EXTENDED);
+}
+
void eve_touch_set_extended(int extended) {
eve_write8(REG_CPURESET, 2); /* touch engine reset */
eve_write8(REG_CTOUCH_EXTENDED, !extended); /* set / clear extended mode */
diff --git a/fw/fe310/eos/eve/eve_touch_engine.h b/fw/fe310/eos/eve/eve_touch_engine.h
index 3a7508f..8eb7333 100644
--- a/fw/fe310/eos/eve/eve_touch_engine.h
+++ b/fw/fe310/eos/eve/eve_touch_engine.h
@@ -1,9 +1,20 @@
#include <stdint.h>
-void eve_touch_init_engine(void);
+#define EVE_TOUCH_ENGINE_HOST 0x4000
+#define EVE_TOUCH_ENGINE_FOCALTECH 0x0380
+#define EVE_TOUCH_ENGINE_GOODIX 0x05D0
+
+#define EVE_TOUCH_ENGINE_MASK 0x4FF0
+
+void eve_touch_init_engine(uint16_t engine);
+uint16_t eve_touch_get_engine(void);
+void eve_touch_set_engine(uint16_t engine);
+void eve_touch_intr_enable(void);
+void eve_touch_intr_disable(void);
void eve_touch_start(void);
void eve_touch_stop(void);
+int eve_touch_get_extended(void);
void eve_touch_set_extended(int extended);
void eve_touch_get_matrix(uint32_t *touch_matrix);
void eve_touch_set_matrix(const uint32_t *touch_matrix);
diff --git a/fw/fe310/eos/eve/eve_vtrack.c b/fw/fe310/eos/eve/eve_vtrack.c
index a7619fb..6cc3c76 100644
--- a/fw/fe310/eos/eve/eve_vtrack.c
+++ b/fw/fe310/eos/eve/eve_vtrack.c
@@ -4,53 +4,63 @@
#include "eve.h"
static EVEVTrack vtrack;
-static EVEPhyAcc vtrack_acc;
void eve_vtrack_init(void) {
- eve_phy_acc_init(&vtrack_acc, -EVE_VTRACK_ACC_A);
eve_vtrack_reset();
}
-EVEVTrack *eve_vtrack_get(void) {
- return &vtrack;
+void eve_vtrack_reset(void) {
+ vtrack.param = NULL;
+ vtrack.tick_f = NULL;
+ vtrack.tick_ms = 0;
+ vtrack.touch = NULL;
}
-void eve_vtrack_set(eve_vtrack_start_t start, eve_vtrack_tick_t tick, eve_vtrack_stop_t stop, void *param) {
- vtrack.start = start;
- vtrack.tick = tick;
- vtrack.stop = stop;
+static void vtrack_start(void *param, eve_vtrack_tick_t tick_f, uint32_t tick_ms, EVETouch *touch, uint8_t tag) {
+ eve_timer_set(touch, EVE_TOUCH_ETYPE_TRACK, tick_ms);
vtrack.param = param;
+ vtrack.tick_f = tick_f;
+ vtrack.tick_ms = tick_ms;
+ vtrack.touch = touch;
+ if (tag != EVE_NOTAG) {
+ touch->tracker.tag = tag;
+ touch->tracker.track = 1;
+ }
}
-void eve_vtrack_reset(void) {
- eve_vtrack_set(eve_vtrack_acc_start, eve_vtrack_acc_tick, NULL, &vtrack_acc);
-}
-
-int eve_vtrack_start(EVETouch *touch, uint8_t tag0, uint32_t to) {
- if (vtrack.start) {
- int start;
-
- start = vtrack.start(touch, vtrack.param);
- if (start) eve_timer_set(touch, EVE_TOUCH_ETYPE_TRACK, tag0, to);
+void eve_vtrack_start(void *param, eve_vtrack_tick_t tick_f, uint32_t tick_ms, EVETouch *touch, uint8_t tag) {
+ vtrack_start(param, tick_f, tick_ms, touch, tag);
- return start;
- }
- return 0;
+ /* ensure that track start event is emitted on first vtrack tick */
+ touch->eevt &= ~EVE_TOUCH_EETYPE_TRACK_XY;
}
-void eve_vtrack_stop(EVETouch *touch) {
- eve_timer_clear(touch);
- eve_vtrack_reset();
+void eos_vtrack_cont(void *param, eve_vtrack_tick_t tick_f, uint32_t tick_ms, EVETouch *touch) {
+ vtrack_start(param, tick_f, tick_ms, touch, EVE_NOTAG);
}
-int eve_vtrack_acc_start(EVETouch *touch, void *p) {
- EVEPhyAcc *param = (EVEPhyAcc *)p;
+int eve_vtrack_tick(uint16_t *touch_evt) {
+ EVETouch *touch = vtrack.touch;
+ int more = 0;
- return eve_phy_acc_start(param, touch->x, touch->y, touch->t, touch->vx, touch->vy);
-}
+ if (vtrack.tick_f) {
+ more = vtrack.tick_f(vtrack.param, &touch->x, &touch->y);
+ }
+ if (more) {
+ eve_ostimer_set(vtrack.tick_ms);
+ if (!(touch->eevt & EVE_TOUCH_EETYPE_TRACK_XY)) {
+ if ((eve_tag_get_opt(touch->tracker.tag) & EVE_TOUCH_OPT_TRACK_X) && (touch->x != touch->x0)) touch->eevt |= touch->x > touch->x0 ? EVE_TOUCH_EETYPE_TRACK_RIGHT : EVE_TOUCH_EETYPE_TRACK_LEFT;
+ if ((eve_tag_get_opt(touch->tracker.tag) & EVE_TOUCH_OPT_TRACK_Y) && (touch->y != touch->y0)) touch->eevt |= touch->y > touch->y0 ? EVE_TOUCH_EETYPE_TRACK_DOWN : EVE_TOUCH_EETYPE_TRACK_UP;
+ *touch_evt |= EVE_TOUCH_ETYPE_TRACK_START;
+ }
+ } else {
+ eve_timer_reset();
+ eve_vtrack_reset();
+ }
-int eve_vtrack_acc_tick(EVETouch *touch, void *p) {
- EVEPhyAcc *param = (EVEPhyAcc *)p;
+ return more;
+}
- return eve_phy_acc_tick(param, eve_get_tick() - touch->t, &touch->x, &touch->y);
+void eve_vtrack_stop(void) {
+ eve_vtrack_reset();
}
diff --git a/fw/fe310/eos/eve/eve_vtrack.h b/fw/fe310/eos/eve/eve_vtrack.h
index 8455502..142d77b 100644
--- a/fw/fe310/eos/eve/eve_vtrack.h
+++ b/fw/fe310/eos/eve/eve_vtrack.h
@@ -1,24 +1,17 @@
#include <stdint.h>
-#define EVE_VTRACK_ACC_A 10000
-
-typedef int (*eve_vtrack_start_t) (EVETouch *, void *);
-typedef int (*eve_vtrack_tick_t) (EVETouch *, void *);
-typedef void (*eve_vtrack_stop_t) (EVETouch *, void *);
+typedef int (*eve_vtrack_tick_t) (void *, int *, int *);
typedef struct EVEVTrack {
- eve_vtrack_start_t start;
- eve_vtrack_tick_t tick;
- eve_vtrack_stop_t stop;
void *param;
+ eve_vtrack_tick_t tick_f;
+ uint32_t tick_ms;
+ EVETouch *touch;
} EVEVTrack;
void eve_vtrack_init(void);
-EVEVTrack *eve_vtrack_get(void);
-void eve_vtrack_set(eve_vtrack_start_t start, eve_vtrack_tick_t tick, eve_vtrack_stop_t stop, void *param);
void eve_vtrack_reset(void);
-int eve_vtrack_start(EVETouch *touch, uint8_t tag0, uint32_t to);
-void eve_vtrack_stop(EVETouch *touch);
-
-int eve_vtrack_acc_start(EVETouch *touch, void *p);
-int eve_vtrack_acc_tick(EVETouch *touch, void *p); \ No newline at end of file
+void eve_vtrack_start(void *param, eve_vtrack_tick_t tick_f, uint32_t tick_ms, EVETouch *touch, uint8_t tag);
+void eos_vtrack_cont(void *param, eve_vtrack_tick_t tick_f, uint32_t tick_ms, EVETouch *touch);
+int eve_vtrack_tick(uint16_t *touch_evt);
+void eve_vtrack_stop(void); \ No newline at end of file
diff --git a/fw/fe310/eos/eve/screen/form.c b/fw/fe310/eos/eve/screen/form.c
index 3e5b97c..de03bfd 100644
--- a/fw/fe310/eos/eve/screen/form.c
+++ b/fw/fe310/eos/eve/screen/form.c
@@ -12,7 +12,8 @@
#define MIN(X, Y) (((X) < (Y)) ? (X) : (Y))
#define MAX(X, Y) (((X) > (Y)) ? (X) : (Y))
-static void widgets_destroy(EVEWidget *widget, uint16_t widget_size) {
+static void widgets_destroy(EVEWidget *widgets, uint16_t widget_size) {
+ EVEWidget *widget = widgets;
int i;
for (i=0; i<widget_size; i++) {
@@ -20,65 +21,60 @@ static void widgets_destroy(EVEWidget *widget, uint16_t widget_size) {
eve_widget_destroy(widget);
widget = eve_widget_next(widget);
}
+ eve_free(widgets);
}
-EVEPage *eve_form_create(EVEWindow *window, EVEViewStack *stack, EVEFormSpec spec[], uint16_t spec_size, eve_page_uievt_t uievt, eve_page_destructor_t destructor) {
+int eve_form_create(EVEPage *page, EVEWindow *window, EVEVStack *stack, EVEFormSpec spec[], uint16_t spec_size, eve_page_uievt_t uievt, eve_page_destructor_t destructor) {
EVEWidget *widgets;
EVEWidget *widget;
EVELabel *label;
- EVEPage *page;
int w_size = 0;
- int i, r;
+ int i, rv;
if (uievt == NULL) uievt = eve_form_uievt;
if (destructor == NULL) destructor = eve_form_destroy;
- page = eve_malloc(sizeof(EVEPage));
- if (page == NULL) {
- return NULL;
- }
- eve_form_init(page, window, stack, NULL, 0, uievt, destructor);
for (i=0; i<spec_size; i++) {
w_size += eve_widget_size(spec[i].widget.type);
}
widgets = eve_malloc(w_size);
if (widgets == NULL) {
- eve_free(page);
- return NULL;
+ return EVE_ERR_NOMEM;
}
+ eve_form_init(page, window, stack, NULL, 0, uievt, destructor);
+
widget = widgets;
for (i=0; i<spec_size; i++) {
- r = eve_widget_create(widget, &spec[i].widget, page);
- if (r) {
+ rv = eve_widget_create(widget, &spec[i].widget, page);
+ if (rv) {
widgets_destroy(widgets, i);
- eve_free(widgets);
- eve_free(page);
- return NULL;
+ return rv;
}
if (spec[i].label.title) {
+ rv = EVE_OK;
label = eve_malloc(sizeof(EVELabel));
- if (label == NULL) {
+ if (label) rv = eve_label_create(label, &spec[i].label, page);
+ if ((label == NULL) || rv) {
+ if (label) eve_free(label);
eve_widget_destroy(widget);
widgets_destroy(widgets, i);
- eve_free(widgets);
- eve_free(page);
- return NULL;
+ return label ? rv : EVE_ERR_NOMEM;
}
- eve_label_create(label, &spec[i].label, page);
eve_widget_set_label(widget, label);
}
- if (widget->g.w == 0) widget->g.w = window->g.w - (widget->label ? widget->label->g.w : 0);
+ if ((widget->g.w == 0) && widget->label) widget->g.w = window->g.w - widget->label->g.w;
+ if (widget->g.w == 0) widget->g.w = window->g.w;
widget = eve_widget_next(widget);
}
eve_form_set_widget(page, widgets, spec_size);
- return page;
+ return EVE_OK;
}
-void eve_form_init(EVEPage *page, EVEWindow *window, EVEViewStack *stack, EVEWidget *widget, uint16_t widget_size, eve_page_uievt_t uievt, eve_page_destructor_t destructor) {
- eve_page_init(page, window, stack, NULL, 0, EVE_PAGE_OPT_SCROLL_Y | EVE_PAGE_OPT_SCROLL_BACK | EVE_PAGE_OPT_TRACK_EXT_Y, eve_page_draw, eve_page_touch, uievt, destructor);
- if (widget) eve_form_set_widget(page, widget, widget_size);
+void eve_form_init(EVEPage *page, EVEWindow *window, EVEVStack *stack, EVEWidget *widget, uint16_t widget_size, eve_page_uievt_t uievt, eve_page_destructor_t destructor) {
+ eve_page_init(page, window, stack, widget, widget_size, EVE_PAGE_OPT_SCROLL_Y | EVE_PAGE_OPT_SCROLL_BACK | EVE_PAGE_OPT_TRACK_EXT_Y, eve_page_draw, eve_page_touch, uievt, destructor);
+ if (widget) eve_form_update_g(page, NULL);
}
void eve_form_set_widget(EVEPage *page, EVEWidget *widget, uint16_t widget_size) {
@@ -88,42 +84,24 @@ void eve_form_set_widget(EVEPage *page, EVEWidget *widget, uint16_t widget_size)
void eve_form_destroy(EVEPage *page) {
widgets_destroy(page->widget, page->widget_size);
- eve_free(page->widget);
- eve_free(page);
}
-int eve_form_uievt(EVEPage *page, uint16_t evt, void *param) {
+void eve_form_uievt(EVEPage *page, uint16_t evt, void *param) {
switch (evt) {
case EVE_UIEVT_WIDGET_UPDATE_G:
eve_form_update_g(page, (EVEWidget *)param);
break;
- case EVE_UIEVT_WIDGET_FOCUS_IN:
- break;
-
- case EVE_UIEVT_WIDGET_FOCUS_OUT:
- break;
-
- case EVE_UIEVT_GEST_SCROLL_START:
- break;
-
- case EVE_UIEVT_GEST_SCROLL_STOP:
- break;
-
- case EVE_UIEVT_GEST_TRACK_START:
- break;
-
case EVE_UIEVT_GEST_TRACK_STOP: {
EVEUIEvtTouch *touch_p = (EVEUIEvtTouch *)param;
if (touch_p->touch->eevt & EVE_TOUCH_EETYPE_TRACK_RIGHT) {
eve_page_close(page);
- return 1;
+ return;
}
break;
}
}
- return 0;
}
void eve_form_update_g(EVEPage *page, EVEWidget *_widget) {
diff --git a/fw/fe310/eos/eve/screen/form.h b/fw/fe310/eos/eve/screen/form.h
index bc81d2d..c4b8493 100644
--- a/fw/fe310/eos/eve/screen/form.h
+++ b/fw/fe310/eos/eve/screen/form.h
@@ -7,10 +7,10 @@ typedef struct EVEFormSpec {
EVEWidgetSpec widget;
} EVEFormSpec;
-EVEPage *eve_form_create(EVEWindow *window, EVEViewStack *stack, EVEFormSpec spec[], uint16_t spec_size, eve_page_uievt_t uievt, eve_page_destructor_t destructor);
-void eve_form_init(EVEPage *page, EVEWindow *window, EVEViewStack *stack, EVEWidget *widget, uint16_t widget_size, eve_page_uievt_t uievt, eve_page_destructor_t destructor);
+int eve_form_create(EVEPage *page, EVEWindow *window, EVEVStack *stack, EVEFormSpec spec[], uint16_t spec_size, eve_page_uievt_t uievt, eve_page_destructor_t destructor);
+void eve_form_init(EVEPage *page, EVEWindow *window, EVEVStack *stack, EVEWidget *widget, uint16_t widget_size, eve_page_uievt_t uievt, eve_page_destructor_t destructor);
void eve_form_set_widget(EVEPage *page, EVEWidget *widget, uint16_t widget_size);
void eve_form_destroy(EVEPage *page);
-int eve_form_uievt(EVEPage *page, uint16_t evt, void *param);
+void eve_form_uievt(EVEPage *page, uint16_t evt, void *param);
void eve_form_update_g(EVEPage *page, EVEWidget *_widget);
diff --git a/fw/fe310/eos/eve/screen/page.c b/fw/fe310/eos/eve/screen/page.c
index 93b81c5..8c02538 100644
--- a/fw/fe310/eos/eve/screen/page.c
+++ b/fw/fe310/eos/eve/screen/page.c
@@ -14,15 +14,36 @@
#define PAGE_TMODE_TRACK 1
#define PAGE_TMODE_SCROLL 2
-void eve_page_init(EVEPage *page, EVEWindow *window, EVEViewStack *stack, EVEWidget *widget, uint16_t widget_size, uint8_t opt, eve_page_draw_t draw, eve_page_touch_t touch, eve_page_uievt_t uievt, eve_page_destructor_t destructor) {
+void eve_page_init(EVEPage *page, EVEWindow *window, EVEVStack *stack, EVEWidget *widget, uint16_t widget_size, uint8_t opt, eve_page_draw_t draw, eve_page_touch_t touch, eve_page_uievt_t uievt, eve_page_destructor_t destructor) {
memset(page, 0, sizeof(EVEPage));
eve_view_init(&page->v, window, (eve_view_draw_t)draw, (eve_view_touch_t)touch, (eve_view_uievt_t)uievt, NULL);
+ eve_phy_lho_init(&page->lho, 100, 0.5, 0);
page->stack = stack;
page->opt = opt;
page->destructor = destructor;
eve_page_set_widget(page, widget, widget_size);
}
+void eve_page_attach(EVEPage *page, EVEWindow *window, void *page_id) {
+ eve_view_attach(&page->v, window, page_id);
+}
+
+void eve_page_detach(EVEPage *page) {
+ eve_view_detach(&page->v);
+}
+
+void eve_page_set_param(EVEPage *page, void *param) {
+ eve_view_set_param(&page->v, param);
+}
+
+EVEView *eve_page_view(EVEPage *page) {
+ return &page->v;
+}
+
+EVEPage *eve_page_from_view(EVEView *view) {
+ return (EVEPage *)view;
+}
+
EVEWidget *eve_page_widget(EVEPage *page, uint16_t _idx) {
EVEWidget *w = page->widget;
int i, idx;
@@ -62,53 +83,81 @@ void eve_page_set_widget(EVEPage *page, EVEWidget *widget, uint16_t widget_size)
page->widget_size = widget_size;
}
-void eve_page_open(EVEPage *parent, eve_view_constructor_t constructor) {
- EVEWindow *window = parent->v.window;
- EVEViewStack *stack = parent->stack;
- eve_page_destructor_t destructor = parent->destructor;
-
- eve_page_set_focus(parent, NULL);
- if (destructor) destructor(parent);
- eve_stack_create_view(stack, window, constructor);
-}
-
-void eve_page_close(EVEPage *page) {
+static void page_destroy(EVEPage *page) {
EVEWindow *window = page->v.window;
- EVEViewStack *stack = page->stack;
eve_page_destructor_t destructor = page->destructor;
- if (stack->level <= 1) return;
-
eve_page_set_focus(page, NULL);
- if (eve_timer_running()) {
- eve_timer_stop();
- }
- if (eve_window_scroll(window->root, NULL) == window) {
+ if (eve_window_scroll(window, NULL) == window) {
eve_window_scroll_stop(window);
}
eve_window_kbd_detach(window);
+ eve_page_detach(page);
+
if (destructor) destructor(page);
- eve_stack_back(stack, window);
+}
+
+void eve_page_open(EVEPage *parent, eve_view_constructor_t constructor) {
+ EVEWindow *window = parent->v.window;
+ EVEVStack *stack = parent->stack;
+ int rv;
+
+ if (eve_vstack_full(stack)) return;
+
+ page_destroy(parent);
+ rv = eve_vstack_create_view(stack, window, constructor);
+ if (rv) {
+ EVEView *view = NULL;
+
+ do {
+ constructor = eve_vstack_get(stack);
+ if (constructor) view = constructor(window, stack);
+ if (view == NULL) eve_vstack_pull(stack);
+ } while ((view == NULL) && constructor);
+ if (view) eve_view_attach(view, window, constructor);
+ }
+}
+
+void eve_page_close(EVEPage *page) {
+ EVEWindow *window = page->v.window;
+ EVEVStack *stack = page->stack;
+ int rv;
+
+ if (eve_vstack_level(stack) == 1) return;
+
+ page_destroy(page);
+ rv = eve_vstack_back(stack, window);
+ if (rv) {
+ eve_view_constructor_t constructor;
+ EVEView *view = NULL;
+
+ do {
+ eve_vstack_pull(stack);
+ constructor = eve_vstack_get(stack);
+ if (constructor) view = constructor(window, stack);
+ } while ((view == NULL) && constructor);
+ if (view) eve_view_attach(view, window, constructor);
+ }
}
/* Screen to page coordinates */
int16_t eve_page_x(EVEPage *page, int16_t x) {
- return x + page->g.x - page->v.window->g.x;
+ return x - page->g.x - page->v.window->g.x;
}
int16_t eve_page_y(EVEPage *page, int16_t y) {
- return y + page->g.y - page->v.window->g.y;
+ return y - page->g.y - page->v.window->g.y;
}
/* Page to window coordinates */
int16_t eve_page_win_x(EVEPage *page, int16_t x) {
- return x - page->g.x;
+ return x + page->g.x;
}
int16_t eve_page_win_y(EVEPage *page, int16_t y) {
- return y - page->g.y;
+ return y + page->g.y;
}
/* Page to screen coordinates */
@@ -120,49 +169,57 @@ int16_t eve_page_scr_y(EVEPage *page, int16_t y) {
return eve_page_win_y(page, y) + page->v.window->g.y;
}
-int eve_page_rect_visible(EVEPage *page, EVERect *g) {
- uint16_t w = page->v.window->g.w;
- uint16_t h = page->v.window->g.h;
+int eve_page_rect_visible(EVEPage *page, EVERect *rect) {
+ EVERect win_g;
- if (((g->x + g->w) >= page->g.x) && ((g->y + g->h) >= page->g.y) && (g->x <= (page->g.x + w)) && (g->y <= (page->g.y + h))) return 1;
- return 0;
+ eve_window_visible_g(page->v.window, &win_g);
+ win_g.x -= page->v.window->g.x;
+ win_g.y -= page->v.window->g.y;
+
+ if ((page->g.x + rect->x + rect->w < win_g.x) ||
+ (page->g.y + rect->y + rect->h < win_g.y) ||
+ (page->g.x + rect->x > win_g.x + win_g.w) ||
+ (page->g.y + rect->y > win_g.y + win_g.h)) return 0;
+
+ return 1;
}
void eve_page_show_rect(EVEPage *page, EVERect *rect) {
- EVERect g;
+ EVERect win_g;
- eve_window_visible_g(page->v.window, &g);
- g.x -= page->v.window->g.x;
- g.y -= page->v.window->g.y;
+ eve_window_visible_g(page->v.window, &win_g);
+ win_g.x -= page->v.window->g.x;
+ win_g.y -= page->v.window->g.y;
- if (rect->x < page->g.x + g.x) {
- page->g.x = rect->x - g.x;
+ if (page->g.x + rect->x < win_g.x) {
+ page->g.x = win_g.x - rect->x;
}
- if (rect->y < page->g.y + g.y) {
- page->g.y = rect->y - g.y;
+ if (page->g.y + rect->y < win_g.y) {
+ page->g.y = win_g.y - rect->y;
}
- if ((rect->x + rect->w) > (page->g.x + g.x + g.w)) {
- page->g.x = (rect->x + rect->w) - (g.x + g.w);
+
+ if (page->g.x + rect->x + rect->w > win_g.x + win_g.w) {
+ page->g.x = win_g.x + win_g.w - (rect->x + rect->w);
}
- if ((rect->y + rect->h) > (page->g.y + g.y + g.h)) {
- page->g.y = (rect->y + rect->h) - (g.y + g.h);
+ if (page->g.y + rect->y + rect->h > win_g.y + win_g.h) {
+ page->g.y = win_g.y + win_g.h - (rect->y + rect->h);
}
}
/* returns true if x or y are out of page bounds for window */
-int eve_page_oob(EVEPage *page, int *_max_x, int *_max_y) {
- int max_x, max_y;
- EVERect vg;
+int eve_page_oob(EVEPage *page, int *min_x, int *min_y) {
+ int _min_x, _min_y;
+ EVERect win_g;
- eve_window_visible_g(page->v.window, &vg);
- max_x = page->g.w > vg.w ? page->g.w - vg.w : 0;
- max_y = page->g.h > vg.h ? page->g.h - vg.h : 0;
+ eve_window_visible_g(page->v.window, &win_g);
+ _min_x = -(page->g.w > win_g.w ? page->g.w - win_g.w : 0);
+ _min_y = -(page->g.h > win_g.h ? page->g.h - win_g.h : 0);
- if (_max_x) *_max_x = max_x;
- if (_max_y) *_max_y = max_y;
+ if (min_x) *min_x = _min_x;
+ if (min_y) *min_y = _min_y;
- return ((page->g.x < 0) || (page->g.x > max_x) ||
- (page->g.y < 0) || (page->g.y > max_y));
+ return ((page->g.x > 0) || (page->g.x < _min_x) ||
+ (page->g.y > 0) || (page->g.y < _min_y));
}
EVEWidget *eve_page_focus(EVEPage *page) {
@@ -174,159 +231,150 @@ void eve_page_set_focus(EVEPage *page, EVEWidget *widget) {
EVEWindow *window = page->v.window;
EVEWidget *widget_f = page->widget_f;
- if (widget_f && widget_f->putc) {
- widget_f->putc(widget_f, EVE_PAGE_KBDCH_CLOSE);
- if (!(widget && widget->putc)) eve_window_kbd_detach(window);
+ if ((widget_f && widget_f->putc) && !(widget && widget->putc)) {
+ eve_window_kbd_detach(window);
}
if (widget && widget->putc) {
EVEKbd *kbd = eve_window_kbd(window);
if (kbd) eve_kbd_set_handler(kbd, widget->putc, widget);
- if (!(widget_f && widget_f->putc)) eve_window_kbd_attach(window);
+ if (!(widget_f && widget_f->putc)) {
+ eve_window_kbd_attach(window);
+ eve_page_show_rect(page, &widget->g);
+ }
+ }
+ if (widget_f) {
+ eve_view_uievt_push(&page->v, EVE_UIEVT_WIDGET_FOCUS_OUT, widget_f);
+ widget_f->touch(widget_f, NULL, EVE_TOUCH_ETYPE_EXT | EVE_UIEVT_WIDGET_FOCUS_OUT);
}
- if (page->widget_f) eve_view_uievt_push(&page->v, EVE_UIEVT_WIDGET_FOCUS_OUT, page->widget_f);
page->widget_f = widget;
- if (page->widget_f) eve_view_uievt_push(&page->v, EVE_UIEVT_WIDGET_FOCUS_IN, page->widget_f);
+ if (widget) {
+ eve_view_uievt_push(&page->v, EVE_UIEVT_WIDGET_FOCUS_IN, widget);
+ widget->touch(widget, NULL, EVE_TOUCH_ETYPE_EXT | EVE_UIEVT_WIDGET_FOCUS_IN);
+ }
}
}
-static int page_touch(EVEPage *page, EVETouch *touch, uint16_t evt, uint8_t tag0) {
+static int page_touch(EVEPage *page, EVETouch *touch, uint16_t evt) {
EVEView *view = &page->v;
EVEWindow *window = view->window;
int scroll_x = 0, scroll_y = 0, scroll;
- int ret = 0;
-
- if (touch) {
- if ((page->opt & EVE_PAGE_OPT_SCROLL_XY) == EVE_PAGE_OPT_SCROLL_XY) {
- scroll_x = scroll_y = (touch->eevt & EVE_TOUCH_EETYPE_TRACK_XY);
- } else if (page->opt & EVE_PAGE_OPT_SCROLL_X) {
- scroll_x = (touch->eevt & EVE_TOUCH_EETYPE_TRACK_X);
- } else if (page->opt & EVE_PAGE_OPT_SCROLL_Y) {
- scroll_y = (touch->eevt & EVE_TOUCH_EETYPE_TRACK_Y);
- }
+ int rv = 0;
+
+ if ((page->opt & EVE_PAGE_OPT_SCROLL_XY) == EVE_PAGE_OPT_SCROLL_XY) {
+ scroll_x = scroll_y = (touch->eevt & EVE_TOUCH_EETYPE_TRACK_XY);
+ } else if (page->opt & EVE_PAGE_OPT_SCROLL_X) {
+ scroll_x = (touch->eevt & EVE_TOUCH_EETYPE_TRACK_X);
+ } else if (page->opt & EVE_PAGE_OPT_SCROLL_Y) {
+ scroll_y = (touch->eevt & EVE_TOUCH_EETYPE_TRACK_Y);
+ }
- scroll = scroll_x || scroll_y;
+ scroll = scroll_x || scroll_y;
- if ((tag0 == page->v.tag) && (evt & EVE_TOUCH_ETYPE_POINT_UP) && !(touch->eevt & (EVE_TOUCH_EETYPE_TRACK_XY | EVE_TOUCH_EETYPE_ABORT))) {
- int _ret = 0;
+ if ((touch->tag0 == page->v.tag) && (evt & EVE_TOUCH_ETYPE_POINT_UP) && !(touch->eevt & (EVE_TOUCH_EETYPE_TRACK_XY | EVE_TOUCH_EETYPE_TRACK_ABORT))) {
+ eve_page_set_focus(page, NULL);
+ eve_view_uievt_push_gest(view, EVE_UIEVT_GEST_TOUCH, touch, evt);
+ if (eve_window_dirty(window)) return 1;
+ rv = 1;
+ }
- eve_page_set_focus(page, NULL);
- _ret = eve_view_uievt_push_gest(view, EVE_UIEVT_GEST_TOUCH, touch, evt, tag0);
- if (_ret) return _ret;
- ret = 1;
+ /* Scroll / track start */
+ if (evt & EVE_TOUCH_ETYPE_TRACK_START) {
+ if (page->track_mode == PAGE_TMODE_NONE) {
+ if (scroll) {
+ page->track_mode = PAGE_TMODE_SCROLL;
+ eve_window_scroll_start(window, touch->tag0);
+ eve_view_uievt_push_gest(view, EVE_UIEVT_GEST_SCROLL_START, touch, evt);
+ } else {
+ page->track_mode = PAGE_TMODE_TRACK;
+ eve_view_uievt_push_gest(view, EVE_UIEVT_GEST_TRACK_START, touch, evt);
+ }
+ if (eve_window_dirty(window)) return 1;
+ }
+ if (scroll_x) {
+ page->x0 = touch->x0 - page->g.x;
+ }
+ if (scroll_y) {
+ page->y0 = touch->y0 - page->g.y;
}
+ rv = 1;
+ }
- /* Scroll / track start */
- if (evt & EVE_TOUCH_ETYPE_TRACK_START) {
- int _ret = 0;
-
- if (!(touch->eevt & EVE_TOUCH_EETYPE_ABORT)) {
- if (scroll) {
- page->track_mode = PAGE_TMODE_SCROLL;
- eve_window_scroll_start(window, touch->tracker.tag);
- _ret = eve_view_uievt_push_gest(view, EVE_UIEVT_GEST_SCROLL_START, touch, evt, tag0);
- } else {
- page->track_mode = PAGE_TMODE_TRACK;
- _ret = eve_view_uievt_push_gest(view, EVE_UIEVT_GEST_TRACK_START, touch, evt, tag0);
- }
- if (_ret) return _ret;
- }
- if (scroll_x) {
- page->x0 = page->g.x;
- }
- if (scroll_y) {
- page->y0 = page->g.y;
- }
- ret = 1;
+ if ((evt & EVE_TOUCH_ETYPE_TRACK) && (page->track_mode == PAGE_TMODE_SCROLL)) {
+ if (scroll_x) {
+ page->g.x = touch->x - page->x0;
}
+ if (scroll_y) {
+ page->g.y = touch->y - page->y0;
+ }
+ rv = 1;
+ }
- /* Scroll / track stop */
- if (((evt & EVE_TOUCH_ETYPE_TRACK_STOP) && !(evt & EVE_TOUCH_ETYPE_TRACK_ABORT)) ||
- ((evt & EVE_TOUCH_ETYPE_POINT_UP) && (touch->eevt & EVE_TOUCH_EETYPE_ABORT) && !(touch->eevt & EVE_TOUCH_EETYPE_TRACK_XY))) {
- if ((page->track_mode == PAGE_TMODE_SCROLL) && (page->opt & EVE_PAGE_OPT_SCROLL_BACK)) {
- int max_x, max_y;
- int oob;
-
- oob = eve_page_oob(page, &max_x, &max_y);
- if (oob) {
- int lho_x, lho_y;
- uint8_t _tag;
- EVEPhyLHO *lho = &page->lho;
-
- lho_x = page->g.x < 0 ? 0 : max_x;
- lho_y = page->g.y < 0 ? 0 : max_y;
- eve_window_scroll(window->root, &_tag);
-
- page->lho_t0 = eve_get_tick();
- eve_phy_lho_init(lho, lho_x, lho_y, 100, 0.5, 0);
- eve_phy_lho_start(lho, page->g.x, page->g.y);
- eve_timer_start(_tag, 20);
+ /* Scroll / track stop */
+ if (((evt & EVE_TOUCH_ETYPE_TRACK_STOP) && !(evt & EVE_TOUCH_ETYPE_TRACK_ABORT)) ||
+ ((evt & EVE_TOUCH_ETYPE_POINT_UP) && (touch->eevt & EVE_TOUCH_EETYPE_TRACK_ABORT) && !(touch->eevt & EVE_TOUCH_EETYPE_TRACK_XY))) {
+ int start = 0;
+
+ if ((page->track_mode == PAGE_TMODE_SCROLL) && (page->opt & EVE_PAGE_OPT_SCROLL_BACK)) {
+ int min_gx, min_gy;
+ int oob;
+
+ oob = eve_page_oob(page, &min_gx, &min_gy);
+ if (oob) {
+ int pivot_x, pivot_y, x0, y0;
+ int scroll_x, scroll_y;
+ EVEPhyLHO *lho = &page->lho;
+ uint8_t scroll_tag;
+
+ pivot_x = touch->x0 - page->g.x + (page->g.x < min_gx ? min_gx : 0);
+ pivot_y = touch->y0 - page->g.y + (page->g.y < min_gy ? min_gy : 0);
+ x0 = touch->x0;
+ y0 = touch->y0;
+
+ scroll_x = page->opt & EVE_PAGE_OPT_SCROLL_X;
+ scroll_y = page->opt & EVE_PAGE_OPT_SCROLL_Y;
+ if (!scroll_x) pivot_x = x0;
+ if (!scroll_y) pivot_y = y0;
+
+ eve_window_scroll(window, &scroll_tag);
+ start = eve_phy_lho_start(lho, pivot_x, pivot_y, x0, y0, eve_get_tick());
+ if (start) {
+ eve_vtrack_start(lho, eve_phy_lho_tick, EVE_TOUCH_TIMEOUT_TRACK, touch, scroll_tag);
}
}
+ }
- if (!eve_timer_running()) {
- int _ret = 0;
-
- switch (page->track_mode) {
- case PAGE_TMODE_SCROLL: {
- page->track_mode = PAGE_TMODE_NONE;
- eve_window_scroll_stop(window);
- _ret = eve_view_uievt_push_gest(view, EVE_UIEVT_GEST_SCROLL_STOP, touch, evt, tag0);
- break;
- }
-
- case PAGE_TMODE_TRACK: {
- page->track_mode = PAGE_TMODE_NONE;
- _ret = eve_view_uievt_push_gest(view, EVE_UIEVT_GEST_TRACK_STOP, touch, evt, tag0);
- break;
- }
+ if (!start) {
+ switch (page->track_mode) {
+ case PAGE_TMODE_SCROLL: {
+ page->track_mode = PAGE_TMODE_NONE;
+ eve_window_scroll_stop(window);
+ eve_view_uievt_push_gest(view, EVE_UIEVT_GEST_SCROLL_STOP, touch, evt);
+ break;
}
- if (_ret) return _ret;
- }
- ret = 1;
- }
- if ((evt & EVE_TOUCH_ETYPE_TRACK) && (page->track_mode == PAGE_TMODE_SCROLL)) {
- if (scroll_x) {
- page->g.x = page->x0 + touch->x0 - touch->x;
- }
- if (scroll_y) {
- page->g.y = page->y0 + touch->y0 - touch->y;
+ case PAGE_TMODE_TRACK: {
+ page->track_mode = PAGE_TMODE_NONE;
+ eve_view_uievt_push_gest(view, EVE_UIEVT_GEST_TRACK_STOP, touch, evt);
+ break;
+ }
}
- ret = 1;
- }
- } else if ((evt & EVE_TOUCH_ETYPE_TIMER) && (page->track_mode == PAGE_TMODE_SCROLL) && (page->opt & EVE_PAGE_OPT_SCROLL_BACK)) {
- EVEPhyLHO *lho = &page->lho;
- int scroll_x = page->opt & EVE_PAGE_OPT_SCROLL_X;
- int scroll_y = page->opt & EVE_PAGE_OPT_SCROLL_Y;
- int x, y, more;
-
- more = eve_phy_lho_tick(lho, eve_get_tick() - page->lho_t0, scroll_x ? &x : NULL, scroll_y ? &y : NULL);
- if (scroll_x) page->g.x = x;
- if (scroll_y) page->g.y = y;
- if (!more) {
- int _ret = 0;
-
- page->track_mode = PAGE_TMODE_NONE;
- eve_timer_stop();
- eve_window_scroll_stop(window);
- _ret = eve_view_uievt_push_gest(view, EVE_UIEVT_GEST_SCROLL_STOP, touch, evt, tag0);
- if (_ret) return _ret;
+ if (eve_window_dirty(window)) return 1;
}
- ret = 1;
+ rv = 1;
}
- return ret;
+ return rv;
}
uint8_t eve_page_draw(EVEPage *page, uint8_t tag0) {
EVEView *view = &page->v;
EVEWidget *widget = page->widget;
int i;
- uint8_t tagN = tag0;
+ uint8_t tagN;
uint8_t tag_opt;
- tag_opt = EVE_TOUCH_OPT_TRACK | EVE_TOUCH_OPT_TRACK_XY;
+ tag_opt = EVE_TOUCH_OPT_TRACK_XY;
if (page->opt & EVE_PAGE_OPT_TRACK_EXT_X) tag_opt |= EVE_TOUCH_OPT_TRACK_EXT_X;
if (page->opt & EVE_PAGE_OPT_TRACK_EXT_Y) tag_opt |= EVE_TOUCH_OPT_TRACK_EXT_Y;
@@ -354,52 +402,41 @@ draw_nextw:
eve_cmd_dl(RESTORE_CONTEXT());
for (i=tag0; i<tagN; i++) {
- if (i != EVE_NOTAG) eve_touch_set_opt(i, eve_touch_get_opt(i) | tag_opt);
+ if (i != EVE_NOTAG) eve_tag_set_opt(i, eve_tag_get_opt(i) | tag_opt);
}
return tagN;
}
-int eve_page_touch(EVEPage *page, EVETouch *touch, uint16_t evt, uint8_t tag0) {
+int eve_page_touch(EVEPage *page, EVETouch *touch, uint16_t evt) {
EVEWidget *widget = page->widget;
- EVEViewStack *stack = page->stack;
+ EVEWindow *window = page->v.window;
int8_t touch_idx = eve_touch_get_idx(touch);
uint16_t _evt;
- int i, ret;
+ int i, rv;
if (touch_idx > 0) return 0;
- _evt = eve_touch_evt(touch, evt, tag0, page->v.tag, 1);
+ _evt = eve_touch_evt(touch, evt, page->v.tag, 1);
if (_evt) {
- ret = page_touch(page, touch, _evt, tag0);
- if (stack->dirty) {
- stack->dirty = 0;
- return 1;
- }
- if (ret) return 1;
+ rv = page_touch(page, touch, _evt);
+ if (rv || eve_window_dirty(window)) return 1;
}
for (i=0; i<page->widget_size; i++) {
if (!eve_page_rect_visible(page, &widget->g) || (widget->flags & (EVE_WIDGET_FLAG_SKIP | EVE_WIDGET_FLAG_RO | EVE_WIDGET_FLAG_HIDDEN))) goto touch_nextw;
- _evt = eve_touch_evt(touch, evt, tag0, widget->tag0, widget->tagN - widget->tag0);
+ _evt = eve_touch_evt(touch, evt, widget->tag0, widget->tagN - widget->tag0);
if (_evt) {
if (page->track_mode == PAGE_TMODE_NONE) {
- ret = widget->touch(widget, touch, _evt);
- if (stack->dirty) {
- stack->dirty = 0;
+ rv = widget->touch(widget, touch, _evt);
+ if (eve_window_dirty(window)) return 1;
+ if (rv) {
+ eve_page_set_focus(page, widget);
return 1;
}
- if (ret) {
- eve_widget_set_focus(widget);
- return 1;
- }
- }
- ret = page_touch(page, touch, _evt, tag0);
- if (stack->dirty) {
- stack->dirty = 0;
- return 1;
}
- if (ret) return 1;
+ rv = page_touch(page, touch, _evt);
+ if (rv || eve_window_dirty(window)) return 1;
}
touch_nextw:
diff --git a/fw/fe310/eos/eve/screen/page.h b/fw/fe310/eos/eve/screen/page.h
index 6874a2d..067565b 100644
--- a/fw/fe310/eos/eve/screen/page.h
+++ b/fw/fe310/eos/eve/screen/page.h
@@ -1,7 +1,5 @@
#include <stdint.h>
-#define EVE_PAGE_KBDCH_CLOSE 0x1a
-
#define EVE_PAGE_OPT_SCROLL_X 0x01
#define EVE_PAGE_OPT_SCROLL_Y 0x02
#define EVE_PAGE_OPT_SCROLL_BACK 0x04
@@ -15,8 +13,8 @@ struct EVEWidget;
struct EVEPage;
typedef uint8_t (*eve_page_draw_t) (struct EVEPage *, uint8_t);
-typedef int (*eve_page_touch_t) (struct EVEPage *, EVETouch *, uint16_t, uint8_t);
-typedef int (*eve_page_uievt_t) (struct EVEPage *, uint16_t, void *);
+typedef int (*eve_page_touch_t) (struct EVEPage *, EVETouch *, uint16_t);
+typedef void (*eve_page_uievt_t) (struct EVEPage *, uint16_t, void *);
typedef void (*eve_page_destructor_t) (struct EVEPage *);
typedef struct EVEPage {
@@ -24,19 +22,23 @@ typedef struct EVEPage {
EVERect g;
int16_t x0;
int16_t y0;
- EVEViewStack *stack;
+ EVEVStack *stack;
eve_page_destructor_t destructor;
struct EVEWidget *widget;
uint16_t widget_size;
struct EVEWidget *widget_f;
EVEPhyLHO lho;
- uint32_t lho_t0;
uint8_t track_mode;
uint8_t opt;
} EVEPage;
-void eve_page_init(EVEPage *page, EVEWindow *window, EVEViewStack *stack, struct EVEWidget *widget, uint16_t widget_size, uint8_t opt, eve_page_draw_t draw, eve_page_touch_t touch, eve_page_uievt_t uievt, eve_page_destructor_t destructor);
+void eve_page_init(EVEPage *page, EVEWindow *window, EVEVStack *stack, struct EVEWidget *widget, uint16_t widget_size, uint8_t opt, eve_page_draw_t draw, eve_page_touch_t touch, eve_page_uievt_t uievt, eve_page_destructor_t destructor);
+void eve_page_attach(EVEPage *page, EVEWindow *window, void *page_id);
+void eve_page_detach(EVEPage *page);
+void eve_page_set_param(EVEPage *page, void *param);
+EVEView *eve_page_view(EVEPage *page);
+EVEPage *eve_page_from_view(EVEView *view);
struct EVEWidget *eve_page_widget(EVEPage *page, uint16_t idx);
struct EVEWidget *eve_page_widget_search(EVEPage *page, char *label);
void eve_page_set_widget(EVEPage *page, struct EVEWidget *widget, uint16_t widget_size);
@@ -53,12 +55,12 @@ int16_t eve_page_win_y(EVEPage *page, int16_t y);
/* Page to screen coordinates */
int16_t eve_page_scr_x(EVEPage *page, int16_t x);
int16_t eve_page_scr_y(EVEPage *page, int16_t y);
-int eve_page_rect_visible(EVEPage *page, EVERect *g);
+int eve_page_rect_visible(EVEPage *page, EVERect *rect);
void eve_page_show_rect(EVEPage *page, EVERect *rect);
-int eve_page_oob(EVEPage *page, int *_max_x, int *_max_y);
+int eve_page_oob(EVEPage *page, int *min_x, int *min_y);
struct EVEWidget *eve_page_focus(EVEPage *page);
void eve_page_set_focus(EVEPage *page, struct EVEWidget *widget);
uint8_t eve_page_draw(EVEPage *page, uint8_t tag0);
-int eve_page_touch(EVEPage *page, EVETouch *touch, uint16_t evt, uint8_t tag0);
+int eve_page_touch(EVEPage *page, EVETouch *touch, uint16_t evt);
diff --git a/fw/fe310/eos/eve/screen/uievt.h b/fw/fe310/eos/eve/screen/uievt.h
index 8e1e682..e40624a 100644
--- a/fw/fe310/eos/eve/screen/uievt.h
+++ b/fw/fe310/eos/eve/screen/uievt.h
@@ -5,12 +5,12 @@
#define EVE_UIEVT_GEST_TRACK_STOP 5
#define EVE_UIEVT_WIN_UPDATE_G 6
#define EVE_UIEVT_PAGE_UPDATE_G 7
-#define EVE_UIEVT_WIDGET_UPDATE_G 8
-#define EVE_UIEVT_WIDGET_FOCUS_IN 9
-#define EVE_UIEVT_WIDGET_FOCUS_OUT 10
+#define EVE_UIEVT_WIDGET_UPDATE 8
+#define EVE_UIEVT_WIDGET_UPDATE_G 9
+#define EVE_UIEVT_WIDGET_FOCUS_IN 10
+#define EVE_UIEVT_WIDGET_FOCUS_OUT 11
typedef struct EVEUIEvtTouch {
EVETouch *touch;
uint16_t evt;
- uint8_t tag0;
} EVEUIEvtTouch;
diff --git a/fw/fe310/eos/eve/screen/view.c b/fw/fe310/eos/eve/screen/view.c
index d6e9ede..a1290f0 100644
--- a/fw/fe310/eos/eve/screen/view.c
+++ b/fw/fe310/eos/eve/screen/view.c
@@ -15,7 +15,19 @@ void eve_view_init(EVEView *view, EVEWindow *window, eve_view_draw_t draw, eve_v
view->window = window;
view->color_bg = 0x000000;
view->color_fg = 0xffffff;
- window->view = view;
+}
+
+void eve_view_attach(EVEView *view, EVEWindow *window, void *view_id) {
+ view->window = window;
+ eve_window_attach_view(window, view, view_id);
+}
+
+void eve_view_detach(EVEView *view) {
+ eve_window_detach_view(view->window);
+}
+
+void eve_view_set_param(EVEView *view, void *param) {
+ view->param = param;
}
void eve_view_set_color_bg(EVEView *view, uint8_t r, uint8_t g, uint8_t b) {
@@ -29,78 +41,121 @@ void eve_view_set_color_fg(EVEView *view, uint8_t r, uint8_t g, uint8_t b) {
uint8_t eve_view_clear(EVEView *view, uint8_t tag0, uint8_t tag_opt) {
EVEWindow *win_scroll = NULL;
EVEWindow *window = view->window;
- uint8_t _tag;
+ uint8_t scroll_tag;
- win_scroll = eve_window_scroll(window->root, &_tag);
+ win_scroll = eve_window_scroll(window, &scroll_tag);
eve_cmd_dl(CLEAR_COLOR_RGBC(view->color_bg));
eve_cmd_dl(COLOR_RGBC(view->color_fg));
if (win_scroll == window) {
- view->tag = _tag;
- eve_touch_set_opt(view->tag, tag_opt);
- eve_cmd_dl(TAG(view->tag));
- eve_cmd_dl(CLEAR_TAG(view->tag));
+ view->tag = scroll_tag;
} else if (win_scroll) {
view->tag = EVE_NOTAG;
- eve_cmd_dl(TAG(view->tag));
- eve_cmd_dl(CLEAR_TAG(view->tag));
} else {
view->tag = tag0;
if (tag0 != EVE_NOTAG) {
- eve_touch_set_opt(tag0, tag_opt);
- eve_cmd_dl(CLEAR_TAG(tag0));
+ eve_tag_set_opt(tag0, tag_opt);
tag0++;
}
}
+ eve_cmd_dl(CLEAR_TAG(view->tag));
eve_cmd_dl(CLEAR(1,1,1));
return tag0;
}
-int eve_view_uievt_push(EVEView *view, uint16_t evt, void *param) {
- if (view->uievt) return view->uievt(view, evt, param);
- return 0;
+uint8_t eve_view_tag(EVEView *view, uint8_t tag, uint8_t tag_opt) {
+ if (tag != EVE_NOTAG) {
+ eve_tag_set_opt(tag, tag_opt);
+ eve_cmd_dl(TAG(tag));
+ tag++;
+ }
+ return tag;
}
-int eve_view_uievt_push_gest(EVEView *view, uint16_t evt, EVETouch *touch, uint16_t t_evt, uint8_t tag0) {
- if (view->uievt) {
- EVEUIEvtTouch param;
+void eve_view_uievt_push(EVEView *view, uint16_t evt, void *param) {
+ if (view->uievt) view->uievt(view, evt, param);
+}
- param.touch = touch;
- param.evt = t_evt;
- param.tag0 = tag0;
- return view->uievt(view, evt, &param);
- }
- return 0;
+void eve_view_uievt_push_gest(EVEView *view, uint16_t evt, EVETouch *touch, uint16_t t_evt) {
+ EVEUIEvtTouch param;
+
+ if (view->uievt == NULL) return;
+
+ param.touch = touch;
+ param.evt = t_evt;
+ view->uievt(view, evt, &param);
}
-void eve_stack_init(EVEViewStack *stack) {
- memset(stack, 0, sizeof(EVEViewStack));
+void eve_vstack_init(EVEVStack *stack) {
+ memset(stack, 0, sizeof(EVEVStack));
}
-void eve_stack_create_view(EVEViewStack *stack, EVEWindow *window, eve_view_constructor_t constructor) {
- int rv;
+int eve_vstack_push(EVEVStack *stack, eve_view_constructor_t constructor) {
+ if (stack->level == EVE_VIEW_SIZE_STACK) return EVE_ERR_FULL;
- stack->dirty = 1;
- if (stack->level < EVE_VIEW_SIZE_STACK - 1) {
- stack->constructor[stack->level] = constructor;
- stack->level++;
- rv = constructor(window, stack);
- if (rv) eve_stack_back(stack, window);
- }
+ stack->constructor[stack->level] = constructor;
+ stack->level++;
+
+ return EVE_OK;
}
-void eve_stack_back(EVEViewStack *stack, EVEWindow *window) {
+eve_view_constructor_t eve_vstack_pull(EVEVStack *stack) {
eve_view_constructor_t constructor;
- int rv = 1;
- stack->dirty = 1;
- while ((stack->level > 1) && rv) {
+ constructor = eve_vstack_get(stack);
+ if (stack->level) {
stack->level--;
- constructor = stack->constructor[stack->level - 1];
- rv = constructor(window, stack);
+ stack->constructor[stack->level] = NULL;
}
+ return constructor;
}
-eve_view_constructor_t eve_stack_get(EVEViewStack *stack) {
+eve_view_constructor_t eve_vstack_get(EVEVStack *stack) {
if (stack->level) return stack->constructor[stack->level - 1];
return NULL;
}
+
+int eve_vstack_empty(EVEVStack *stack) {
+ return (stack->level == 0);
+}
+
+int eve_vstack_full(EVEVStack *stack) {
+ return (stack->level == EVE_VIEW_SIZE_STACK);
+}
+
+int eve_vstack_level(EVEVStack *stack) {
+ return stack->level;
+}
+
+int eve_vstack_create_view(EVEVStack *stack, EVEWindow *window, eve_view_constructor_t constructor) {
+ EVEView *view;
+ int rv;
+
+ rv = eve_vstack_push(stack, constructor);
+ if (rv) return rv;
+
+ view = constructor(window, stack);
+ if (view == NULL) {
+ eve_vstack_pull(stack);
+ return EVE_ERR;
+ }
+
+ eve_view_attach(view, window, constructor);
+
+ return EVE_OK;
+}
+
+int eve_vstack_back(EVEVStack *stack, EVEWindow *window) {
+ EVEView *view;
+ eve_view_constructor_t constructor;
+
+ eve_vstack_pull(stack);
+ constructor = eve_vstack_get(stack);
+ if (constructor == NULL) return EVE_ERR_EMPTY;
+
+ view = constructor(window, stack);
+ if (view == NULL) return EVE_ERR;
+
+ eve_view_attach(view, window, constructor);
+
+ return EVE_OK;
+}
diff --git a/fw/fe310/eos/eve/screen/view.h b/fw/fe310/eos/eve/screen/view.h
index 3e8c0a0..c40a620 100644
--- a/fw/fe310/eos/eve/screen/view.h
+++ b/fw/fe310/eos/eve/screen/view.h
@@ -5,13 +5,13 @@
#define EVE_VIEW_SIZE_STACK 16
struct EVEView;
-struct EVEViewStack;
+struct EVEVStack;
struct EVEWindow;
typedef uint8_t (*eve_view_draw_t) (struct EVEView *, uint8_t);
-typedef int (*eve_view_touch_t) (struct EVEView *, EVETouch *, uint16_t, uint8_t);
-typedef int (*eve_view_uievt_t) (struct EVEView *, uint16_t, void *);
-typedef int (*eve_view_constructor_t) (struct EVEWindow *window, struct EVEViewStack *);
+typedef int (*eve_view_touch_t) (struct EVEView *, EVETouch *, uint16_t);
+typedef void (*eve_view_uievt_t) (struct EVEView *, uint16_t, void *);
+typedef struct EVEView *(*eve_view_constructor_t) (struct EVEWindow *window, struct EVEVStack *);
typedef struct EVEView {
eve_view_draw_t draw;
@@ -24,21 +24,29 @@ typedef struct EVEView {
uint8_t tag;
} EVEView;
-typedef struct EVEViewStack {
+typedef struct EVEVStack {
eve_view_constructor_t constructor[EVE_VIEW_SIZE_STACK];
uint8_t level;
- uint8_t dirty;
-} EVEViewStack;
+} EVEVStack;
void eve_view_init(EVEView *view, struct EVEWindow *window, eve_view_draw_t draw, eve_view_touch_t touch, eve_view_uievt_t uievt, void *param);
+void eve_view_attach(EVEView *view, struct EVEWindow *window, void *view_id);
+void eve_view_detach(EVEView *view);
+void eve_view_set_param(EVEView *view, void *param);
void eve_view_set_color_bg(EVEView *view, uint8_t r, uint8_t g, uint8_t b);
void eve_view_set_color_fg(EVEView *view, uint8_t r, uint8_t g, uint8_t b);
uint8_t eve_view_clear(EVEView *view, uint8_t tag0, uint8_t tag_opt);
-
-int eve_view_uievt_push(EVEView *view, uint16_t evt, void *param);
-int eve_view_uievt_push_gest(EVEView *view, uint16_t evt, EVETouch *touch, uint16_t t_evt, uint8_t tag0);
-
-void eve_stack_init(EVEViewStack *stack);
-void eve_stack_create_view(EVEViewStack *stack, struct EVEWindow *window, eve_view_constructor_t constructor);
-void eve_stack_back(EVEViewStack *stack, struct EVEWindow *window);
-eve_view_constructor_t eve_stack_get(EVEViewStack *stack); \ No newline at end of file
+uint8_t eve_view_tag(EVEView *view, uint8_t tag, uint8_t tag_opt);
+
+void eve_view_uievt_push(EVEView *view, uint16_t evt, void *param);
+void eve_view_uievt_push_gest(EVEView *view, uint16_t evt, EVETouch *touch, uint16_t t_evt);
+
+void eve_vstack_init(EVEVStack *stack);
+int eve_vstack_push(EVEVStack *stack, eve_view_constructor_t constructor);
+eve_view_constructor_t eve_vstack_pull(EVEVStack *stack);
+eve_view_constructor_t eve_vstack_get(EVEVStack *stack);
+int eve_vstack_empty(EVEVStack *stack);
+int eve_vstack_full(EVEVStack *stack);
+int eve_vstack_level(EVEVStack *stack);
+int eve_vstack_create_view(EVEVStack *stack, struct EVEWindow *window, eve_view_constructor_t constructor);
+int eve_vstack_back(EVEVStack *stack, struct EVEWindow *window);
diff --git a/fw/fe310/eos/eve/screen/window.c b/fw/fe310/eos/eve/screen/window.c
index 34d265a..90f4e20 100644
--- a/fw/fe310/eos/eve/screen/window.c
+++ b/fw/fe310/eos/eve/screen/window.c
@@ -1,6 +1,5 @@
#include <stdlib.h>
#include <string.h>
-#include <stdio.h>
#include "eve.h"
#include "eve_kbd.h"
@@ -28,7 +27,7 @@ void eve_window_init_root(EVEWindowRoot *root, EVERect *g, char *name, EVEFont *
root->font = font;
root->win_kbd = NULL;
root->win_scroll = NULL;
- root->tag0 = EVE_NOTAG;
+ root->tag_scroll = EVE_NOTAG;
eve_touch_set_handler(eve_window_root_touch, root);
}
@@ -41,10 +40,10 @@ static uint8_t kbd_draw(EVEView *view, uint8_t tag0) {
return tag0;
}
-static int kbd_touch(EVEView *view, EVETouch *touch, uint16_t evt, uint8_t tag0) {
+static int kbd_touch(EVEView *view, EVETouch *touch, uint16_t evt) {
EVEKbd *kbd = view->param;
- return eve_kbd_touch(kbd, touch, evt, tag0);
+ return eve_kbd_touch(kbd, touch, evt);
}
void eve_window_init_kbd(EVEWindowKbd *win_kbd, EVERect *g, EVEWindowRoot *root, char *name, EVEKbd *kbd) {
@@ -55,6 +54,7 @@ void eve_window_init_kbd(EVEWindowKbd *win_kbd, EVERect *g, EVEWindowRoot *root,
win_kbd->kbd = kbd;
root->win_kbd = win_kbd;
eve_view_init(&win_kbd->v, _window, kbd_draw, kbd_touch, NULL, kbd);
+ eve_view_attach(&win_kbd->v, _window, NULL);
}
void eve_window_set_parent(EVEWindow *window, EVEWindow *parent) {
@@ -62,6 +62,26 @@ void eve_window_set_parent(EVEWindow *window, EVEWindow *parent) {
window->root = parent->root;
}
+void eve_window_attach_view(EVEWindow *window, EVEView *view, void *view_id) {
+ if (window->view) window->dirty = 1;
+ window->view = view;
+ window->view_id = view_id;
+}
+
+void eve_window_detach_view(EVEWindow *window) {
+ if (window->view) window->dirty = 1;
+ window->view = NULL;
+ window->view_id = NULL;
+}
+
+int eve_window_dirty(EVEWindow *window) {
+ return window->dirty;
+}
+
+void eve_window_clean(EVEWindow *window) {
+ window->dirty = 0;
+}
+
int eve_window_visible(EVEWindow *window) {
if (window->g.x >= window->root->w.g.w) return 0;
if (window->g.y >= window->root->w.g.h) return 0;
@@ -70,31 +90,32 @@ int eve_window_visible(EVEWindow *window) {
return 1;
}
-static void window_visible_g(EVEWindow *w, EVERect *g) {
- while (w) {
- if (eve_window_visible(w)) {
- if (w->g.x > g->x) g->w = MIN(g->w, w->g.x - g->x);
- if (w->g.y > g->y) g->h = MIN(g->h, w->g.y - g->y);
- if (w->g.x + w->g.w < g->x + g->w) {
- uint16_t x0 = g->w - MIN(g->w, (g->x + g->w) - (w->g.x + w->g.w));
- g->x += x0;
- g->w -= x0;
+static void window_visible_g(EVEWindow *win, EVERect *rect) {
+ while (win) {
+ if (eve_window_visible(win)) {
+ if (win->g.x > rect->x) rect->w = MIN(rect->w, win->g.x - rect->x);
+ if (win->g.y > rect->y) rect->h = MIN(rect->h, win->g.y - rect->y);
+ if (win->g.x + win->g.w < rect->x + rect->w) {
+ uint16_t x0 = rect->w - MIN(rect->w, (rect->x + rect->w) - (win->g.x + win->g.w));
+ rect->x += x0;
+ rect->w -= x0;
}
- if (w->g.y + w->g.h < g->y + g->h) {
- uint16_t y0 = g->h - MIN(g->h, (g->y + g->h) - (w->g.y + w->g.h));
- g->y += y0;
- g->h -= y0;
+ if (win->g.y + win->g.h < rect->y + rect->h) {
+ uint16_t y0 = rect->h - MIN(rect->h, (rect->y + rect->h) - (win->g.y + win->g.h));
+ rect->y += y0;
+ rect->h -= y0;
}
+ if ((rect->w == 0) || (rect->h == 0)) return;
}
- if (w->child_head) window_visible_g(w->child_head, g);
- w = w->next;
+ if (win->child_head) window_visible_g(win->child_head, rect);
+ win = win->next;
}
}
-void eve_window_visible_g(EVEWindow *window, EVERect *g) {
- *g = window->g;
- if (window->child_head) window_visible_g(window->child_head, g);
- window_visible_g(window->next, g);
+void eve_window_visible_g(EVEWindow *window, EVERect *rect) {
+ *rect = window->g;
+ if (window->child_head) window_visible_g(window->child_head, rect);
+ window_visible_g(window->next, rect);
}
void eve_window_append(EVEWindow *window) {
@@ -160,8 +181,8 @@ EVEWindow *eve_window_search(EVEWindow *window, char *name) {
while (window) {
if (window->name && (strcmp(name, window->name) == 0)) return window;
if (window->child_head) {
- EVEWindow *ret = eve_window_search(window->child_head, name);
- if (ret) return ret;
+ EVEWindow *rv = eve_window_search(window->child_head, name);
+ if (rv) return rv;
}
window = window->next;
}
@@ -198,17 +219,18 @@ uint8_t eve_window_draw(EVEWindow *window, uint8_t tag0) {
return tag0;
}
-int eve_window_touch(EVEWindow *window, EVETouch *touch, uint16_t evt, uint8_t tag0) {
- int ret = 0;
+int eve_window_touch(EVEWindow *window, EVETouch *touch, uint16_t evt) {
+ int rv = 0;
while (window) {
if (window->child_tail) {
- ret = eve_window_touch(window->child_tail, touch, evt, tag0);
- if (ret) return 1;
+ rv = eve_window_touch(window->child_tail, touch, evt);
+ if (rv) return 1;
}
if (eve_window_visible(window) && window->view) {
- ret = window->view->touch(window->view, touch, evt, tag0);
- if (ret) return 1;
+ rv = window->view->touch(window->view, touch, evt);
+ window->dirty = 0;
+ if (rv) return 1;
}
window = window->prev;
}
@@ -223,24 +245,31 @@ void eve_window_root_draw(EVEWindowRoot *root) {
eve_cmd_burst_start();
eve_cmd_dl(CMD_DLSTART);
- if (root->tag0 != EVE_NOTAG) tag0 = EVE_NOTAG;
+ if (root->tag_scroll != EVE_NOTAG) tag0 = EVE_NOTAG;
eve_window_draw(&root->w, tag0);
eve_cmd_dl(DISPLAY());
eve_cmd_dl(CMD_SWAP);
eve_cmd_burst_end();
rv = eve_cmd_exec(1);
- if (rv) printf("EVE EXEC ERR\n");
+ if (rv) EVE_LOG(EVE_LOG_ERR, "EVE CMD EXEC ERR:%d\n", rv);
}
-void eve_window_root_touch(EVETouch *touch, uint16_t evt, uint8_t tag0, void *win) {
+void eve_window_root_touch(EVETouch *touch, uint16_t evt, void *win) {
EVEWindowRoot *root = (EVEWindowRoot *)win;
- int ret;
+ int rv;
- if (root->tag0 != EVE_NOTAG) tag0 = root->tag0;
- ret = eve_window_touch(&root->w, touch, evt, tag0);
- if (ret) {
- eve_touch_clear_opt();
+ rv = eve_window_touch(&root->w, touch, evt);
+ if (rv) {
+ uint8_t tag_opt = 0;
+
+ if (root->tag_scroll != EVE_NOTAG) {
+ tag_opt = eve_tag_get_opt(root->tag_scroll);
+ }
+ eve_tag_clear_opt();
+ if (root->tag_scroll != EVE_NOTAG) {
+ eve_tag_set_opt(root->tag_scroll, tag_opt);
+ }
eve_window_root_draw(root);
}
}
@@ -275,14 +304,10 @@ void eve_window_kbd_detach(EVEWindow *window) {
}
}
-EVEFont *eve_window_font(EVEWindow *window) {
+EVEWindow *eve_window_scroll(EVEWindow *window, uint8_t *tag) {
EVEWindowRoot *root = window->root;
- return root->font;
-}
-
-EVEWindow *eve_window_scroll(EVEWindowRoot *root, uint8_t *tag) {
- if (tag) *tag = root->tag0;
+ if (tag) *tag = root->tag_scroll;
return root->win_scroll;
}
@@ -290,12 +315,18 @@ void eve_window_scroll_start(EVEWindow *window, uint8_t tag) {
EVEWindowRoot *root = window->root;
root->win_scroll = window;
- root->tag0 = tag;
+ root->tag_scroll = tag;
}
void eve_window_scroll_stop(EVEWindow *window) {
EVEWindowRoot *root = window->root;
root->win_scroll = NULL;
- root->tag0 = EVE_NOTAG;
+ root->tag_scroll = EVE_NOTAG;
+}
+
+EVEFont *eve_window_font(EVEWindow *window) {
+ EVEWindowRoot *root = window->root;
+
+ return root->font;
}
diff --git a/fw/fe310/eos/eve/screen/window.h b/fw/fe310/eos/eve/screen/window.h
index 27465c4..ac52fb8 100644
--- a/fw/fe310/eos/eve/screen/window.h
+++ b/fw/fe310/eos/eve/screen/window.h
@@ -8,12 +8,14 @@ typedef struct EVEWindow {
EVERect g;
char *name;
EVEView *view;
+ void *view_id;
struct EVEWindowRoot *root;
struct EVEWindow *parent;
struct EVEWindow *next;
struct EVEWindow *prev;
struct EVEWindow *child_head;
struct EVEWindow *child_tail;
+ int dirty;
} EVEWindow;
typedef struct EVEWindowKbd {
@@ -28,7 +30,7 @@ typedef struct EVEWindowRoot {
EVEFont *font;
EVEWindowKbd *win_kbd;
EVEWindow *win_scroll;
- uint8_t tag0;
+ uint8_t tag_scroll;
} EVEWindowRoot;
void eve_window_init(EVEWindow *window, EVERect *g, EVEWindow *parent, char *name);
@@ -36,8 +38,13 @@ void eve_window_init_root(EVEWindowRoot *root, EVERect *g, char *name, EVEFont *
void eve_window_init_kbd(EVEWindowKbd *win_kbd, EVERect *g, EVEWindowRoot *root, char *name, EVEKbd *kbd);
void eve_window_set_parent(EVEWindow *window, EVEWindow *parent);
+void eve_window_attach_view(EVEWindow *window, EVEView *view, void *view_id);
+void eve_window_detach_view(EVEWindow *window);
+int eve_window_dirty(EVEWindow *window);
+void eve_window_clean(EVEWindow *window);
+
int eve_window_visible(EVEWindow *window);
-void eve_window_visible_g(EVEWindow *window, EVERect *g);
+void eve_window_visible_g(EVEWindow *window, EVERect *rect);
void eve_window_append(EVEWindow *window);
void eve_window_insert_above(EVEWindow *window, EVEWindow *win_prev);
@@ -46,15 +53,16 @@ void eve_window_remove(EVEWindow *window);
EVEWindow *eve_window_search(EVEWindow *window, char *name);
uint8_t eve_window_draw(EVEWindow *window, uint8_t tag0);
-int eve_window_touch(EVEWindow *window, EVETouch *touch, uint16_t evt, uint8_t tag0);
+int eve_window_touch(EVEWindow *window, EVETouch *touch, uint16_t evt);
void eve_window_root_draw(EVEWindowRoot *root);
-void eve_window_root_touch(EVETouch *touch, uint16_t evt, uint8_t tag0, void *win);
+void eve_window_root_touch(EVETouch *touch, uint16_t evt, void *win);
EVEKbd *eve_window_kbd(EVEWindow *window);
void eve_window_kbd_attach(EVEWindow *window);
void eve_window_kbd_detach(EVEWindow *window);
-EVEFont *eve_window_font(EVEWindow *window);
-EVEWindow *eve_window_scroll(EVEWindowRoot *root, uint8_t *tag);
+EVEWindow *eve_window_scroll(EVEWindow *window, uint8_t *tag);
void eve_window_scroll_start(EVEWindow *window, uint8_t tag);
void eve_window_scroll_stop(EVEWindow *window);
+
+EVEFont *eve_window_font(EVEWindow *window);
diff --git a/fw/fe310/eos/eve/widget/freew.c b/fw/fe310/eos/eve/widget/freew.c
index 11b8e50..f88f81e 100644
--- a/fw/fe310/eos/eve/widget/freew.c
+++ b/fw/fe310/eos/eve/widget/freew.c
@@ -10,22 +10,28 @@
#include "widget.h"
-void eve_freew_init(EVEFreeWidget *widget, EVERect *g, EVEPage *page, eve_freew_draw_t draw, eve_freew_touch_t touch, eve_kbd_input_handler_t putc) {
+int eve_freew_init(EVEFreeWidget *widget, EVERect *g, EVEPage *page, eve_freew_draw_t draw, eve_freew_touch_t touch, eve_kbd_input_handler_t putc) {
EVEWidget *_widget = &widget->w;
memset(widget, 0, sizeof(EVEFreeWidget));
eve_widget_init(_widget, EVE_WIDGET_TYPE_FREE, g, page, eve_freew_draw, eve_freew_touch, putc);
widget->_draw = draw;
widget->_touch = touch;
+
+ return EVE_OK;
+}
+
+void eve_freew_set_uievt_handler(EVEFreeWidget *widget, eve_freew_uievt_t handler) {
+ widget->_uievt = handler;
}
int eve_freew_create(EVEWidget *_widget, EVEWidgetSpec *spec, EVEPage *page) {
EVEFreeWidget *widget = (EVEFreeWidget *)_widget;
EVEFreeSpec *tspec = &spec->tspec.free;
+ int rv;
- eve_freew_init(widget, &spec->g, page, tspec->draw, tspec->touch, tspec->putc);
-
- return EVE_OK;
+ rv = eve_freew_init(widget, &spec->g, page, tspec->draw, tspec->touch, tspec->putc);
+ return rv;
}
uint8_t eve_freew_draw(EVEWidget *_widget, uint8_t tag0) {
@@ -42,27 +48,53 @@ uint8_t eve_freew_draw(EVEWidget *_widget, uint8_t tag0) {
int eve_freew_touch(EVEWidget *_widget, EVETouch *touch, uint16_t evt) {
EVEFreeWidget *widget = (EVEFreeWidget *)_widget;
- int ret;
+ int rv;
+
+ /* widget received non-touch event */
+ if (evt & EVE_TOUCH_ETYPE_EXT) {
+ evt &= ~EVE_TOUCH_ETYPE_EXT;
+ if (widget->_uievt) widget->_uievt(widget, evt);
- ret = widget->_touch(widget, touch, evt);
- return ret;
+ /* always return 0 for non-touch events */
+ return 0;
+ }
+
+ rv = widget->_touch(widget, touch, evt);
+ return rv;
}
-uint8_t eve_freew_tag(EVEFreeWidget *widget) {
+uint8_t eve_freew_tag0(EVEFreeWidget *widget) {
+ EVEWidget *_widget = &widget->w;
+
+ return _widget->tag0;
+}
+
+void eve_freew_tag(EVEFreeWidget *widget, uint8_t tag_opt) {
EVEWidget *_widget = &widget->w;
- uint8_t ret = EVE_NOTAG;
if (_widget->tagN != EVE_NOTAG) {
- ret = _widget->tagN;
- eve_cmd_dl(TAG(ret));
+ eve_tag_set_opt(_widget->tagN, tag_opt);
+ eve_cmd_dl(TAG(_widget->tagN));
_widget->tagN++;
}
+}
- return ret;
+void eve_freew_tag_idx(EVEFreeWidget *widget, uint8_t i) {
+ EVEWidget *_widget = &widget->w;
+ uint8_t tag = _widget->tag0;
+
+ if (tag != EVE_NOTAG) {
+ tag += i;
+
+ /* prevents overflow */
+ if ((tag >= _widget->tag0) && (tag < _widget->tagN)) {
+ eve_cmd_dl(TAG(tag));
+ }
+ }
}
-uint8_t eve_widget_tag_index(EVEFreeWidget *widget, uint8_t tag) {
+uint8_t eve_freew_get_tag_idx(EVEFreeWidget *widget, uint8_t tag) {
EVEWidget *_widget = &widget->w;
return tag - _widget->tag0;
-} \ No newline at end of file
+}
diff --git a/fw/fe310/eos/eve/widget/freew.h b/fw/fe310/eos/eve/widget/freew.h
index cbcd08b..82038c4 100644
--- a/fw/fe310/eos/eve/widget/freew.h
+++ b/fw/fe310/eos/eve/widget/freew.h
@@ -5,11 +5,13 @@ struct EVEWidgetSpec;
typedef void (*eve_freew_draw_t) (struct EVEFreeWidget *);
typedef int (*eve_freew_touch_t) (struct EVEFreeWidget *, EVETouch *, uint16_t);
+typedef void (*eve_freew_uievt_t) (struct EVEFreeWidget *, uint16_t);
typedef struct EVEFreeWidget {
EVEWidget w;
eve_freew_draw_t _draw;
eve_freew_touch_t _touch;
+ eve_freew_uievt_t _uievt;
} EVEFreeWidget;
typedef struct EVEFreeSpec {
@@ -18,11 +20,14 @@ typedef struct EVEFreeSpec {
eve_kbd_input_handler_t putc;
} EVEFreeSpec;
-void eve_freew_init(EVEFreeWidget *widget, EVERect *g, EVEPage *page, eve_freew_draw_t draw, eve_freew_touch_t touch, eve_kbd_input_handler_t putc);
+int eve_freew_init(EVEFreeWidget *widget, EVERect *g, EVEPage *page, eve_freew_draw_t draw, eve_freew_touch_t touch, eve_kbd_input_handler_t putc);
+void eve_freew_set_uievt_handler(EVEFreeWidget *widget, eve_freew_uievt_t handler);
int eve_freew_create(EVEWidget *_widget, struct EVEWidgetSpec *spec, EVEPage *page);
uint8_t eve_freew_draw(EVEWidget *_widget, uint8_t tag0);
int eve_freew_touch(EVEWidget *_widget, EVETouch *touch, uint16_t evt);
-uint8_t eve_freew_tag(EVEFreeWidget *widget);
-uint8_t eve_widget_tag_index(EVEFreeWidget *widget, uint8_t tag); \ No newline at end of file
+uint8_t eve_freew_tag0(EVEFreeWidget *widget);
+void eve_freew_tag(EVEFreeWidget *widget, uint8_t tag_opt);
+void eve_freew_tag_idx(EVEFreeWidget *widget, uint8_t i);
+uint8_t eve_freew_get_tag_idx(EVEFreeWidget *widget, uint8_t tag);
diff --git a/fw/fe310/eos/eve/widget/label.c b/fw/fe310/eos/eve/widget/label.c
index 43c710c..d596677 100644
--- a/fw/fe310/eos/eve/widget/label.c
+++ b/fw/fe310/eos/eve/widget/label.c
@@ -10,26 +10,31 @@
#include "label.h"
-void eve_label_init(EVELabel *label, EVERect *g, EVEFont *font, char *title) {
+int eve_label_init(EVELabel *label, EVERect *g, EVEFont *font, char *title) {
size_t title_len;
int title_w, rv;
- memset(label, 0, sizeof(EVELabel));
- if (g) label->g = *g;
+ if (font == NULL) return EVE_ERR;
- rv = eve_font_verify(font, label->title, &title_w, &title_len);
- if (rv) title[title_len] = '\0';
+ rv = eve_font_verify(font, title, 0, &title_w, &title_len);
+ if (rv) return rv;
+ memset(label, 0, sizeof(EVELabel));
+ if (g) label->g = *g;
label->font = font;
label->title = title;
if (label->g.h == 0) label->g.h = eve_font_h(font);
if (label->g.w == 0) label->g.w = title_w + EVE_LABEL_MARGIN;
+
+ return EVE_OK;
}
-void eve_label_create(EVELabel *label, EVELabelSpec *spec, EVEPage *page) {
+int eve_label_create(EVELabel *label, EVELabelSpec *spec, EVEPage *page) {
EVEFont *font = spec->font ? spec->font : eve_window_font(page->v.window);
+ int rv;
- eve_label_init(label, &spec->g, font, spec->title);
+ rv = eve_label_init(label, &spec->g, font, spec->title);
+ return rv;
}
void eve_label_draw(EVELabel *label) {
diff --git a/fw/fe310/eos/eve/widget/label.h b/fw/fe310/eos/eve/widget/label.h
index 9992f8c..f9c192b 100644
--- a/fw/fe310/eos/eve/widget/label.h
+++ b/fw/fe310/eos/eve/widget/label.h
@@ -15,7 +15,7 @@ typedef struct EVELabelSpec {
int16_t margin;
} EVELabelSpec;
-void eve_label_init(EVELabel *label, EVERect *g, EVEFont *font, char *title);
+int eve_label_init(EVELabel *label, EVERect *g, EVEFont *font, char *title);
-void eve_label_create(EVELabel *label, EVELabelSpec *spec, EVEPage *page);
+int eve_label_create(EVELabel *label, EVELabelSpec *spec, EVEPage *page);
void eve_label_draw(EVELabel *label); \ No newline at end of file
diff --git a/fw/fe310/eos/eve/widget/pagew.c b/fw/fe310/eos/eve/widget/pagew.c
index 77e8f01..0ce4e82 100644
--- a/fw/fe310/eos/eve/widget/pagew.c
+++ b/fw/fe310/eos/eve/widget/pagew.c
@@ -10,8 +10,12 @@
#include "widget.h"
-void eve_pagew_init(EVEPageWidget *widget, EVERect *g, EVEPage *page, EVEFont *font, char *title, eve_view_constructor_t constructor) {
+int eve_pagew_init(EVEPageWidget *widget, EVERect *g, EVEPage *page, EVEFont *font, char *title, eve_view_constructor_t constructor) {
EVEWidget *_widget = &widget->w;
+ int title_w, rv;
+
+ rv = eve_font_verify(font, title, 0, &title_w, NULL);
+ if (rv) return rv;
memset(widget, 0, sizeof(EVEPageWidget));
eve_widget_init(_widget, EVE_WIDGET_TYPE_PAGE, g, page, eve_pagew_draw, eve_pagew_touch, NULL);
@@ -19,16 +23,19 @@ void eve_pagew_init(EVEPageWidget *widget, EVERect *g, EVEPage *page, EVEFont *f
widget->title = title;
widget->constructor = constructor;
if (_widget->g.h == 0) _widget->g.h = eve_font_h(widget->font);
+ if (_widget->g.w == 0) _widget->g.w = title_w;
+
+ return EVE_OK;
}
int eve_pagew_create(EVEWidget *_widget, EVEWidgetSpec *spec, EVEPage *page) {
EVEPageWidget *widget = (EVEPageWidget *)_widget;
EVEPageSpec *tspec = &spec->tspec.page;
EVEFont *font = tspec->font ? tspec->font : eve_window_font(page->v.window);
+ int rv;
- eve_pagew_init(widget, &spec->g, page, font, tspec->title, tspec->constructor);
-
- return EVE_OK;
+ rv = eve_pagew_init(widget, &spec->g, page, font, tspec->title, tspec->constructor);
+ return rv;
}
uint8_t eve_pagew_draw(EVEWidget *_widget, uint8_t tag0) {
@@ -50,6 +57,9 @@ int eve_pagew_touch(EVEWidget *_widget, EVETouch *touch, uint16_t evt) {
EVEPage *parent = _widget->page;
EVEPageWidget *widget = (EVEPageWidget *)_widget;
+ /* widget received non-touch event, always return 0 */
+ if (evt & EVE_TOUCH_ETYPE_EXT) return 0;
+
if (evt & EVE_TOUCH_ETYPE_TAG_UP) {
eve_page_open(parent, widget->constructor);
return 1;
diff --git a/fw/fe310/eos/eve/widget/pagew.h b/fw/fe310/eos/eve/widget/pagew.h
index b1a91b2..9a1f1a1 100644
--- a/fw/fe310/eos/eve/widget/pagew.h
+++ b/fw/fe310/eos/eve/widget/pagew.h
@@ -15,7 +15,7 @@ typedef struct EVEPageSpec {
eve_view_constructor_t constructor;
} EVEPageSpec;
-void eve_pagew_init(EVEPageWidget *widget, EVERect *g, EVEPage *page, EVEFont *font, char *title, eve_view_constructor_t constructor);
+int eve_pagew_init(EVEPageWidget *widget, EVERect *g, EVEPage *page, EVEFont *font, char *title, eve_view_constructor_t constructor);
int eve_pagew_create(EVEWidget *_widget, struct EVEWidgetSpec *spec, EVEPage *page);
uint8_t eve_pagew_draw(EVEWidget *_widget, uint8_t tag0);
diff --git a/fw/fe310/eos/eve/widget/selectw.c b/fw/fe310/eos/eve/widget/selectw.c
index f0dfed9..c0e2bfe 100644
--- a/fw/fe310/eos/eve/widget/selectw.c
+++ b/fw/fe310/eos/eve/widget/selectw.c
@@ -14,19 +14,26 @@
#define DIVC(x,y) ((x) / (y) + ((x) % (y) != 0))
-static int selectw_verify(utf8_t *option, uint16_t option_size) {
+static int selectw_verify(utf8_t *option, uint16_t option_size, EVEFont *font, size_t *_o_len) {
size_t o_len;
uint16_t o_curr;
int rv;
o_curr = 0;
while (o_curr < option_size) {
- rv = utf8_verify(option + o_curr, option_size - o_curr, &o_len);
- if (rv) return EVE_ERR;
- if (o_len == 0) return EVE_OK;
+ rv = eve_font_verify(font, option + o_curr, option_size - o_curr, NULL, &o_len);
+ if (rv) {
+ if (_o_len) *_o_len = o_curr;
+ return rv;
+ }
o_curr += o_len + 1;
+ if (o_len == 0) {
+ if (_o_len) *_o_len = o_curr;
+ return EVE_OK;
+ }
}
+ if (_o_len) *_o_len = o_curr;
return EVE_OK;
}
@@ -57,28 +64,32 @@ static void selectw_update_sz(EVESelectWidget *widget, int uievt) {
if (uievt) eve_view_uievt_push(&page->v, EVE_UIEVT_WIDGET_UPDATE_G, _widget);
}
-void eve_selectw_init(EVESelectWidget *widget, EVERect *g, EVEPage *page, EVEFont *font, utf8_t *option, uint16_t option_size, uint8_t multi) {
+int eve_selectw_init(EVESelectWidget *widget, EVERect *g, EVEPage *page, EVEFont *font, utf8_t *option, uint16_t option_size, uint8_t multi) {
EVEWidget *_widget = &widget->w;
int rv;
+ rv = selectw_verify(option, option_size, font, NULL);
+ if (rv) return rv;
+
memset(widget, 0, sizeof(EVESelectWidget));
eve_widget_init(_widget, EVE_WIDGET_TYPE_SELECT, g, page, eve_selectw_draw, eve_selectw_touch, NULL);
+
widget->font = font;
- rv = selectw_verify(option, option_size);
- if (rv == EVE_OK) {
- widget->option = option;
- widget->option_size = option_size;
- widget->option_count = selectw_count(widget);
- selectw_update_sz(widget, 0);
- }
+ widget->option = option;
+ widget->option_size = option_size;
+ widget->option_count = selectw_count(widget);
+ selectw_update_sz(widget, 0);
+
widget->multi = multi;
widget->select = widget->multi ? 0 : SELECTW_NOSELECT;
+
+ return EVE_OK;
}
int eve_selectw_update(EVESelectWidget *widget) {
int rv, i;
- rv = selectw_verify(widget->option, widget->option_size);
+ rv = selectw_verify(widget->option, widget->option_size, widget->font, NULL);
if (rv) return rv;
widget->option_count = selectw_count(widget);
@@ -92,6 +103,7 @@ int eve_selectw_create(EVEWidget *_widget, EVEWidgetSpec *spec, EVEPage *page) {
EVESelectSpec *tspec = &spec->tspec.select;
EVEFont *font = tspec->font ? tspec->font : eve_window_font(page->v.window);
utf8_t *option;
+ int rv;
option = eve_malloc(tspec->option_size);
if (option == NULL) {
@@ -99,9 +111,8 @@ int eve_selectw_create(EVEWidget *_widget, EVEWidgetSpec *spec, EVEPage *page) {
}
memset(option, 0, tspec->option_size);
- eve_selectw_init(widget, &spec->g, page, font, option, tspec->option_size, tspec->multi);
-
- return EVE_OK;
+ rv = eve_selectw_init(widget, &spec->g, page, font, option, tspec->option_size, tspec->multi);
+ return rv;
}
void eve_selectw_destroy(EVEWidget *_widget) {
@@ -172,6 +183,10 @@ uint8_t eve_selectw_draw(EVEWidget *_widget, uint8_t tag0) {
int eve_selectw_touch(EVEWidget *_widget, EVETouch *touch, uint16_t evt) {
EVESelectWidget *widget = (EVESelectWidget *)_widget;
+ EVEPage *page = _widget->page;
+
+ /* widget received non-touch event, always return 0 */
+ if (evt & EVE_TOUCH_ETYPE_EXT) return 0;
if (evt & EVE_TOUCH_ETYPE_TAG_UP) {
int i = touch->tag0 - _widget->tag0 + widget->line0;
@@ -192,6 +207,8 @@ int eve_selectw_touch(EVEWidget *_widget, EVETouch *touch, uint16_t evt) {
}
}
+ eve_view_uievt_push(&page->v, EVE_UIEVT_WIDGET_UPDATE, _widget);
+
return 1;
}
@@ -226,8 +243,8 @@ int eve_selectw_add_option(EVESelectWidget *widget, utf8_t *option) {
int o_curr;
int rv, i;
- rv = utf8_verify(option, strlen(option) + 1, NULL);
- if (rv) return EVE_ERR;
+ rv = eve_font_verify(widget->font, option, 0, NULL, NULL);
+ if (rv) return rv;
o_curr = 0;
i = 0;
@@ -252,10 +269,11 @@ int eve_selectw_add_option(EVESelectWidget *widget, utf8_t *option) {
int eve_selectw_set_option(EVESelectWidget *widget, utf8_t *option, uint16_t option_size) {
int rv, i;
- rv = selectw_verify(option, option_size);
- if (rv) return rv;
if (option_size > widget->option_size) return EVE_ERR_FULL;
+ rv = selectw_verify(option, option_size, widget->font, NULL);
+ if (rv) return rv;
+
memcpy(widget->option, option, option_size);
memset(widget->option + option_size, 0, widget->option_size - option_size);
@@ -264,3 +282,23 @@ int eve_selectw_set_option(EVESelectWidget *widget, utf8_t *option, uint16_t opt
return EVE_OK;
}
+
+void eve_selectw_fix_option(EVESelectWidget *widget, utf8_t *option, uint16_t option_size) {
+ size_t good_l, bad_l;
+ int rv;
+
+ do {
+ rv = selectw_verify(option, option_size, widget->font, &good_l);
+ if (rv == EVE_OK) return;
+
+ option += good_l;
+ option_size -= good_l;
+
+ bad_l = strnlen(option, option_size);
+ if (bad_l != option_size) {
+ bad_l++;
+ }
+ memmove(option, option + bad_l, option_size - bad_l);
+ memset(option + option_size - bad_l, 0, bad_l);
+ } while (bad_l != option_size);
+}
diff --git a/fw/fe310/eos/eve/widget/selectw.h b/fw/fe310/eos/eve/widget/selectw.h
index aa49866..185d787 100644
--- a/fw/fe310/eos/eve/widget/selectw.h
+++ b/fw/fe310/eos/eve/widget/selectw.h
@@ -19,7 +19,7 @@ typedef struct EVESelectSpec {
uint8_t multi;
} EVESelectSpec;
-void eve_selectw_init(EVESelectWidget *widget, EVERect *g, EVEPage *page, EVEFont *font, utf8_t *option, uint16_t option_size, uint8_t multi);
+int eve_selectw_init(EVESelectWidget *widget, EVERect *g, EVEPage *page, EVEFont *font, utf8_t *option, uint16_t option_size, uint8_t multi);
int eve_selectw_update(EVESelectWidget *widget);
int eve_selectw_create(EVEWidget *_widget, struct EVEWidgetSpec *spec, EVEPage *page);
@@ -31,3 +31,4 @@ utf8_t *eve_selectw_option(EVESelectWidget *widget, int idx);
utf8_t *eve_selectw_option_selected(EVESelectWidget *widget);
int eve_selectw_add_option(EVESelectWidget *widget, utf8_t *option);
int eve_selectw_set_option(EVESelectWidget *widget, utf8_t *option, uint16_t option_size);
+void eve_selectw_fix_option(EVESelectWidget *widget, utf8_t *option, uint16_t option_size);
diff --git a/fw/fe310/eos/eve/widget/spacerw.c b/fw/fe310/eos/eve/widget/spacerw.c
index aa5bec1..f597a2d 100644
--- a/fw/fe310/eos/eve/widget/spacerw.c
+++ b/fw/fe310/eos/eve/widget/spacerw.c
@@ -10,15 +10,18 @@
#include "widget.h"
-void eve_spacerw_init(EVEWidget *widget, EVERect *g, EVEPage *page) {
+int eve_spacerw_init(EVEWidget *widget, EVERect *g, EVEPage *page) {
memset(widget, 0, sizeof(EVEWidget));
eve_widget_init(widget, EVE_WIDGET_TYPE_SPACER, g, page, eve_spacerw_draw, eve_spacerw_touch, NULL);
+
+ return EVE_OK;
}
int eve_spacerw_create(EVEWidget *_widget, EVEWidgetSpec *spec, EVEPage *page) {
- eve_spacerw_init(_widget, &spec->g, page);
+ int rv;
- return EVE_OK;
+ rv = eve_spacerw_init(_widget, &spec->g, page);
+ return rv;
}
uint8_t eve_spacerw_draw(EVEWidget *_widget, uint8_t tag0) {
diff --git a/fw/fe310/eos/eve/widget/spacerw.h b/fw/fe310/eos/eve/widget/spacerw.h
index 621b45b..ae97479 100644
--- a/fw/fe310/eos/eve/widget/spacerw.h
+++ b/fw/fe310/eos/eve/widget/spacerw.h
@@ -2,7 +2,7 @@
struct EVEWidgetSpec;
-void eve_spacerw_init(EVEWidget *widget, EVERect *g, EVEPage *page);
+int eve_spacerw_init(EVEWidget *widget, EVERect *g, EVEPage *page);
int eve_spacerw_create(EVEWidget *_widget, struct EVEWidgetSpec *spec, EVEPage *page);
uint8_t eve_spacerw_draw(EVEWidget *_widget, uint8_t tag0);
diff --git a/fw/fe310/eos/eve/widget/strw.c b/fw/fe310/eos/eve/widget/strw.c
index 6a2692b..847de49 100644
--- a/fw/fe310/eos/eve/widget/strw.c
+++ b/fw/fe310/eos/eve/widget/strw.c
@@ -12,7 +12,7 @@
#include "widget.h"
-#define STRW_TOUCH_OPT EVE_TOUCH_OPT_TRACK | EVE_TOUCH_OPT_TRACK_X | EVE_TOUCH_OPT_TRACK_EXT_X | EVE_TOUCH_OPT_LPRESS
+#define STRW_TOUCH_OPT EVE_TOUCH_OPT_TRACK_X | EVE_TOUCH_OPT_TRACK_EXT_X | EVE_TOUCH_OPT_LPRESS
#define STRW_TMODE_NONE 0
#define STRW_TMODE_CRSR 1
@@ -27,37 +27,33 @@
#define CHAR_VALID_INPUT(c) ((c >= 0x20) && (c < 0x7f))
-void eve_strw_init(EVEStrWidget *widget, EVERect *g, EVEPage *page, EVEFont *font, utf8_t *str, uint16_t str_size) {
+int eve_strw_init(EVEStrWidget *widget, EVERect *g, EVEPage *page, EVEFont *font, utf8_t *str, uint16_t str_size) {
EVEWidget *_widget = &widget->w;
size_t str_len;
int str_w, rv;
+ rv = eve_font_verify(font, str, str_size, &str_w, &str_len);
+ if (rv) return rv;
+
memset(widget, 0, sizeof(EVEStrWidget));
eve_widget_init(_widget, EVE_WIDGET_TYPE_STR, g, page, eve_strw_draw, eve_strw_touch, eve_strw_putc);
- rv = utf8_verify(str, str_size, &str_len);
- if (rv) str[str_len] = '\0';
-
- rv = eve_font_verify(font, str, &str_w, &str_len);
- if (rv) str[str_len] = '\0';
-
widget->font = font;
widget->str = str;
widget->str_size = str_size;
widget->str_len = str_len;
widget->str_g.w = str_w;
if (_widget->g.h == 0) _widget->g.h = eve_font_h(widget->font);
+
+ return EVE_OK;
}
int eve_strw_update(EVEStrWidget *widget) {
size_t str_len;
int str_w, rv;
- rv = utf8_verify(widget->str, widget->str_size, &str_len);
- if (rv) widget->str[str_len] = '\0';
-
- rv = eve_font_verify(widget->font, widget->str, &str_w, &str_len);
- if (rv) widget->str[str_len] = '\0';
+ rv = eve_font_verify(widget->font, widget->str, widget->str_size, &str_w, &str_len);
+ if (rv) return rv;
widget->str_len = str_len;
widget->str_g.w = str_w;
@@ -71,14 +67,15 @@ int eve_strw_create(EVEWidget *_widget, EVEWidgetSpec *spec, EVEPage *page) {
EVEFont *font = tspec->font ? tspec->font : eve_window_font(page->v.window);
utf8_t *str;
uint16_t *line;
+ int rv;
str = eve_malloc(tspec->str_size);
if (str == NULL) return EVE_ERR_NOMEM;
str[0] = '\0';
- eve_strw_init(widget, &spec->g, page, font, str, tspec->str_size);
-
- return EVE_OK;
+ rv = eve_strw_init(widget, &spec->g, page, font, str, tspec->str_size);
+ if (rv) eve_free(str);
+ return rv;
}
void eve_strw_destroy(EVEWidget *_widget) {
@@ -87,15 +84,20 @@ void eve_strw_destroy(EVEWidget *_widget) {
eve_free(widget->str);
}
-static void show_rect(EVEStrWidget *widget) {
+static void show_text(EVEStrWidget *widget, EVEStrCursor *cursor, int del_w) {
EVEWidget *_widget = &widget->w;
- EVERect focus;
+ int w0 = widget->font->w;
+ int w1 = _widget->g.w - widget->font->w;
- focus.x = _widget->g.x;
- focus.y = _widget->g.y;
- focus.w = _widget->g.w;
- focus.h = 2 * widget->font->h;
- eve_page_show_rect(_widget->page, &focus);
+ if (del_w && (widget->str_g.w - widget->str_g.x < w1)) {
+ widget->str_g.x = (widget->str_g.x > del_w ? widget->str_g.x - del_w : 0);
+ }
+ if (cursor->x - widget->str_g.x < w0) {
+ widget->str_g.x = (cursor->x > w0 ? cursor->x - w0 : 0);
+ }
+ if (cursor->x - widget->str_g.x > w1) {
+ widget->str_g.x = cursor->x - w1;
+ }
}
static EVEStrCursor *cursor_prox(EVEStrWidget *widget, EVEStrCursor *cursor, EVETouch *touch, short *dx) {
@@ -156,7 +158,7 @@ uint8_t eve_strw_draw(EVEWidget *_widget, uint8_t tag0) {
_widget->tag0 = tag0;
if (tag0 != EVE_NOTAG) {
eve_cmd_dl(TAG(tag0));
- eve_touch_set_opt(tag0, STRW_TOUCH_OPT);
+ eve_tag_set_opt(tag0, STRW_TOUCH_OPT);
tag0++;
}
_widget->tagN = tag0;
@@ -228,7 +230,22 @@ int eve_strw_touch(EVEWidget *_widget, EVETouch *touch, uint16_t evt) {
EVEPage *page = _widget->page;
EVEStrCursor *t_cursor = NULL;
short dx;
- int ret = 0;
+ int rv = 0;
+
+ /* widget received non-touch event */
+ if (evt & EVE_TOUCH_ETYPE_EXT) {
+ evt &= ~EVE_TOUCH_ETYPE_EXT;
+ switch (evt) {
+ case EVE_UIEVT_WIDGET_FOCUS_OUT: {
+ if (widget->cursor1.on) eve_strw_cursor_clear(widget, &widget->cursor1);
+ if (widget->cursor2.on) eve_strw_cursor_clear(widget, &widget->cursor2);
+ break;
+ }
+ }
+
+ /* always return 0 for non-touch events */
+ return 0;
+ }
if (evt & (EVE_TOUCH_ETYPE_LPRESS | EVE_TOUCH_ETYPE_TRACK_START)) {
if (widget->cursor2.on) {
@@ -266,10 +283,11 @@ int eve_strw_touch(EVEWidget *_widget, EVETouch *touch, uint16_t evt) {
case STRW_TMODE_CRSR:
eve_strw_cursor_set(widget, widget->track.cursor, eve_page_x(page, touch->x) + widget->track.dx);
+ show_text(widget, widget->track.cursor, 0);
break;
}
}
- ret = 1;
+ rv = 1;
} else {
if (evt & EVE_TOUCH_ETYPE_LPRESS) {
if (widget->cursor2.on) {
@@ -283,13 +301,12 @@ int eve_strw_touch(EVEWidget *_widget, EVETouch *touch, uint16_t evt) {
} else {
// select
}
- ret = 1;
+ rv = 1;
}
- if ((evt & EVE_TOUCH_ETYPE_POINT_UP) && !(touch->eevt & (EVE_TOUCH_EETYPE_TRACK_XY | EVE_TOUCH_EETYPE_ABORT | EVE_TOUCH_EETYPE_LPRESS))) {
+ if ((evt & EVE_TOUCH_ETYPE_POINT_UP) && !(touch->eevt & (EVE_TOUCH_EETYPE_TRACK_XY | EVE_TOUCH_EETYPE_TRACK_ABORT | EVE_TOUCH_EETYPE_LPRESS))) {
eve_strw_cursor_set(widget, &widget->cursor1, eve_page_x(page, touch->x0));
if (widget->cursor2.on) eve_strw_cursor_clear(widget, &widget->cursor2);
- show_rect(widget);
- ret = 1;
+ rv = 1;
}
}
@@ -299,7 +316,7 @@ int eve_strw_touch(EVEWidget *_widget, EVETouch *touch, uint16_t evt) {
widget->track.dx = 0;
}
- return ret;
+ return rv;
}
void eve_strw_putc(void *w, int c) {
@@ -309,19 +326,18 @@ void eve_strw_putc(void *w, int c) {
EVEStrCursor *cursor2 = &widget->cursor2;
utf8_t *str;
utf8_t *clipb = NULL;
- int w0 = widget->font->w;
- int w1 = _widget->g.w - widget->font->w;
int ins_c = 0, del_c = 0;
int ins_w = 0, del_w = 0;
- if (c == EVE_PAGE_KBDCH_CLOSE) {
- if (cursor1->on) eve_strw_cursor_clear(widget, cursor1);
- if (cursor2->on) eve_strw_cursor_clear(widget, cursor2);
+ if (!cursor1->on) return;
+
+ if (c == '\n') {
+ EVEPage *page = _widget->page;
+
+ eve_view_uievt_push(&page->v, EVE_UIEVT_WIDGET_UPDATE, _widget);
return;
}
- if (!cursor1->on) return;
-
if (!cursor2->on && ((c == CH_BS) || (c == CH_DEL))) {
ucp_t uc;
@@ -349,10 +365,6 @@ void eve_strw_putc(void *w, int c) {
}
break;
}
- if (widget->str_g.w - widget->str_g.x < w1) {
- widget->str_g.x -= del_w;
- if (widget->str_g.x < 0) widget->str_g.x = 0;
- }
} else {
EVEStrCursor *c1 = cursor1;
EVEStrCursor *c2 = cursor1;
@@ -387,9 +399,8 @@ void eve_strw_putc(void *w, int c) {
clipb = eve_clipb_get();
if (clipb) {
- rv = utf8_verify(clipb, EVE_CLIPB_SIZE_BUF, &clipb_len);
- if (!rv) ins_w = eve_font_str_w(widget->font, clipb);
- if (rv || (ins_w < 0)) {
+ rv = eve_font_verify(widget->font, clipb, EVE_CLIPB_SIZE_BUF, &ins_w, &clipb_len);
+ if (rv) {
clipb = NULL;
clipb_len = 0;
ins_w = 0;
@@ -419,8 +430,7 @@ void eve_strw_putc(void *w, int c) {
if (cursor2->on) eve_strw_cursor_clear(widget, cursor2);
}
- if (cursor1->x - widget->str_g.x < w0) widget->str_g.x = cursor1->x > w0 ? cursor1->x - w0 : 0;
- if (cursor1->x - widget->str_g.x > w1) widget->str_g.x = cursor1->x - w1;
+ show_text(widget, cursor1, del_w);
}
void eve_strw_cursor_set(EVEStrWidget *widget, EVEStrCursor *cursor, int16_t x) {
diff --git a/fw/fe310/eos/eve/widget/strw.h b/fw/fe310/eos/eve/widget/strw.h
index acfd74b..a2817d0 100644
--- a/fw/fe310/eos/eve/widget/strw.h
+++ b/fw/fe310/eos/eve/widget/strw.h
@@ -33,7 +33,7 @@ typedef struct EVEStrSpec {
uint16_t str_size;
} EVEStrSpec;
-void eve_strw_init(EVEStrWidget *widget, EVERect *g, EVEPage *page, EVEFont *font, utf8_t *str, uint16_t str_size);
+int eve_strw_init(EVEStrWidget *widget, EVERect *g, EVEPage *page, EVEFont *font, utf8_t *str, uint16_t str_size);
int eve_strw_update(EVEStrWidget *widget);
int eve_strw_create(EVEWidget *_widget, struct EVEWidgetSpec *spec, EVEPage *page);
diff --git a/fw/fe310/eos/eve/widget/textw.c b/fw/fe310/eos/eve/widget/textw.c
index 7998e75..0a6a700 100644
--- a/fw/fe310/eos/eve/widget/textw.c
+++ b/fw/fe310/eos/eve/widget/textw.c
@@ -12,7 +12,7 @@
#include "widget.h"
-#define TEXTW_TOUCH_OPT EVE_TOUCH_OPT_TRACK | EVE_TOUCH_OPT_TRACK_XY | EVE_TOUCH_OPT_TRACK_EXT_XY | EVE_TOUCH_OPT_LPRESS
+#define TEXTW_TOUCH_OPT EVE_TOUCH_OPT_TRACK_XY | EVE_TOUCH_OPT_TRACK_EXT_XY | EVE_TOUCH_OPT_LPRESS
#define CH_BS 0x08
#define CH_DEL 0x7f
@@ -30,20 +30,17 @@
#define DIVC(x,y) ((x) / (y) + ((x) % (y) != 0))
-void eve_textw_init(EVETextWidget *widget, EVERect *g, EVEPage *page, EVEFont *font, utf8_t *text, uint16_t text_size, uint16_t *line, uint16_t line_size) {
+int eve_textw_init(EVETextWidget *widget, EVERect *g, EVEPage *page, EVEFont *font, utf8_t *text, uint16_t text_size, uint16_t *line, uint16_t line_size) {
EVEWidget *_widget = &widget->w;
size_t text_len;
int rv;
+ rv = eve_font_verify(font, text, text_size, NULL, &text_len);
+ if (rv) return rv;
+
memset(widget, 0, sizeof(EVETextWidget));
eve_widget_init(_widget, EVE_WIDGET_TYPE_TEXT, g, page, eve_textw_draw, eve_textw_touch, eve_textw_putc);
- rv = utf8_verify(text, text_size, &text_len);
- if (rv) text[text_len] = '\0';
-
- rv = eve_font_verify(font, text, NULL, &text_len);
- if (rv) text[text_len] = '\0';
-
widget->font = font;
widget->text = text;
widget->text_size = text_size;
@@ -52,17 +49,16 @@ void eve_textw_init(EVETextWidget *widget, EVERect *g, EVEPage *page, EVEFont *f
widget->line_size = line_size;
memset(widget->line, 0xff, line_size * sizeof(uint16_t));
eve_textw_text_update(widget, 0, 0);
+
+ return EVE_OK;
}
int eve_textw_update(EVETextWidget *widget) {
size_t text_len;
int rv;
- rv = utf8_verify(widget->text, widget->text_size, &text_len);
- if (rv) widget->text[text_len] = '\0';
-
- rv = eve_font_verify(widget->font, widget->text, NULL, &text_len);
- if (rv) widget->text[text_len] = '\0';
+ rv = eve_font_verify(widget->font, widget->text, widget->text_size, NULL, &text_len);
+ if (rv) return rv;
widget->text_len = text_len;
memset(widget->line, 0xff, widget->line_size * sizeof(uint16_t));
@@ -77,6 +73,7 @@ int eve_textw_create(EVEWidget *_widget, EVEWidgetSpec *spec, EVEPage *page) {
EVEFont *font = tspec->font ? tspec->font : eve_window_font(page->v.window);
utf8_t *text;
uint16_t *line;
+ int rv;
text = eve_malloc(tspec->text_size);
if (text == NULL) {
@@ -89,9 +86,12 @@ int eve_textw_create(EVEWidget *_widget, EVEWidgetSpec *spec, EVEPage *page) {
return EVE_ERR_NOMEM;
}
- eve_textw_init(widget, &spec->g, page, font, text, tspec->text_size, line, tspec->line_size);
-
- return EVE_OK;
+ rv = eve_textw_init(widget, &spec->g, page, font, text, tspec->text_size, line, tspec->line_size);
+ if (rv) {
+ eve_free(line);
+ eve_free(text);
+ }
+ return rv;
}
void eve_textw_destroy(EVEWidget *_widget) {
@@ -214,7 +214,7 @@ uint8_t eve_textw_draw(EVEWidget *_widget, uint8_t tag0) {
for (i=line0; i<lineN; i++) {
if (_widget->tagN != EVE_NOTAG) {
eve_cmd_dl(TAG(_widget->tagN));
- eve_touch_set_opt(_widget->tagN, TEXTW_TOUCH_OPT);
+ eve_tag_set_opt(_widget->tagN, TEXTW_TOUCH_OPT);
_widget->tagN++;
}
if (!s && c1 && (c1->line == i)) {
@@ -257,7 +257,7 @@ uint8_t eve_textw_draw(EVEWidget *_widget, uint8_t tag0) {
if (lineNvisible) {
if (_widget->tagN != EVE_NOTAG) {
eve_cmd_dl(TAG(_widget->tagN));
- eve_touch_set_opt(_widget->tagN, TEXTW_TOUCH_OPT);
+ eve_tag_set_opt(_widget->tagN, TEXTW_TOUCH_OPT);
_widget->tagN++;
}
draw_line(widget, lineN, 0, 0, 0, _widget->g.w, 0);
@@ -276,7 +276,27 @@ int eve_textw_touch(EVEWidget *_widget, EVETouch *touch, uint16_t evt) {
EVEPage *page = _widget->page;
EVETextCursor *t_cursor = NULL;
short dx, dl;
- int ret = 0;
+ int rv = 0;
+
+ /* widget received non-touch event */
+ if (evt & EVE_TOUCH_ETYPE_EXT) {
+ evt &= ~EVE_TOUCH_ETYPE_EXT;
+ switch (evt) {
+ case EVE_UIEVT_WIDGET_FOCUS_IN: {
+ if (widget->cursor1.on) show_rect(widget, &widget->cursor1);
+ break;
+ }
+
+ case EVE_UIEVT_WIDGET_FOCUS_OUT: {
+ if (widget->cursor1.on) eve_textw_cursor_clear(widget, &widget->cursor1);
+ if (widget->cursor2.on) eve_textw_cursor_clear(widget, &widget->cursor2);
+ break;
+ }
+ }
+
+ /* always return 0 for non-touch events */
+ return 0;
+ }
if (evt & (EVE_TOUCH_ETYPE_LPRESS | EVE_TOUCH_ETYPE_TRACK_START)) {
if (widget->cursor2.on) {
@@ -294,7 +314,7 @@ int eve_textw_touch(EVEWidget *_widget, EVETouch *touch, uint16_t evt) {
if (widget->track.cursor) {
if (evt & EVE_TOUCH_ETYPE_TRACK) eve_textw_cursor_set(widget, widget->track.cursor, touch->tag + widget->track.dl, eve_page_x(page, touch->x) + widget->track.dx);
- ret = 1;
+ rv = 1;
} else {
if (evt & EVE_TOUCH_ETYPE_LPRESS) {
if (widget->cursor2.on) {
@@ -308,13 +328,12 @@ int eve_textw_touch(EVEWidget *_widget, EVETouch *touch, uint16_t evt) {
} else {
// select
}
- ret = 1;
+ rv = 1;
}
- if ((evt & EVE_TOUCH_ETYPE_TAG_UP) && !(touch->eevt & (EVE_TOUCH_EETYPE_TRACK_XY | EVE_TOUCH_EETYPE_ABORT | EVE_TOUCH_EETYPE_LPRESS))) {
+ if ((evt & EVE_TOUCH_ETYPE_TAG_UP) && !(touch->eevt & (EVE_TOUCH_EETYPE_TRACK_XY | EVE_TOUCH_EETYPE_TRACK_ABORT | EVE_TOUCH_EETYPE_LPRESS))) {
eve_textw_cursor_set(widget, &widget->cursor1, touch->tag_up, eve_page_x(page, touch->x0));
if (widget->cursor2.on) eve_textw_cursor_clear(widget, &widget->cursor2);
- show_rect(widget, &widget->cursor1);
- ret = 1;
+ rv = 1;
}
}
@@ -324,7 +343,7 @@ int eve_textw_touch(EVEWidget *_widget, EVETouch *touch, uint16_t evt) {
widget->track.dl = 0;
}
- return ret;
+ return rv;
}
void eve_textw_putc(void *w, int c) {
@@ -334,16 +353,10 @@ void eve_textw_putc(void *w, int c) {
EVETextCursor *cursor2 = &widget->cursor2;
utf8_t *text;
utf8_t *clipb = NULL;
- int i, r;
+ int i, line;
int ins_c = 0, del_c = 0;
int ch_w = 0;
- if (c == EVE_PAGE_KBDCH_CLOSE) {
- if (cursor1->on) eve_textw_cursor_clear(widget, cursor1);
- if (cursor2->on) eve_textw_cursor_clear(widget, cursor2);
- return;
- }
-
if (!cursor1->on) return;
if (!cursor2->on && ((c == CH_BS) || (c == CH_DEL))) {
@@ -401,9 +414,8 @@ void eve_textw_putc(void *w, int c) {
clipb = eve_clipb_get();
if (clipb) {
- rv = utf8_verify(clipb, EVE_CLIPB_SIZE_BUF, &clipb_len);
- if (!rv) ch_w = eve_font_str_w(widget->font, clipb);
- if (rv || (ch_w < 0)) {
+ rv = eve_font_verify(widget->font, clipb, EVE_CLIPB_SIZE_BUF, &ch_w, &clipb_len);
+ if (rv) {
clipb = NULL;
clipb_len = 0;
ch_w = 0;
@@ -437,9 +449,9 @@ void eve_textw_putc(void *w, int c) {
widget->line[i] += ins_c - del_c;
}
- r = cursor1->line;
- if (cursor1->line) r = eve_textw_text_update(widget, cursor1->line - 1, 1);
- if (r == cursor1->line) eve_textw_text_update(widget, cursor1->line, 1);
+ line = cursor1->line;
+ if (cursor1->line) line = eve_textw_text_update(widget, cursor1->line - 1, 1);
+ if (line == cursor1->line) eve_textw_text_update(widget, cursor1->line, 1);
if (cursor1->line && (cursor1->ch < LINE_START(widget, cursor1->line))) {
while (cursor1->line && (cursor1->ch < LINE_START(widget, cursor1->line))) cursor1->line--;
@@ -449,7 +461,7 @@ void eve_textw_putc(void *w, int c) {
while ((cursor1->line != widget->line_len - 1) && (cursor1->ch > LINE_END(widget, cursor1->line))) cursor1->line++;
eve_textw_cursor_update(widget, cursor1);
show_rect(widget, cursor1);
- } else if ((cursor1->line) && (r != cursor1->line)) {
+ } else if ((cursor1->line) && (line != cursor1->line)) {
eve_textw_cursor_update(widget, cursor1);
} else {
cursor1->x += ch_w;
diff --git a/fw/fe310/eos/eve/widget/textw.h b/fw/fe310/eos/eve/widget/textw.h
index 0fb3505..d3d544b 100644
--- a/fw/fe310/eos/eve/widget/textw.h
+++ b/fw/fe310/eos/eve/widget/textw.h
@@ -34,7 +34,7 @@ typedef struct EVETextSpec {
uint16_t line_size;
} EVETextSpec;
-void eve_textw_init(EVETextWidget *widget, EVERect *g, EVEPage *page, EVEFont *font, utf8_t *text, uint16_t text_size, uint16_t *line, uint16_t line_size);
+int eve_textw_init(EVETextWidget *widget, EVERect *g, EVEPage *page, EVEFont *font, utf8_t *text, uint16_t text_size, uint16_t *line, uint16_t line_size);
int eve_textw_update(EVETextWidget *widget);
int eve_textw_create(EVEWidget *_widget, struct EVEWidgetSpec *spec, EVEPage *page);
diff --git a/fw/fe310/eos/eve/widget/togglew.c b/fw/fe310/eos/eve/widget/togglew.c
index c68e191..06d5fc3 100644
--- a/fw/fe310/eos/eve/widget/togglew.c
+++ b/fw/fe310/eos/eve/widget/togglew.c
@@ -10,7 +10,7 @@
#include "widget.h"
-void eve_togglew_init(EVEToggleWidget *widget, EVERect *g, EVEPage *page, EVEFont *font, char *labels) {
+int eve_togglew_init(EVEToggleWidget *widget, EVERect *g, EVEPage *page, EVEFont *font, char *labels) {
EVEWidget *_widget = &widget->w;
memset(widget, 0, sizeof(EVEToggleWidget));
@@ -18,16 +18,18 @@ void eve_togglew_init(EVEToggleWidget *widget, EVERect *g, EVEPage *page, EVEFon
widget->font = font;
widget->labels = labels;
if (_widget->g.h == 0) _widget->g.h = eve_font_h(widget->font);
+
+ return EVE_OK;
}
int eve_togglew_create(EVEWidget *_widget, EVEWidgetSpec *spec, EVEPage *page) {
EVEToggleWidget *widget = (EVEToggleWidget *)_widget;
EVEToggleSpec *tspec = &spec->tspec.toggle;
EVEFont *font = tspec->font ? tspec->font : eve_window_font(page->v.window);
+ int rv;
- eve_togglew_init(widget, &spec->g, page, font, tspec->labels);
-
- return EVE_OK;
+ rv = eve_togglew_init(widget, &spec->g, page, font, tspec->labels);
+ return rv;
}
uint8_t eve_togglew_draw(EVEWidget *_widget, uint8_t tag0) {
@@ -46,23 +48,30 @@ uint8_t eve_togglew_draw(EVEWidget *_widget, uint8_t tag0) {
int eve_togglew_touch(EVEWidget *_widget, EVETouch *touch, uint16_t evt) {
EVEToggleWidget *widget = (EVEToggleWidget *)_widget;
+ EVEPage *page = _widget->page;
+
+ /* widget received non-touch event, always return 0 */
+ if (evt & EVE_TOUCH_ETYPE_EXT) return 0;
if (evt & EVE_TOUCH_ETYPE_TAG_UP) {
widget->state = !widget->state;
+
+ eve_view_uievt_push(&page->v, EVE_UIEVT_WIDGET_UPDATE, _widget);
+
return 1;
}
return 0;
}
+uint8_t eve_togglew_get(EVEToggleWidget *widget) {
+ return widget->state;
+}
+
void eve_togglew_set(EVEToggleWidget *widget) {
widget->state = 1;
}
-void eve_togglew_clr(EVEToggleWidget *widget) {
+void eve_togglew_clear(EVEToggleWidget *widget) {
widget->state = 0;
}
-
-uint8_t eve_togglew_get(EVEToggleWidget *widget) {
- return widget->state;
-} \ No newline at end of file
diff --git a/fw/fe310/eos/eve/widget/togglew.h b/fw/fe310/eos/eve/widget/togglew.h
index aa5485d..af37672 100644
--- a/fw/fe310/eos/eve/widget/togglew.h
+++ b/fw/fe310/eos/eve/widget/togglew.h
@@ -17,12 +17,12 @@ typedef struct EVEToggleSpec {
uint8_t state;
} EVEToggleSpec;
-void eve_togglew_init(EVEToggleWidget *widget, EVERect *g, EVEPage *page, EVEFont *font, char *labels);
+int eve_togglew_init(EVEToggleWidget *widget, EVERect *g, EVEPage *page, EVEFont *font, char *labels);
int eve_togglew_create(EVEWidget *_widget, struct EVEWidgetSpec *spec, EVEPage *page);
uint8_t eve_togglew_draw(EVEWidget *_widget, uint8_t tag0);
int eve_togglew_touch(EVEWidget *_widget, EVETouch *touch, uint16_t evt);
+uint8_t eve_togglew_get(EVEToggleWidget *widget);
void eve_togglew_set(EVEToggleWidget *widget);
-void eve_togglew_clr(EVEToggleWidget *widget);
-uint8_t eve_togglew_get(EVEToggleWidget *widget); \ No newline at end of file
+void eve_togglew_clear(EVEToggleWidget *widget);
diff --git a/fw/fe310/eos/eve/widget/widget.c b/fw/fe310/eos/eve/widget/widget.c
index 88b90a9..8b0a2e4 100644
--- a/fw/fe310/eos/eve/widget/widget.c
+++ b/fw/fe310/eos/eve/widget/widget.c
@@ -49,16 +49,10 @@ void eve_widget_destroy(EVEWidget *widget) {
if (_eve_widget_destroy[widget->type]) _eve_widget_destroy[widget->type](widget);
}
-void eve_widget_set_focus(EVEWidget *widget) {
- EVEPage *page = widget->page;
-
- eve_page_set_focus(page, widget);
-}
-
void eve_widget_set_flags(EVEWidget *widget, uint8_t flags) {
widget->flags |= flags;
}
-void eve_widget_clr_flags(EVEWidget *widget, uint8_t flags) {
+void eve_widget_clear_flags(EVEWidget *widget, uint8_t flags) {
widget->flags &= ~flags;
}
diff --git a/fw/fe310/eos/eve/widget/widget.h b/fw/fe310/eos/eve/widget/widget.h
index a565b53..e7ab2f2 100644
--- a/fw/fe310/eos/eve/widget/widget.h
+++ b/fw/fe310/eos/eve/widget/widget.h
@@ -45,6 +45,5 @@ size_t eve_widget_size(uint8_t type);
void eve_widget_set_label(EVEWidget *widget, EVELabel *label);
EVEWidget *eve_widget_next(EVEWidget *widget);
-void eve_widget_set_focus(EVEWidget *widget);
void eve_widget_set_flags(EVEWidget *widget, uint8_t flags);
-void eve_widget_clr_flags(EVEWidget *widget, uint8_t flags); \ No newline at end of file
+void eve_widget_clear_flags(EVEWidget *widget, uint8_t flags); \ No newline at end of file
diff --git a/fw/fe310/eos/event.c b/fw/fe310/eos/event.c
index f76384a..b21e5ea 100644
--- a/fw/fe310/eos/event.c
+++ b/fw/fe310/eos/event.c
@@ -1,69 +1,110 @@
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
-#include <stdio.h>
#include "encoding.h"
#include "platform.h"
#include "eos.h"
+#include "log.h"
#include "msgq.h"
#include "event.h"
EOSMsgQ _eos_event_q;
static EOSMsgItem event_q_array[EOS_EVT_SIZE_Q];
-static eos_evt_handler_t evt_handler[EOS_EVT_MAX_EVT + 1];
+static eos_evt_handler_t evt_handler[EOS_EVT_MAX];
+static eos_evt_handler_global_t evt_handler_global;
+static eos_evt_loopf_t evt_loop_f;
-static void evtq_handler(unsigned char type, unsigned char *buffer, uint16_t len) {
+static void evtq_handler(unsigned char type, unsigned char *buffer, uint16_t len, uint8_t _idx) {
unsigned char idx = (type & EOS_EVT_MASK) >> 4;
- if (idx && (idx <= EOS_EVT_MAX_EVT)) {
- evt_handler[idx](type, buffer, len);
+ if (idx && (idx <= EOS_EVT_MAX)) {
+ evt_handler[idx - 1](type, buffer, len);
} else {
eos_evtq_bad_handler(type, buffer, len);
}
}
-int eos_evtq_init(uint8_t wakeup_cause) {
+int eos_evtq_init(void) {
int i;
- evt_handler[0] = evtq_handler;
- for (i=0; i<EOS_EVT_MAX_EVT; i++) {
- evt_handler[i + 1] = eos_evtq_bad_handler;
+ evt_handler_global = evtq_handler;
+ for (i=0; i<EOS_EVT_MAX; i++) {
+ evt_handler[i] = eos_evtq_bad_handler;
}
eos_msgq_init(&_eos_event_q, event_q_array, EOS_EVT_SIZE_Q);
return EOS_OK;
}
+int eos_evtq_len(void) {
+ int rv;
+
+ clear_csr(mstatus, MSTATUS_MIE);
+ rv = eos_msgq_len(&_eos_event_q);
+ set_csr(mstatus, MSTATUS_MIE);
+
+ return rv;
+}
+
int eos_evtq_push(unsigned char type, unsigned char *buffer, uint16_t len) {
+ int rv;
+
+ clear_csr(mstatus, MSTATUS_MIE);
+ rv = eos_msgq_push(&_eos_event_q, type, buffer, len);
+ set_csr(mstatus, MSTATUS_MIE);
+
+ return rv;
+}
+
+int eos_evtq_push_widx(unsigned char type, unsigned char *buffer, uint16_t len, uint8_t *idx) {
+ int rv;
+
clear_csr(mstatus, MSTATUS_MIE);
- int ret = eos_msgq_push(&_eos_event_q, type, buffer, len);
+ rv = eos_msgq_push_widx(&_eos_event_q, type, buffer, len, idx);
set_csr(mstatus, MSTATUS_MIE);
- return ret;
+
+ return rv;
}
int eos_evtq_push_isr(unsigned char type, unsigned char *buffer, uint16_t len) {
return eos_msgq_push(&_eos_event_q, type, buffer, len);
}
+int eos_evtq_push_widx_isr(unsigned char type, unsigned char *buffer, uint16_t len, uint8_t *idx) {
+ return eos_msgq_push_widx(&_eos_event_q, type, buffer, len, idx);
+}
+
void eos_evtq_pop(unsigned char *type, unsigned char **buffer, uint16_t *len) {
clear_csr(mstatus, MSTATUS_MIE);
eos_msgq_pop(&_eos_event_q, type, buffer, len);
set_csr(mstatus, MSTATUS_MIE);
}
+void eos_evtq_pop_widx(unsigned char *type, unsigned char **buffer, uint16_t *len, uint8_t *idx) {
+ clear_csr(mstatus, MSTATUS_MIE);
+ eos_msgq_pop_widx(&_eos_event_q, type, buffer, len, idx);
+ set_csr(mstatus, MSTATUS_MIE);
+}
+
void eos_evtq_pop_isr(unsigned char *type, unsigned char **buffer, uint16_t *len) {
eos_msgq_pop(&_eos_event_q, type, buffer, len);
}
+void eos_evtq_pop_widx_isr(unsigned char *type, unsigned char **buffer, uint16_t *len, uint8_t *idx) {
+ eos_msgq_pop_widx(&_eos_event_q, type, buffer, len, idx);
+}
+
int eos_evtq_get(unsigned char type, unsigned char **buffer, uint16_t *len) {
int rv = 0;
clear_csr(mstatus, MSTATUS_MIE);
rv = eos_msgq_find(&_eos_event_q, type, NULL, 0, buffer, len);
set_csr(mstatus, MSTATUS_MIE);
+
+ return rv;
}
int eos_evtq_find(unsigned char type, unsigned char *selector, uint16_t sel_len, unsigned char **buffer, uint16_t *len) {
@@ -72,23 +113,30 @@ int eos_evtq_find(unsigned char type, unsigned char *selector, uint16_t sel_len,
clear_csr(mstatus, MSTATUS_MIE);
rv = eos_msgq_find(&_eos_event_q, type, selector, sel_len, buffer, len);
set_csr(mstatus, MSTATUS_MIE);
+
+ return rv;
}
-void eos_evtq_wait(unsigned char type, unsigned char *selector, uint16_t sel_len, unsigned char **buffer, uint16_t *len) {
+int eos_evtq_wait(unsigned char type, unsigned char *selector, uint16_t sel_len, unsigned char **buffer, uint16_t *len) {
int rv = 0;
while(!rv) {
clear_csr(mstatus, MSTATUS_MIE);
rv = eos_msgq_find(&_eos_event_q, type, selector, sel_len, buffer, len);
- if (!rv) {
+ if (rv && (rv != EOS_ERR_NOTFOUND)) {
+ set_csr(mstatus, MSTATUS_MIE);
+ return rv;
+ }
+ if (rv) {
unsigned char _type;
unsigned char *_buffer;
uint16_t _len;
+ uint8_t idx;
- eos_msgq_pop(&_eos_event_q, &_type, &_buffer, &_len);
+ eos_msgq_pop_widx(&_eos_event_q, &_type, &_buffer, &_len, &idx);
if (_type) {
set_csr(mstatus, MSTATUS_MIE);
- evt_handler[0](_type, _buffer, _len);
+ evt_handler_global(_type, _buffer, _len, idx);
} else {
asm volatile ("wfi");
set_csr(mstatus, MSTATUS_MIE);
@@ -109,12 +157,13 @@ void eos_evtq_flush_isr(void) {
unsigned char type;
unsigned char *buffer;
uint16_t len;
+ uint8_t idx;
do {
- eos_msgq_pop(&_eos_event_q, &type, &buffer, &len);
+ eos_msgq_pop_widx(&_eos_event_q, &type, &buffer, &len, &idx);
if (type) {
set_csr(mstatus, MSTATUS_MIE);
- evt_handler[0](type, buffer, len);
+ evt_handler_global(type, buffer, len, idx);
clear_csr(mstatus, MSTATUS_MIE);
}
} while (type);
@@ -125,6 +174,7 @@ void eos_evtq_loop(void) {
while(foo) {
eos_evtq_exec();
+ if (evt_loop_f) evt_loop_f();
}
}
@@ -132,33 +182,46 @@ void eos_evtq_exec(void) {
unsigned char type;
unsigned char *buffer;
uint16_t len;
+ uint8_t idx;
clear_csr(mstatus, MSTATUS_MIE);
- eos_msgq_pop(&_eos_event_q, &type, &buffer, &len);
+ eos_msgq_pop_widx(&_eos_event_q, &type, &buffer, &len, &idx);
if (type) {
set_csr(mstatus, MSTATUS_MIE);
- evt_handler[0](type, buffer, len);
+ evt_handler_global(type, buffer, len, idx);
} else {
asm volatile ("wfi");
set_csr(mstatus, MSTATUS_MIE);
}
+}
+void eos_evtq_set_loopf(eos_evt_loopf_t loop_f) {
+ evt_loop_f = loop_f;
}
+
void eos_evtq_bad_handler(unsigned char type, unsigned char *buffer, uint16_t len) {
- printf("EVT BAD HANDLER:0x%x\n", type);
+ EOS_LOG(EOS_LOG_ERR, "EVT BAD HANDLER:0x%.2X\n", type);
}
void eos_evtq_set_handler(unsigned char type, eos_evt_handler_t handler) {
unsigned char idx = (type & EOS_EVT_MASK) >> 4;
if (handler == NULL) handler = eos_evtq_bad_handler;
- if (idx <= EOS_EVT_MAX_EVT) evt_handler[idx] = handler;
+ if (idx && (idx <= EOS_EVT_MAX)) evt_handler[idx - 1] = handler;
}
eos_evt_handler_t eos_evtq_get_handler(unsigned char type) {
unsigned char idx = (type & EOS_EVT_MASK) >> 4;
- if (idx <= EOS_EVT_MAX_EVT) return evt_handler[idx];
+ if (idx && (idx <= EOS_EVT_MAX)) return evt_handler[idx - 1];
return NULL;
}
+
+void eos_evtq_set_handler_global(eos_evt_handler_global_t handler) {
+ evt_handler_global = handler;
+}
+
+eos_evt_handler_global_t eos_evtq_get_handler_global(void) {
+ return evt_handler_global;
+}
diff --git a/fw/fe310/eos/event.h b/fw/fe310/eos/event.h
index 9501a15..bdc1af1 100644
--- a/fw/fe310/eos/event.h
+++ b/fw/fe310/eos/event.h
@@ -3,20 +3,35 @@
#include "evt_def.h"
typedef void (*eos_evt_handler_t) (unsigned char, unsigned char *, uint16_t);
+typedef void (*eos_evt_handler_global_t) (unsigned char, unsigned char *, uint16_t, uint8_t);
+
+typedef void (*eos_evt_loopf_t) (void);
+
+int eos_evtq_init(void);
+int eos_evtq_len(void);
-int eos_evtq_init(uint8_t wakeup_cause);
int eos_evtq_push(unsigned char type, unsigned char *buffer, uint16_t len);
+int eos_evtq_push_widx(unsigned char type, unsigned char *buffer, uint16_t len, uint8_t *idx);
int eos_evtq_push_isr(unsigned char type, unsigned char *buffer, uint16_t len);
+int eos_evtq_push_widx_isr(unsigned char type, unsigned char *buffer, uint16_t len, uint8_t *idx);
+
void eos_evtq_pop(unsigned char *type, unsigned char **buffer, uint16_t *len);
+void eos_evtq_pop_widx(unsigned char *type, unsigned char **buffer, uint16_t *len, uint8_t *idx) ;
void eos_evtq_pop_isr(unsigned char *type, unsigned char **buffer, uint16_t *len);
+void eos_evtq_pop_widx_isr(unsigned char *type, unsigned char **buffer, uint16_t *len, uint8_t *idx);
+
int eos_evtq_get(unsigned char type, unsigned char **buffer, uint16_t *len);
int eos_evtq_find(unsigned char type, unsigned char *selector, uint16_t sel_len, unsigned char **buffer, uint16_t *len);
-void eos_evtq_wait(unsigned char type, unsigned char *selector, uint16_t sel_len, unsigned char **buffer, uint16_t *len);
+int eos_evtq_wait(unsigned char type, unsigned char *selector, uint16_t sel_len, unsigned char **buffer, uint16_t *len);
+
void eos_evtq_flush(void);
void eos_evtq_flush_isr(void);
void eos_evtq_loop(void);
void eos_evtq_exec(void);
+void eos_evtq_set_loopf(eos_evt_loopf_t loop_f);
void eos_evtq_bad_handler(unsigned char type, unsigned char *buffer, uint16_t len);
void eos_evtq_set_handler(unsigned char type, eos_evt_handler_t handler);
eos_evt_handler_t eos_evtq_get_handler(unsigned char type);
+void eos_evtq_set_handler_global(eos_evt_handler_global_t handler);
+eos_evt_handler_global_t eos_evtq_get_handler_global(void);
diff --git a/fw/fe310/eos/evt_def.h b/fw/fe310/eos/evt_def.h
index e34b2d2..0105457 100644
--- a/fw/fe310/eos/evt_def.h
+++ b/fw/fe310/eos/evt_def.h
@@ -3,11 +3,11 @@
#define EOS_EVT_NET 0x30
#define EOS_EVT_SPI 0x40
#define EOS_EVT_UART 0x50
-#define EOS_EVT_EVE 0x60
-#define EOS_EVT_CTP 0x70
-#define EOS_EVT_USER 0x80
+#define EOS_EVT_EGPIO 0x60
+#define EOS_EVT_USER 0x70
+#define EOS_EVT_USER1 0x80
-#define EOS_EVT_MAX_EVT 8
+#define EOS_EVT_MAX 8
#define EOS_EVT_MASK 0xF0
#define EOS_EVT_SIZE_Q 4
diff --git a/fw/fe310/eos/irq_def.h b/fw/fe310/eos/irq_def.h
index fc16489..62a2b90 100644
--- a/fw/fe310/eos/irq_def.h
+++ b/fw/fe310/eos/irq_def.h
@@ -1,8 +1,7 @@
-#define IRQ_PRIORITY_I2S_SD 7
-
-#define IRQ_PRIORITY_EVE 5
-#define IRQ_PRIORITY_CTP 5
+#define IRQ_PRIORITY_I2S 7
+#define IRQ_PRIORITY_CTP 6
+#define IRQ_PRIORITY_EGPIO 5
#define IRQ_PRIORITY_SPI_XCHG 5
#define IRQ_PRIORITY_NET_CTS 4
diff --git a/fw/fe310/eos/log.h b/fw/fe310/eos/log.h
new file mode 100644
index 0000000..be9b024
--- /dev/null
+++ b/fw/fe310/eos/log.h
@@ -0,0 +1,15 @@
+#include <stdio.h>
+
+#define EOS_LOG_DEBUG 1
+#define EOS_LOG_INFO 2
+#define EOS_LOG_ERR 3
+
+#define EOS_LOG_NONE 255
+
+#ifdef EOS_DEBUG
+#define EOS_LOG_LEVEL EOS_LOG_DEBUG
+#else
+#define EOS_LOG_LEVEL EOS_LOG_NONE
+#endif
+
+#define EOS_LOG(l, ...) ((l) >= EOS_LOG_LEVEL ? printf(__VA_ARGS__) : 0 )
diff --git a/fw/fe310/eos/msgq.c b/fw/fe310/eos/msgq.c
index a483a58..2af3b14 100644
--- a/fw/fe310/eos/msgq.c
+++ b/fw/fe310/eos/msgq.c
@@ -17,7 +17,15 @@ void eos_msgq_init(EOSMsgQ *msgq, EOSMsgItem *array, uint8_t size) {
msgq->array = array;
}
+uint8_t eos_msgq_len(EOSMsgQ *msgq) {
+ return (uint8_t)(msgq->idx_w - msgq->idx_r);
+}
+
int eos_msgq_push(EOSMsgQ *msgq, unsigned char type, unsigned char *buffer, uint16_t len) {
+ return eos_msgq_push_widx(msgq, type, buffer, len, NULL);
+}
+
+int eos_msgq_push_widx(EOSMsgQ *msgq, unsigned char type, unsigned char *buffer, uint16_t len, uint8_t *_idx) {
if ((uint8_t)(msgq->idx_w - msgq->idx_r) == msgq->size) return EOS_ERR_FULL;
uint8_t idx = IDX_MASK(msgq->idx_w, msgq->size);
@@ -25,10 +33,15 @@ int eos_msgq_push(EOSMsgQ *msgq, unsigned char type, unsigned char *buffer, uint
msgq->array[idx].buffer = buffer;
msgq->array[idx].len = len;
msgq->idx_w++;
+ if (_idx) *_idx = idx;
return EOS_OK;
}
void eos_msgq_pop(EOSMsgQ *msgq, unsigned char *type, unsigned char **buffer, uint16_t *len) {
+ eos_msgq_pop_widx(msgq, type, buffer, len, NULL);
+}
+
+void eos_msgq_pop_widx(EOSMsgQ *msgq, unsigned char *type, unsigned char **buffer, uint16_t *len, uint8_t *_idx) {
if (msgq->idx_r == msgq->idx_w) {
*type = 0;
*buffer = NULL;
@@ -39,6 +52,7 @@ void eos_msgq_pop(EOSMsgQ *msgq, unsigned char *type, unsigned char **buffer, ui
*buffer = msgq->array[idx].buffer;
*len = msgq->array[idx].len;
msgq->idx_r++;
+ if (_idx) *_idx = idx;
}
}
@@ -52,7 +66,7 @@ int eos_msgq_find(EOSMsgQ *msgq, unsigned char type, unsigned char *selector, ui
*buffer = NULL;
*len = 0;
}
- return 0;
+ return EOS_ERR_NOTFOUND;
}
idx = IDX_MASK(msgq->idx_r, msgq->size);
@@ -65,7 +79,7 @@ int eos_msgq_find(EOSMsgQ *msgq, unsigned char type, unsigned char *selector, ui
*buffer = _buffer;
*len = _len;
}
- return 1;
+ return EOS_OK;
}
}
for (i = msgq->idx_r + 1; IDX_LT(i, msgq->idx_w); i++) {
@@ -82,7 +96,7 @@ int eos_msgq_find(EOSMsgQ *msgq, unsigned char type, unsigned char *selector, ui
*buffer = _buffer;
*len = _len;
}
- return 1;
+ return EOS_OK;
}
}
}
@@ -90,11 +104,7 @@ int eos_msgq_find(EOSMsgQ *msgq, unsigned char type, unsigned char *selector, ui
*buffer = NULL;
*len = 0;
}
- return 0;
-}
-
-uint8_t eos_msgq_len(EOSMsgQ *msgq) {
- return (uint8_t)(msgq->idx_w - msgq->idx_r);
+ return EOS_ERR_NOTFOUND;
}
void eos_bufq_init(EOSBufQ *bufq, unsigned char **array, uint8_t size) {
@@ -104,6 +114,10 @@ void eos_bufq_init(EOSBufQ *bufq, unsigned char **array, uint8_t size) {
bufq->array = array;
}
+uint8_t eos_bufq_len(EOSBufQ *bufq) {
+ return (uint8_t)(bufq->idx_w - bufq->idx_r);
+}
+
int eos_bufq_push(EOSBufQ *bufq, unsigned char *buffer) {
if ((uint8_t)(bufq->idx_w - bufq->idx_r) == bufq->size) return EOS_ERR_FULL;
@@ -116,7 +130,3 @@ unsigned char *eos_bufq_pop(EOSBufQ *bufq) {
return bufq->array[IDX_MASK(bufq->idx_r++, bufq->size)];
}
-
-uint8_t eos_bufq_len(EOSBufQ *bufq) {
- return (uint8_t)(bufq->idx_w - bufq->idx_r);
-}
diff --git a/fw/fe310/eos/msgq.h b/fw/fe310/eos/msgq.h
index 7e3b5e5..0634144 100644
--- a/fw/fe310/eos/msgq.h
+++ b/fw/fe310/eos/msgq.h
@@ -14,10 +14,12 @@ typedef struct EOSMsgQ {
} EOSMsgQ;
void eos_msgq_init(EOSMsgQ *msgq, EOSMsgItem *array, uint8_t size);
+uint8_t eos_msgq_len(EOSMsgQ *msgq);
int eos_msgq_push(EOSMsgQ *msgq, unsigned char type, unsigned char *buffer, uint16_t len);
+int eos_msgq_push_widx(EOSMsgQ *msgq, unsigned char type, unsigned char *buffer, uint16_t len, uint8_t *_idx);
void eos_msgq_pop(EOSMsgQ *msgq, unsigned char *type, unsigned char **buffer, uint16_t *len);
+void eos_msgq_pop_widx(EOSMsgQ *msgq, unsigned char *type, unsigned char **buffer, uint16_t *len, uint8_t *_idx);
int eos_msgq_find(EOSMsgQ *msgq, unsigned char type, unsigned char *selector, uint16_t sel_len, unsigned char **buffer, uint16_t *len);
-uint8_t eos_msgq_len(EOSMsgQ *msgq);
typedef struct EOSBufQ {
uint8_t idx_r;
@@ -27,6 +29,6 @@ typedef struct EOSBufQ {
} EOSBufQ;
void eos_bufq_init(EOSBufQ *bufq, unsigned char **array, uint8_t size);
+uint8_t eos_bufq_len(EOSBufQ *bufq);
int eos_bufq_push(EOSBufQ *bufq, unsigned char *buffer);
unsigned char *eos_bufq_pop(EOSBufQ *bufq);
-uint8_t eos_bufq_len(EOSBufQ *bufq);
diff --git a/fw/fe310/eos/net/Makefile b/fw/fe310/eos/net/Makefile
index fc65454..0646956 100644
--- a/fw/fe310/eos/net/Makefile
+++ b/fw/fe310/eos/net/Makefile
@@ -1,6 +1,6 @@
include ../../common.mk
-obj = rng.o pwr.o wifi.o sock.o cell.o
+obj = rng.o wifi.o sock.o cell.o
lib = ../../libeos-net.a
diff --git a/fw/fe310/eos/net/cell.c b/fw/fe310/eos/net/cell.c
index 96216ba..c0c77af 100644
--- a/fw/fe310/eos/net/cell.c
+++ b/fw/fe310/eos/net/cell.c
@@ -10,21 +10,21 @@
static eos_evt_handler_t evt_handler[EOS_CELL_MAX_MTYPE];
-static void cell_handle_msg(unsigned char type, unsigned char *buffer, uint16_t len) {
+static void cell_handle_msg(unsigned char type, unsigned char *buffer, uint16_t buf_len) {
unsigned char mtype;
unsigned char idx;
- if ((buffer == NULL) || (len < 1)) {
- eos_net_bad_handler(type, buffer, len);
+ if ((buffer == NULL) || (buf_len < 1)) {
+ eos_net_bad_handler(type, buffer, buf_len);
return;
}
mtype = buffer[0];
idx = (mtype & EOS_CELL_MTYPE_MASK) >> 4;
if ((idx < EOS_CELL_MAX_MTYPE) && evt_handler[idx]) {
- evt_handler[idx](mtype & ~EOS_CELL_MTYPE_MASK, buffer, len);
+ evt_handler[idx](mtype & ~EOS_CELL_MTYPE_MASK, buffer, buf_len);
} else {
- eos_net_bad_handler(type, buffer, len);
+ eos_net_bad_handler(type, buffer, buf_len);
}
}
@@ -52,32 +52,32 @@ eos_evt_handler_t eos_cell_get_handler(unsigned char mtype) {
int eos_cell_send_buffer(unsigned char *buffer, uint16_t buf_len, uint16_t offset, int sync) {
buffer -= offset;
- return eos_net_send_async(EOS_NET_MTYPE_CELL, buffer, buf_len + offset, 1);
+ return _eos_net_send(EOS_NET_MTYPE_CELL, buffer, buf_len + offset, !sync, 1);
}
-int eos_cell_status_parse(unsigned char *buffer, uint16_t len, uint8_t *status, uint8_t *connected) {
- if (len < 2) return EOS_ERR_SIZE;
+int eos_cell_status_parse(unsigned char *buffer, uint16_t buf_len, uint8_t *status, uint8_t *connected) {
+ if (buf_len < 2) return EOS_ERR_SIZE;
if (buffer[0] != (EOS_CELL_MTYPE_DEV | EOS_CELL_MTYPE_STATUS)) return EOS_ERR_NET;
buffer++;
- len--;
+ buf_len--;
*status = buffer[0];
buffer++;
- len--;
+ buf_len--;
if (*status == EOS_CELL_STATUS_PPP) {
- if (len < 1) return EOS_ERR_SIZE;
+ if (buf_len < 1) return EOS_ERR_SIZE;
if (connected) *connected = buffer[0];
buffer++;
- len--;
+ buf_len--;
}
return EOS_OK;
}
int eos_cell_status(uint8_t *status, uint8_t *connected, unsigned char *buffer) {
unsigned char type;
- uint16_t len;
+ uint16_t buf_len;
int do_release;
int rv;
@@ -88,10 +88,10 @@ int eos_cell_status(uint8_t *status, uint8_t *connected, unsigned char *buffer)
}
type = EOS_NET_MTYPE_CELL;
- len = 1;
+ buf_len = 1;
buffer[0] = EOS_CELL_MTYPE_DEV | EOS_CELL_MTYPE_STATUS;
- rv = eos_net_xchg(&type, buffer, &len);
+ rv = eos_net_xchg(&type, buffer, &buf_len);
if (rv) goto cell_status_fin;
if (type != EOS_NET_MTYPE_CELL) {
@@ -99,7 +99,7 @@ int eos_cell_status(uint8_t *status, uint8_t *connected, unsigned char *buffer)
goto cell_status_fin;
}
- rv = eos_cell_status_parse(buffer, len, status, connected);
+ rv = eos_cell_status_parse(buffer, buf_len, status, connected);
cell_status_fin:
if (do_release) eos_net_free(buffer, 1);
@@ -132,7 +132,7 @@ int eos_cell_uart_give(unsigned char *buffer, int sync) {
return _eos_net_send(EOS_NET_MTYPE_CELL, buffer, 1, async, 1);
}
-unsigned char *eos_cell_uart_data_buffer(uint16_t *offset) {
+unsigned char *eos_cell_uart_data_alloc(uint16_t *offset) {
unsigned char *buffer;
buffer = eos_net_alloc();
@@ -185,7 +185,7 @@ int eos_cell_voice_hangup(unsigned char *buffer, int sync) {
return _eos_net_send(EOS_NET_MTYPE_CELL, buffer, 1, async, 1);
}
-unsigned char *eos_cell_voice_pcm_buffer(uint16_t *offset) {
+unsigned char *eos_cell_voice_pcm_alloc(uint16_t *offset) {
unsigned char *buffer;
buffer = eos_net_alloc();
@@ -197,7 +197,7 @@ unsigned char *eos_cell_voice_pcm_buffer(uint16_t *offset) {
int eos_cell_sms_send(char *addr, char *txt, unsigned char *buffer, int sync) {
int async;
size_t addr_len, txt_len;
- uint16_t len;
+ uint16_t buf_len;
addr_len = strlen(addr);
txt_len = strlen(txt);
@@ -221,48 +221,48 @@ int eos_cell_sms_send(char *addr, char *txt, unsigned char *buffer, int sync) {
buffer[3] = EOS_CELL_SMS_ADDRTYPE_OTHER;
}
buffer[4] = addr_len;
- len = 5;
- memcpy(buffer + len, addr, addr_len);
- len += addr_len;
- memcpy(buffer + len, txt, txt_len);
- len += txt_len;
- return _eos_net_send(EOS_NET_MTYPE_CELL, buffer, len, async, 1);
+ buf_len = 5;
+ memcpy(buffer + buf_len, addr, addr_len);
+ buf_len += addr_len;
+ memcpy(buffer + buf_len, txt, txt_len);
+ buf_len += txt_len;
+ return _eos_net_send(EOS_NET_MTYPE_CELL, buffer, buf_len, async, 1);
}
-int _eos_cell_sms_parse(unsigned char *buffer, uint16_t len, char **addr, uint16_t *addr_len, char **txt, uint16_t *txt_len) {
+int _eos_cell_sms_parse(unsigned char *buffer, uint16_t buf_len, char **addr, uint16_t *addr_len, char **txt, uint16_t *txt_len) {
uint16_t _addr_len;
- if (len < 4 + EOS_CELL_SMS_SIZE_TS) return EOS_ERR_SIZE;
+ if (buf_len < 4 + EOS_CELL_SMS_SIZE_TS) return EOS_ERR_SIZE;
if (buffer[0] != (EOS_CELL_MTYPE_SMS | EOS_CELL_MTYPE_SMS_MSG)) return EOS_ERR_NET;
buffer += 3 + EOS_CELL_SMS_SIZE_TS;
- len -= 3 + EOS_CELL_SMS_SIZE_TS;
+ buf_len -= 3 + EOS_CELL_SMS_SIZE_TS;
_addr_len = *buffer;
if (_addr_len > EOS_CELL_SMS_SIZE_ADDR) return EOS_ERR_SIZE;
- if ((_addr_len == 0) || (len < (_addr_len + 1))) return EOS_ERR_SIZE;
+ if ((_addr_len == 0) || (buf_len < (_addr_len + 1))) return EOS_ERR_SIZE;
if (addr && addr_len) {
*addr = buffer + 1;
*addr_len = _addr_len;
}
buffer += _addr_len + 1;
- len -= _addr_len + 1;
+ buf_len -= _addr_len + 1;
- if (len > EOS_CELL_SMS_SIZE_TXT) return EOS_ERR_SIZE;
+ if (buf_len > EOS_CELL_SMS_SIZE_TXT) return EOS_ERR_SIZE;
if (txt && txt_len) {
*txt = buffer;
- *txt_len = len;
+ *txt_len = buf_len;
}
return EOS_OK;
}
-int eos_cell_sms_parse(unsigned char *buffer, uint16_t len, char *addr, uint16_t addr_size, char *txt, uint16_t txt_size) {
+int eos_cell_sms_parse(unsigned char *buffer, uint16_t buf_len, char *addr, uint16_t addr_size, char *txt, uint16_t txt_size) {
char *_addr, *_txt;
uint16_t _addr_len, _txt_len;
int rv;
- rv = _eos_cell_sms_parse(buffer, len, &_addr, &_addr_len, &_txt, &_txt_len);
+ rv = _eos_cell_sms_parse(buffer, buf_len, &_addr, &_addr_len, &_txt, &_txt_len);
if (rv) return rv;
if (addr_size < _addr_len + 1) return EOS_ERR_SIZE;
if (txt_size < _txt_len + 1) return EOS_ERR_SIZE;
@@ -276,7 +276,7 @@ int eos_cell_sms_parse(unsigned char *buffer, uint16_t len, char *addr, uint16_t
int eos_cell_pdp_get(unsigned char atype, char *arg, uint16_t arg_size, unsigned char *buffer) {
unsigned char type;
- uint16_t len;
+ uint16_t buf_len;
int do_release;
int rv;
@@ -287,24 +287,24 @@ int eos_cell_pdp_get(unsigned char atype, char *arg, uint16_t arg_size, unsigned
}
type = EOS_NET_MTYPE_CELL;
- len = 1;
+ buf_len = 1;
buffer[0] = EOS_CELL_MTYPE_PDP | atype;
- rv = eos_net_xchg(&type, buffer, &len);
+ rv = eos_net_xchg(&type, buffer, &buf_len);
if (rv) goto cell_pdp_get_fin;
- if ((type != EOS_NET_MTYPE_CELL) || (len == 0) || (buffer[0] != EOS_CELL_MTYPE_PDP | atype)) {
+ if ((type != EOS_NET_MTYPE_CELL) || (buf_len == 0) || (buffer[0] != EOS_CELL_MTYPE_PDP | atype)) {
rv = EOS_ERR_NET;
goto cell_pdp_get_fin;
}
- len--;
- if ((len > EOS_CELL_PDP_SIZE_ARG) || (len > arg_size - 1)) {
+ buf_len--;
+ if ((buf_len > EOS_CELL_PDP_SIZE_ARG) || (buf_len > arg_size - 1)) {
rv = EOS_ERR_SIZE;
goto cell_pdp_get_fin;
}
- memcpy(buffer + 1, arg, len);
- arg[len] = '\0';
+ memcpy(buffer + 1, arg, buf_len);
+ arg[buf_len] = '\0';
cell_pdp_get_fin:
if (do_release) eos_net_free(buffer, 1);
diff --git a/fw/fe310/eos/net/cell.h b/fw/fe310/eos/net/cell.h
index ac334e9..3264022 100644
--- a/fw/fe310/eos/net/cell.h
+++ b/fw/fe310/eos/net/cell.h
@@ -1,4 +1,5 @@
#include <stdint.h>
+
#include "../event.h"
#define EOS_CELL_MTYPE_DEV 0x10
@@ -27,7 +28,6 @@
#define EOS_CELL_MTYPE_VOICE_END 7
#define EOS_CELL_MTYPE_VOICE_MISS 8
#define EOS_CELL_MTYPE_VOICE_BUSY 9
-#define EOS_CELL_MTYPE_VOICE_ERR 10
#define EOS_CELL_MTYPE_SMS_MSG 1
#define EOS_CELL_MTYPE_SMS_LIST 2
@@ -73,20 +73,20 @@ void eos_cell_set_handler(unsigned char mtype, eos_evt_handler_t handler);
eos_evt_handler_t eos_cell_get_handler(unsigned char mtype);
int eos_cell_send_buffer(unsigned char *buffer, uint16_t buf_len, uint16_t offset, int sync);
-int eos_cell_status_parse(unsigned char *buffer, uint16_t len, uint8_t *status, uint8_t *connected);
+int eos_cell_status_parse(unsigned char *buffer, uint16_t buf_len, uint8_t *status, uint8_t *connected);
int eos_cell_status(uint8_t *status, uint8_t *connected, unsigned char *buffer);
int eos_cell_uart_take(unsigned char *buffer, int sync);
int eos_cell_uart_give(unsigned char *buffer, int sync);
-unsigned char *eos_cell_uart_data_buffer(uint16_t *offset);
+unsigned char *eos_cell_uart_data_alloc(uint16_t *offset);
int eos_cell_voice_dial(char *num, unsigned char *buffer, int sync);
int eos_cell_voice_answer(unsigned char *buffer, int sync);
int eos_cell_voice_hangup(unsigned char *buffer, int sync);
-unsigned char *eos_cell_voice_pcm_buffer(uint16_t *offset);
+unsigned char *eos_cell_voice_pcm_alloc(uint16_t *offset);
int eos_cell_sms_send(char *addr, char *txt, unsigned char *buffer, int sync);
-int _eos_cell_sms_parse(unsigned char *buffer, uint16_t len, char **addr, uint16_t *addr_len, char **txt, uint16_t *txt_len);
-int eos_cell_sms_parse(unsigned char *buffer, uint16_t len, char *addr, uint16_t addr_size, char *txt, uint16_t txt_size);
+int _eos_cell_sms_parse(unsigned char *buffer, uint16_t buf_len, char **addr, uint16_t *addr_len, char **txt, uint16_t *txt_len);
+int eos_cell_sms_parse(unsigned char *buffer, uint16_t buf_len, char *addr, uint16_t addr_size, char *txt, uint16_t txt_size);
int eos_cell_pdp_get(unsigned char atype, char *arg, uint16_t arg_size, unsigned char *buffer);
int eos_cell_pdp_set(unsigned char atype, char *arg, unsigned char *buffer, int sync);
diff --git a/fw/fe310/eos/net/pwr.c b/fw/fe310/eos/net/pwr.c
deleted file mode 100644
index 308a05a..0000000
--- a/fw/fe310/eos/net/pwr.c
+++ /dev/null
@@ -1,80 +0,0 @@
-#include <stdlib.h>
-#include <stdint.h>
-
-#include "eos.h"
-#include "event.h"
-#include "dev/net.h"
-
-#include "soc/pwr.h"
-#include "soc/spi.h"
-#include "dev/spi.h"
-#include "dev/net.h"
-#include "dev/lcd.h"
-#include "eve/eve.h"
-#include "dev/flash.h"
-
-#include "pwr.h"
-
-static eos_evt_handler_t evt_handler[EOS_PWR_MAX_MTYPE];
-static unsigned char power_btn_down;
-
-static void pwr_handle_msg(unsigned char type, unsigned char *buffer, uint16_t len) {
- unsigned char mtype;
-
- if ((buffer == NULL) || (len < 1)) {
- eos_net_bad_handler(type, buffer, len);
- return;
- }
-
- mtype = buffer[0];
- if ((mtype < EOS_PWR_MAX_MTYPE) && evt_handler[mtype]) {
- evt_handler[mtype](mtype, buffer, len);
- } else {
- eos_net_bad_handler(type, buffer, len);
- }
-}
-
-static void pwr_handle_btn(unsigned char type, unsigned char *buffer, uint16_t len) {
- int rv;
- unsigned char level = buffer[1];
-
- eos_net_free(buffer, 0);
- if (!level) {
- power_btn_down = 1;
- return;
- }
- if (!power_btn_down) return;
-
- rv = eos_lcd_sleep();
-
- rv = eos_spi_select(EOS_SPI_DEV_EVE);
- if (!rv) {
- eve_pwr_sleep();
- eos_spi_deselect();
- }
-
- rv = eos_net_sleep(1000);
-
- eos_flash_norm();
-
- eos_pwr_sleep();
-}
-
-void eos_pwr_net_init(void) {
- int i;
-
- for (i=0; i<EOS_PWR_MAX_MTYPE; i++) {
- evt_handler[i] = NULL;
- }
- eos_net_set_handler(EOS_NET_MTYPE_POWER, pwr_handle_msg);
- eos_pwr_set_handler(EOS_PWR_MTYPE_BUTTON, pwr_handle_btn);
-}
-
-void eos_pwr_set_handler(unsigned char mtype, eos_evt_handler_t handler) {
- if (mtype < EOS_PWR_MAX_MTYPE) evt_handler[mtype] = handler;
-}
-
-eos_evt_handler_t eos_pwr_get_handler(unsigned char mtype) {
- if (mtype < EOS_PWR_MAX_MTYPE) return evt_handler[mtype];
- return NULL;
-}
diff --git a/fw/fe310/eos/net/pwr.h b/fw/fe310/eos/net/pwr.h
deleted file mode 100644
index b82a96b..0000000
--- a/fw/fe310/eos/net/pwr.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#include <stdint.h>
-#include "../event.h"
-
-#define EOS_PWR_MTYPE_BUTTON 1
-
-#define EOS_PWR_MAX_MTYPE 2
-
-void eos_pwr_net_init(void);
-void eos_pwr_set_handler(unsigned char mtype, eos_evt_handler_t handler);
-eos_evt_handler_t eos_pwr_get_handler(unsigned char mtype);
diff --git a/fw/fe310/eos/net/sock.c b/fw/fe310/eos/net/sock.c
index c9934e8..c55b8e8 100644
--- a/fw/fe310/eos/net/sock.c
+++ b/fw/fe310/eos/net/sock.c
@@ -10,26 +10,40 @@
static eos_evt_handler_t evt_handler[EOS_SOCK_MAX_SOCK];
-static void sock_handle_msg(unsigned char type, unsigned char *buffer, uint16_t len) {
+static void sock_handle_msg(unsigned char type, unsigned char *buffer, uint16_t buf_len) {
unsigned char sock;
+ int i;
- if ((buffer == NULL) || (len < 2)) {
- eos_net_bad_handler(type, buffer, len);
- return;
- }
-
- sock = buffer[1];
- if ((sock == 0) || (sock > EOS_SOCK_MAX_SOCK) || (evt_handler[sock - 1] == NULL)) {
- eos_net_bad_handler(type, buffer, len);
+ if ((buffer == NULL) || (buf_len < 2)) {
+ eos_net_bad_handler(type, buffer, buf_len);
return;
}
switch(buffer[0]) {
- case EOS_SOCK_MTYPE_PKT:
- evt_handler[sock - 1](type, buffer, len);
+ case EOS_SOCK_MTYPE_PKT: {
+ sock = buffer[1];
+ if ((sock == 0) || (sock > EOS_SOCK_MAX_SOCK) || (evt_handler[sock - 1] == NULL)) {
+ eos_net_bad_handler(type, buffer, buf_len);
+ return;
+ }
+ evt_handler[sock - 1](type, buffer, buf_len);
+ break;
+ }
+
+ case EOS_SOCK_MTYPE_CLOSE: {
+ for (i=1; i<buf_len; i++) {
+ sock = buffer[i];
+ if ((sock == 0) || (sock > EOS_SOCK_MAX_SOCK) || (evt_handler[sock - 1] == NULL)) {
+ eos_net_bad_handler(type, buffer, buf_len);
+ return;
+ }
+ evt_handler[sock - 1](type, buffer, buf_len);
+ }
break;
+ }
+
default:
- eos_net_bad_handler(type, buffer, len);
+ eos_net_bad_handler(type, buffer, buf_len);
break;
}
}
@@ -54,7 +68,7 @@ eos_evt_handler_t eos_sock_get_handler(unsigned char sock) {
int eos_sock_open_udp(eos_evt_handler_t handler, unsigned char *buffer) {
unsigned char type;
- uint16_t len;
+ uint16_t buf_len;
int do_release;
int rv, sock;
@@ -65,23 +79,23 @@ int eos_sock_open_udp(eos_evt_handler_t handler, unsigned char *buffer) {
}
type = EOS_NET_MTYPE_SOCK;
- len = 1;
+ buf_len = 1;
buffer[0] = EOS_SOCK_MTYPE_OPEN_DGRAM;
- rv = eos_net_xchg(&type, buffer, &len);
+ rv = eos_net_xchg(&type, buffer, &buf_len);
if (rv) goto sock_open_udp_fin;
if (type != EOS_NET_MTYPE_SOCK) {
rv = EOS_ERR_NET;
goto sock_open_udp_fin;
}
- if (len < 2) {
+ if (buf_len < 2) {
rv = EOS_ERR_SIZE;
goto sock_open_udp_fin;
}
sock = buffer[1];
- if (sock == 0) {
+ if ((sock == 0) || (sock > EOS_SOCK_MAX_SOCK)) {
rv = EOS_ERR_NET;
goto sock_open_udp_fin;
}
@@ -108,7 +122,29 @@ void eos_sock_close(unsigned char sock, unsigned char *buffer) {
eos_sock_set_handler(sock, NULL);
}
-static int sock_send(unsigned char sock, unsigned char *msg, uint16_t msg_len, EOSNetAddr *addr, unsigned char *buffer) {
+int eos_sock_pkt_alloc(unsigned char **buffer, unsigned char *pkt, size_t pkt_len) {
+ *buffer = NULL;
+
+ if (pkt && (pkt_len + EOS_SOCK_SIZE_UDP_HDR > EOS_NET_SIZE_BUF)) return EOS_ERR_SIZE;
+
+ *buffer = eos_net_alloc();
+ *buffer += EOS_SOCK_SIZE_UDP_HDR;
+ if (pkt) memcpy(*buffer, pkt, pkt_len);
+
+ return EOS_OK;
+}
+
+unsigned char *eos_sock_buf2pkt(unsigned char *buf, uint16_t buf_len) {
+ if (buf_len < EOS_SOCK_SIZE_UDP_HDR) return NULL;
+
+ return buf + EOS_SOCK_SIZE_UDP_HDR;
+}
+
+unsigned char *eos_sock_pkt2buf(unsigned char *pkt) {
+ return pkt - EOS_SOCK_SIZE_UDP_HDR;
+}
+
+static void sock_sendto(unsigned char sock, EOSNetAddr *addr, unsigned char *buffer) {
buffer[0] = EOS_SOCK_MTYPE_PKT;
buffer[1] = sock;
buffer += 2;
@@ -117,46 +153,47 @@ static int sock_send(unsigned char sock, unsigned char *msg, uint16_t msg_len, E
buffer[0] = addr->port >> 8;
buffer[1] = addr->port;
buffer += sizeof(addr->port);
- if (msg) {
- if (msg_len + EOS_SOCK_SIZE_UDP_HDR > EOS_NET_SIZE_BUF) return EOS_ERR_SIZE;
- memcpy(buffer, msg, msg_len);
- }
-
- return EOS_OK;
}
-int eos_sock_sendto(unsigned char sock, unsigned char *msg, size_t msg_len, EOSNetAddr *addr, unsigned char *buffer) {
+int eos_sock_sendto(unsigned char sock, EOSNetAddr *addr, unsigned char *buffer, uint16_t buf_len, unsigned char more) {
int rv;
- rv = sock_send(sock, msg, msg_len, addr, buffer);
- if (rv) return rv;
+ buffer -= EOS_SOCK_SIZE_UDP_HDR;
+ sock_sendto(sock, addr, buffer);
- return eos_net_send(EOS_NET_MTYPE_SOCK, buffer, msg_len + EOS_SOCK_SIZE_UDP_HDR);
+ rv = eos_net_send(EOS_NET_MTYPE_SOCK, buffer, buf_len + EOS_SOCK_SIZE_UDP_HDR, more);
+ return rv;
}
-int eos_sock_sendto_async(unsigned char sock, unsigned char *msg, size_t msg_len, EOSNetAddr *addr, unsigned char *buffer, unsigned char more) {
+int eos_sock_sendto_sync(unsigned char sock, EOSNetAddr *addr, unsigned char *buffer, uint16_t buf_len) {
int rv;
- rv = sock_send(sock, msg, msg_len, addr, buffer);
- if (rv) return rv;
+ buffer -= EOS_SOCK_SIZE_UDP_HDR;
+ sock_sendto(sock, addr, buffer);
- return eos_net_send_async(EOS_NET_MTYPE_SOCK, buffer, msg_len + EOS_SOCK_SIZE_UDP_HDR, more);
+ rv = eos_net_send_sync(EOS_NET_MTYPE_SOCK, buffer, buf_len + EOS_SOCK_SIZE_UDP_HDR);
+ return rv;
}
-int eos_sock_recvfrom(unsigned char *buffer, uint16_t len, unsigned char *msg, size_t msg_size, EOSNetAddr *addr) {
- if (len < EOS_SOCK_SIZE_UDP_HDR) return EOS_ERR_SIZE;
+int eos_sock_recvfrom(unsigned char *buffer, uint16_t buf_len, EOSNetAddr *addr, unsigned char *pkt, size_t pkt_size) {
+ if (buf_len < EOS_SOCK_SIZE_UDP_HDR) return EOS_ERR_SIZE;
+ if (buffer[0] == EOS_SOCK_MTYPE_CLOSE) return EOS_SOCK_ERR_CLOSED;
if (buffer[0] != EOS_SOCK_MTYPE_PKT) return EOS_ERR_NET;
buffer += 2;
- memcpy(addr->host, buffer, sizeof(addr->host));
+ if (addr) {
+ memcpy(addr->host, buffer, sizeof(addr->host));
+ }
buffer += sizeof(addr->host);
- addr->port = (uint16_t)buffer[0] << 8;
- addr->port |= (uint16_t)buffer[1];
+ if (addr) {
+ addr->port = (uint16_t)buffer[0] << 8;
+ addr->port |= (uint16_t)buffer[1];
+ }
buffer += sizeof(addr->port);
- if (msg) {
- if (msg_size < len - EOS_SOCK_SIZE_UDP_HDR) return EOS_ERR_SIZE;
- memcpy(msg, buffer, len - EOS_SOCK_SIZE_UDP_HDR);
+ if (pkt) {
+ if (pkt_size < buf_len - EOS_SOCK_SIZE_UDP_HDR) return EOS_ERR_SIZE;
+ memcpy(pkt, buffer, buf_len - EOS_SOCK_SIZE_UDP_HDR);
}
return EOS_OK;
diff --git a/fw/fe310/eos/net/sock.h b/fw/fe310/eos/net/sock.h
index e2f8637..8dbb111 100644
--- a/fw/fe310/eos/net/sock.h
+++ b/fw/fe310/eos/net/sock.h
@@ -1,4 +1,5 @@
#include <stdint.h>
+
#include "../event.h"
#define EOS_SOCK_MTYPE_PKT 0
@@ -11,6 +12,8 @@
#define EOS_IPv4_ADDR_SIZE 4
+#define EOS_SOCK_ERR_CLOSED -1021
+
typedef struct EOSNetAddr {
unsigned char host[EOS_IPv4_ADDR_SIZE];
uint16_t port;
@@ -23,6 +26,10 @@ eos_evt_handler_t eos_sock_get_handler(unsigned char sock);
int eos_sock_open_udp(eos_evt_handler_t handler, unsigned char *buffer);
void eos_sock_close(unsigned char sock, unsigned char *buffer);
-int eos_sock_sendto(unsigned char sock, unsigned char *msg, size_t msg_len, EOSNetAddr *addr, unsigned char *buffer);
-int eos_sock_sendto_async(unsigned char sock, unsigned char *msg, size_t msg_len, EOSNetAddr *addr, unsigned char *buffer, unsigned char more);
-int eos_sock_recvfrom(unsigned char *buffer, uint16_t len, unsigned char *msg, size_t msg_size, EOSNetAddr *addr);
+int eos_sock_pkt_alloc(unsigned char **buffer, unsigned char *pkt, size_t pkt_len);
+unsigned char *eos_sock_buf2pkt(unsigned char *buf, uint16_t buf_len);
+unsigned char *eos_sock_pkt2buf(unsigned char *pkt);
+
+int eos_sock_sendto(unsigned char sock, EOSNetAddr *addr, unsigned char *buffer, uint16_t buf_len, unsigned char more);
+int eos_sock_sendto_sync(unsigned char sock, EOSNetAddr *addr, unsigned char *buffer, uint16_t buf_len);
+int eos_sock_recvfrom(unsigned char *buffer, uint16_t buf_len, EOSNetAddr *addr, unsigned char *pkt, size_t pkt_size);
diff --git a/fw/fe310/eos/net/wifi.c b/fw/fe310/eos/net/wifi.c
index ebbb9ca..1391121 100644
--- a/fw/fe310/eos/net/wifi.c
+++ b/fw/fe310/eos/net/wifi.c
@@ -10,19 +10,19 @@
static eos_evt_handler_t evt_handler[EOS_WIFI_MAX_MTYPE];
-static void wifi_handle_msg(unsigned char type, unsigned char *buffer, uint16_t len) {
+static void wifi_handle_msg(unsigned char type, unsigned char *buffer, uint16_t buf_len) {
unsigned char mtype;
- if ((buffer == NULL) || (len < 1)) {
- eos_net_bad_handler(type, buffer, len);
+ if ((buffer == NULL) || (buf_len < 1)) {
+ eos_net_bad_handler(type, buffer, buf_len);
return;
}
mtype = buffer[0];
if ((mtype < EOS_WIFI_MAX_MTYPE) && evt_handler[mtype]) {
- evt_handler[mtype](mtype, buffer, len);
+ evt_handler[mtype](mtype, buffer, buf_len);
} else {
- eos_net_bad_handler(type, buffer, len);
+ eos_net_bad_handler(type, buffer, buf_len);
}
}
@@ -44,28 +44,28 @@ eos_evt_handler_t eos_wifi_get_handler(unsigned char mtype) {
return NULL;
}
-int eos_wifi_status_parse(unsigned char *buffer, uint16_t len, uint8_t *status, uint8_t ip_addr[], char *ssid, uint16_t ssid_size) {
- if (len < 2) return EOS_ERR_SIZE;
+int eos_wifi_status_parse(unsigned char *buffer, uint16_t buf_len, uint8_t *status, uint8_t ip_addr[], char *ssid, uint16_t ssid_size) {
+ if (buf_len < 2) return EOS_ERR_SIZE;
if (buffer[0] != EOS_WIFI_MTYPE_STATUS) return EOS_ERR_NET;
buffer++;
- len--;
+ buf_len--;
*status = buffer[0];
buffer++;
- len--;
+ buf_len--;
switch (*status) {
case EOS_WIFI_STATUS_GOT_IP:
- if (len < sizeof(uint32_t)) return EOS_ERR_SIZE;
+ if (buf_len < sizeof(uint32_t)) return EOS_ERR_SIZE;
if (ip_addr) memcpy(ip_addr, buffer, sizeof(uint32_t));
buffer += sizeof(uint32_t);
- len -= sizeof(uint32_t);
+ buf_len -= sizeof(uint32_t);
case EOS_WIFI_STATUS_CONNECTED:
if (ssid) {
- if ((len == 0) || (len > EOS_WIFI_SIZE_SSID) || (len > ssid_size - 1)) return EOS_ERR_SIZE;
- memcpy(ssid, buffer, len);
- ssid[len] = '\0';
+ if ((buf_len == 0) || (buf_len > EOS_WIFI_SIZE_SSID) || (buf_len > ssid_size - 1)) return EOS_ERR_SIZE;
+ memcpy(ssid, buffer, buf_len);
+ ssid[buf_len] = '\0';
}
break;
}
@@ -74,7 +74,7 @@ int eos_wifi_status_parse(unsigned char *buffer, uint16_t len, uint8_t *status,
int eos_wifi_status(uint8_t *status, uint8_t ip_addr[], char *ssid, uint16_t ssid_size, unsigned char *buffer) {
unsigned char type;
- uint16_t len;
+ uint16_t buf_len;
int do_release;
int rv;
@@ -85,17 +85,17 @@ int eos_wifi_status(uint8_t *status, uint8_t ip_addr[], char *ssid, uint16_t ssi
}
type = EOS_NET_MTYPE_WIFI;
- len = 1;
+ buf_len = 1;
buffer[0] = EOS_WIFI_MTYPE_STATUS;
- rv = eos_net_xchg(&type, buffer, &len);
+ rv = eos_net_xchg(&type, buffer, &buf_len);
if (rv) goto wifi_status_fin;
if (type != EOS_NET_MTYPE_WIFI) {
rv = EOS_ERR_NET;
goto wifi_status_fin;
}
- rv = eos_wifi_status_parse(buffer, len, status, ip_addr, ssid, ssid_size);
+ rv = eos_wifi_status_parse(buffer, buf_len, status, ip_addr, ssid, ssid_size);
wifi_status_fin:
if (do_release) eos_net_free(buffer, 1);
diff --git a/fw/fe310/eos/net/wifi.h b/fw/fe310/eos/net/wifi.h
index 93d2fc4..800723e 100644
--- a/fw/fe310/eos/net/wifi.h
+++ b/fw/fe310/eos/net/wifi.h
@@ -1,4 +1,5 @@
#include <stdint.h>
+
#include "../event.h"
#define EOS_WIFI_MTYPE_STATUS 0
@@ -24,10 +25,10 @@ void eos_wifi_init(void);
void eos_wifi_set_handler(unsigned char mtype, eos_evt_handler_t handler);
eos_evt_handler_t eos_wifi_get_handler(unsigned char mtype);
-int eos_wifi_status_parse(unsigned char *buffer, uint16_t len, uint8_t *status, uint8_t ip_addr[], char *ssid, uint16_t ssid_size);
+int eos_wifi_status_parse(unsigned char *buffer, uint16_t buf_len, uint8_t *status, uint8_t ip_addr[], char *ssid, uint16_t ssid_size);
int eos_wifi_status(uint8_t *status, uint8_t ip_addr[], char *ssid, uint16_t ssid_size, unsigned char *buffer);
int eos_wifi_start(unsigned char *buffer, int sync);
int eos_wifi_stop(unsigned char *buffer, int sync);
int eos_wifi_scan(unsigned char *buffer, int sync);
int eos_wifi_connect(char *ssid, char *pwd, unsigned char *buffer, int sync);
-int eos_wifi_disconnect(unsigned char *buffer, int sync); \ No newline at end of file
+int eos_wifi_disconnect(unsigned char *buffer, int sync);
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);
diff --git a/fw/fe310/eos/unicode.c b/fw/fe310/eos/unicode.c
index af41d24..ce02ddb 100644
--- a/fw/fe310/eos/unicode.c
+++ b/fw/fe310/eos/unicode.c
@@ -107,6 +107,7 @@ int utf8_verify(utf8_t *str, size_t str_size, size_t *str_len) {
size_t len = 0;
int ch_l, rv;
+ ch_l = 0;
while (len < str_size) {
if (str_size - len < 4) {
rv = utf8_len_str(str + len);
diff --git a/hw/library/usb.dcm b/hw/library/haptic.dcm
index 5f3ed79..5f3ed79 100644
--- a/hw/library/usb.dcm
+++ b/hw/library/haptic.dcm
diff --git a/hw/library/haptic.lib b/hw/library/haptic.lib
new file mode 100644
index 0000000..2e59a48
--- /dev/null
+++ b/hw/library/haptic.lib
@@ -0,0 +1,26 @@
+EESchema-LIBRARY Version 2.4
+#encoding utf-8
+#
+# DRV2605LDGS
+#
+DEF DRV2605LDGS U 0 40 Y Y 1 F N
+F0 "U" 0 300 60 H V C CNN
+F1 "DRV2605LDGS" 0 -400 60 H V C CNN
+F2 "" 0 0 60 H I C CNN
+F3 "" 0 0 60 H I C CNN
+DRAW
+S -350 250 350 -350 0 1 0 N
+X REG 1 550 -200 200 L 50 50 1 1 O
+X VDD 10 550 200 200 L 50 50 1 1 W
+X SCL 2 -550 200 200 R 50 50 1 1 I
+X SDA 3 -550 100 200 R 50 50 1 1 B
+X IN/TRIG 4 -550 0 200 R 50 50 1 1 I
+X EN 5 -550 -100 200 R 50 50 1 1 I
+X VDD/NC 6 550 100 200 L 50 50 1 1 W
+X OUT+ 7 550 0 200 L 50 50 1 1 O
+X GND 8 550 -300 200 L 50 50 1 1 W
+X OUT- 9 550 -100 200 L 50 50 1 1 O
+ENDDRAW
+ENDDEF
+#
+#End Library
diff --git a/hw/library/usb.lib b/hw/library/usb.lib
deleted file mode 100644
index 2fc61d0..0000000
--- a/hw/library/usb.lib
+++ /dev/null
@@ -1,44 +0,0 @@
-EESchema-LIBRARY Version 2.4
-#encoding utf-8
-#
-# USB3_B_Micro
-#
-DEF USB3_B_Micro J 0 40 Y Y 1 F N
-F0 "J" -350 700 60 H V C CNN
-F1 "USB3_B_Micro" 100 700 60 H V C CNN
-F2 "" 0 100 60 H I C CNN
-F3 "" 0 100 60 H I C CNN
-DRAW
-C -100 145 25 1 1 10 F
-C 0 -130 50 1 1 0 F
-S -400 650 400 -600 1 1 10 f
-S -110 -600 -90 -560 1 1 0 N
-S -10 -600 10 -560 1 1 0 N
-S 75 170 125 220 1 1 10 F
-S 400 -490 360 -510 1 1 0 N
-S 400 -390 360 -410 1 1 0 N
-S 400 -190 360 -210 1 1 0 N
-S 400 -90 360 -110 1 1 0 N
-S 400 110 360 90 1 1 0 N
-S 400 210 360 190 1 1 0 N
-S 400 310 360 290 1 1 0 N
-S 400 510 360 490 1 1 0 N
-P 2 1 1 20 0 -130 0 270 N
-P 3 1 1 20 0 -30 -100 70 -100 120 N
-P 3 1 1 20 0 20 100 120 100 170 N
-P 4 1 1 10 -50 270 0 370 50 270 -50 270 F
-X VBUS 1 500 500 100 L 50 50 1 1 P
-X SSRX+ 10 500 -500 100 L 50 50 1 1 I
-X SHIELD 11 -200 -700 100 U 50 50 1 1 P
-X D- 2 500 300 100 L 50 50 1 1 B
-X D+ 3 500 200 100 L 50 50 1 1 B
-X ID 4 500 100 100 L 50 50 1 1 O
-X GND 5 0 -700 100 U 50 50 1 1 P
-X SSTX- 6 500 -100 100 L 50 50 1 1 O
-X SSTX+ 7 500 -200 100 L 50 50 1 1 O
-X DRAIN 8 -100 -700 100 U 50 50 1 1 P
-X SSRX- 9 500 -400 100 L 50 50 1 1 I
-ENDDRAW
-ENDDEF
-#
-#End Library
diff --git a/util/prog.c b/util/prog.c
index 0227682..e4360e0 100644
--- a/util/prog.c
+++ b/util/prog.c
@@ -48,11 +48,8 @@ int main(int argc, char *argv[]) {
ftdi_set_eeprom_value(ftdi, SELF_POWERED, 1);
ftdi_set_eeprom_value(ftdi, CBUS_FUNCTION_0, CBUSX_PWREN);
ftdi_set_eeprom_value(ftdi, CBUS_FUNCTION_1, CBUSX_IOMODE);
- /* next rev hw
- ftdi_set_eeprom_value(ftdi, CBUS_FUNCTION_3, CBUSX_VBUS_SENSE);
- */
ftdi_set_eeprom_value(ftdi, CBUS_FUNCTION_2, CBUSX_TRISTATE);
- ftdi_set_eeprom_value(ftdi, CBUS_FUNCTION_3, CBUSX_TRISTATE);
+ ftdi_set_eeprom_value(ftdi, CBUS_FUNCTION_3, CBUSX_VBUS_SENSE);
ret = ftdi_eeprom_build(ftdi);
if (ret < 0) goto ftdi_fin;
diff --git a/util/switch.c b/util/switch.c
index 2fc0eb6..9f60fd3 100644
--- a/util/switch.c
+++ b/util/switch.c
@@ -47,7 +47,7 @@ int main(int argc, char *argv[]) {
case DEV_ESP32: {
printf("Switch to esp32\n");
- ret = ftdi_set_bitmode(ftdi, 0x00, BITMODE_CBUS);
+ ret = ftdi_set_bitmode(ftdi, 0x22, BITMODE_CBUS);
break;
}
}
diff --git a/yocto/README b/yocto/README
index ef99121..6c92a6e 100644
--- a/yocto/README
+++ b/yocto/README
@@ -7,6 +7,8 @@ https://developer.toradex.com/linux-bsp/os-development/build-yocto/build-a-refer
https://developer.toradex.com/linux-bsp/os-development/build-u-boot-and-linux-kernel-from-source-code/build-u-boot/
https://developer.toradex.com/linux-bsp/os-development/build-u-boot-and-linux-kernel-from-source-code/build-linux-kernel-from-source-code/
https://developer.toradex.com/linux-bsp/os-development/build-u-boot-and-linux-kernel-from-source-code/build-device-tree-overlays-from-source-code/
+https://developer.toradex.com/linux-bsp/os-development/build-yocto/custom-meta-layers-recipes-and-images-in-yocto-project-hello-world-examples/
+https://developer.toradex.com/linux-bsp/os-development/build-yocto/device-tree-overlays-linux
- install dependencies:
# dependencies for yocto:
@@ -18,7 +20,7 @@ apt-get install bc build-essential git libncurses5-dev lzop perl libssl-dev biso
apt-get install u-boot-tools
# dependencies for kernel:
- apt-get install bc build-essential git libncurses5-dev lzop perl libssl-dev bison flex
+apt-get install bc build-essential git libncurses5-dev lzop perl libssl-dev bison flex
apt-get install u-boot-tools
locale-gen en_US.UTF-8
@@ -43,12 +45,9 @@ curl https://commondatastorage.googleapis.com/git-repo-downloads/repo > bin/repo
chmod 755 bin/repo
- install the ARM GCC toolchain:
-mkdir arm
-cd arm
wget https://developer.arm.com/-/media/Files/downloads/gnu/14.2.rel1/binrel/arm-gnu-toolchain-14.2.rel1-x86_64-aarch64-none-linux-gnu.tar.xz
tar xvf arm-gnu-toolchain-14.2.rel1-x86_64-aarch64-none-linux-gnu.tar.xz
ln -s arm-gnu-toolchain-14.2.rel1-x86_64-aarch64-none-linux-gnu gcc-linaro-aarch64
-cd ..
- install device tree compiler tool:
git clone https://git.kernel.org/pub/scm/utils/dtc/dtc.git -b v1.7.2
@@ -76,11 +75,12 @@ yocto image
- clone meta-information
mkdir oe-core
cd oe-core
-# branch: repo init -u git://git.toradex.com/toradex-manifest.git -b scarthgap-7.x.y -m tdxref/default.xml
+# branch:
+repo init -u git://git.toradex.com/toradex-manifest.git -b scarthgap-7.x.y -m tdxref/default.xml
# specific tag:
-repo init -u git://git.toradex.com/toradex-manifest.git -b refs/tags/7.1.0 -m tdxref/default.xml
+# repo init -u git://git.toradex.com/toradex-manifest.git -b refs/tags/7.1.0 -m tdxref/default.xml
repo sync
-# repeat sync until successful
+# repeat repo sync until successful
- setup environment:
. export
@@ -90,17 +90,59 @@ vi conf/local.conf
...
# set MACHINE:
MACHINE ?= "verdin-imx8mp"
-# append:
+...
+# set debian packages
+PACKAGE_CLASSES ?= "package_deb"
+...
+# append
ACCEPT_FSL_EULA = "1"
-TOOLCHAIN_TARGET_TASK:append = " kernel-devsrc"
+
+- append mikrophone layer:
+vi conf/bblayers.conf
+# append to BBLAYERS variable:
...
+ ${TOPDIR}/../layers/meta-mikrophone \
+"
-- build:
-bitbake -k tdx-reference-minimal-image -c populate_sdk
+# copy yocto/meta-mikrophone to ../layers/ dir from mikroPhone repo
+
+- build image:
+bitbake -k mikrophone-image
+bitbake -k mikrophone-image -c populate_sdk
+
+- install sdk:
+deploy/sdk/tdx-xwayland-glibc-x86_64-mikroPhone-Image-armv8a-verdin-imx8mp-toolchain-7.x.y.sh
+# install into: /build/tdx-xwayland/7.x.y
- machine.conf in: layers/meta-toradex-nxp/conf/machine/verdin-imx8mp.conf
-- distro.conf in: layers/meta-toradex-distro/conf/distro/*.conf
-- demo images in: layers/meta-toradex-demos/recipes-images/images/*.bb
+ layers/meta-mikrophone/conf/machine/include/verdin-imx8mp.inc
+- mikrophone distro.conf in: layers/meta-mikrophone/conf/distro/mikrophone.conf
+- mikrophone images in: layers/meta-mikrophone/recipes-images/images/mikrophone-image.bb
+
+- deployable tarballs in: build/deploy/images/verdin-imx8mp/
+- deployable sdk in: build/deploy/sdk/
+
+- toradex distro.conf in: layers/meta-toradex-distro/conf/distro/*.conf
+- toradex demo images in: layers/meta-toradex-demos/recipes-images/images/*.bb
+
+
+upgrade yocto image
+-------------------
+
+- upgrade yocto:
+. /build/tools/start.sh
+cd /build/oe-core
+repo sync
+
+- build image:
+. export
+bitbake -k mikrophone-image
+bitbake -k mikrophone-image -c populate_sdk
+
+- to launch TEZI installer: insert sdcard, reboot linux then stop u-boot auto boot and type:
+setenv fdtfile imx8mp-verdin-wifi-dev.dtb
+boot
+
u-boot
------
@@ -177,3 +219,46 @@ overlay
cd overlays
STAGING_KERNEL_DIR=../linux-toradex make mikroPhone-panel_overlay.dtbo
cd ..
+
+
+esp32d
+------
+
+- setup environment:
+. /build/tdx-xwayland/7.x.y/environment-setup-armv8a-tdx-linux
+
+- build:
+# copy yocto/esp32d from mikroPhone repo
+cd esp32d
+make
+cd ..
+
+
+debian repository
+-----------------
+
+- install aptly and configure aptly:
+apt-get install aptly gnupg1 gpgv1
+aptly # creates config file
+vi ~/.aptly.conf
+...
+ "gpgProvider": "internal",
+...
+ "FileSystemPublishEndpoints": {
+ "mikrophone": {
+ "rootDir": "/build/repo",
+ "linkMethod": "copy",
+ "verifyMethod": "md5"
+ }
+ },
+...
+
+- generate gpg signing key:
+gpg1 --gen-key
+gpg1 --export --armor # signing key for apt-key add
+
+- create and publish repository:
+aptly repo create -distribution=koshuta -component=main mikrophone
+aptly repo add mikrophone /build/oe-core/build/deploy/deb
+aptly publish repo mikrophone filesystem:mikrophone:
+aptly publish update koshuta filesystem:mikrophone:
diff --git a/yocto/esp32d/Makefile b/yocto/esp32d/Makefile
new file mode 100644
index 0000000..677d09d
--- /dev/null
+++ b/yocto/esp32d/Makefile
@@ -0,0 +1,15 @@
+#CFLAGS =
+LDFLAGS = -pthread -lgpiod
+TARGET = esp32d
+obj = msgq.o spi.o tun.o
+
+all: $(TARGET)
+
+%.o: %.c %.h
+ $(CC) $(CFLAGS) -c $<
+
+$(TARGET): $(obj)
+ $(CC) $(obj) $(LDFLAGS) -o $@
+
+clean:
+ rm -f $(TARGET) *.o
diff --git a/yocto/esp32d/msgq.c b/yocto/esp32d/msgq.c
new file mode 100644
index 0000000..3039f13
--- /dev/null
+++ b/yocto/esp32d/msgq.c
@@ -0,0 +1,43 @@
+#include <stdlib.h>
+#include <pthread.h>
+
+#include "msgq.h"
+
+#define IDX_MASK(IDX, SIZE) ((IDX) & ((SIZE) - 1))
+
+int msgq_init(MSGQueue *msgq, unsigned char **array, uint16_t size) {
+ int rv;
+
+ msgq->idx_r = 0;
+ msgq->idx_w = 0;
+ msgq->size = size;
+ msgq->array = array;
+ rv = pthread_mutex_init(&msgq->mutex, NULL);
+ if (rv) {
+ return MSGQ_ERR;
+ }
+
+ rv = pthread_cond_init(&msgq->cond, NULL);
+ if (rv) {
+ pthread_mutex_destroy(&msgq->mutex);
+ return MSGQ_ERR;
+ }
+ return MSGQ_OK;
+}
+
+int msgq_push(MSGQueue *msgq, unsigned char *buffer) {
+ if ((uint16_t)(msgq->idx_w - msgq->idx_r) == msgq->size) return MSGQ_ERR_FULL;
+
+ msgq->array[IDX_MASK(msgq->idx_w++, msgq->size)] = buffer;
+ return MSGQ_OK;
+}
+
+unsigned char *msgq_pop(MSGQueue *msgq) {
+ if (msgq->idx_r == msgq->idx_w) return NULL;
+
+ return msgq->array[IDX_MASK(msgq->idx_r++, msgq->size)];
+}
+
+uint16_t msgq_len(MSGQueue *msgq) {
+ return (uint16_t)(msgq->idx_w - msgq->idx_r);
+}
diff --git a/yocto/esp32d/msgq.h b/yocto/esp32d/msgq.h
new file mode 100644
index 0000000..32b20d0
--- /dev/null
+++ b/yocto/esp32d/msgq.h
@@ -0,0 +1,22 @@
+#include <stdint.h>
+
+#define MSGQ_OK 0
+#define MSGQ_ERR -1
+
+#define MSGQ_ERR_SIZE -10
+#define MSGQ_ERR_FULL -11
+#define MSGQ_ERR_EMPTY -12
+
+typedef struct MSGQueue {
+ uint16_t idx_r;
+ uint16_t idx_w;
+ uint16_t size;
+ unsigned char **array;
+ pthread_mutex_t mutex;
+ pthread_cond_t cond;
+} MSGQueue;
+
+int msgq_init(MSGQueue *msgq, unsigned char **array, uint16_t size);
+int msgq_push(MSGQueue *msgq, unsigned char *buffer);
+unsigned char *msgq_pop(MSGQueue *msgq);
+uint16_t msgq_len(MSGQueue *msgq);
diff --git a/yocto/esp32d/spi.c b/yocto/esp32d/spi.c
new file mode 100644
index 0000000..db46a63
--- /dev/null
+++ b/yocto/esp32d/spi.c
@@ -0,0 +1,411 @@
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <assert.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+
+#include <linux/spi/spidev.h>
+
+#include <gpiod.h>
+#include <pthread.h>
+
+#include "msgq.h"
+#include "tun.h"
+#include "spi.h"
+
+static pthread_t worker_thd;
+static pthread_t rtscts_thd;
+static pthread_t msg_handler_thd;
+static pthread_t tun_handler_thd;
+static pthread_mutex_t mutex;
+static pthread_cond_t cond;
+
+static MSGQueue spi_bufq;
+static unsigned char *spi_bufq_array[SPI_SIZE_BUFQ];
+
+static MSGQueue spi_msgq_in;
+static unsigned char *spi_msgq_in_array[SPI_SIZE_MSGQ_IN];
+
+static MSGQueue spi_msgq_out;
+static unsigned char *spi_msgq_out_array[SPI_SIZE_MSGQ_OUT];
+
+static uint32_t spi_speed = SPI_SPEED;
+static int spi_fd;
+static volatile int spi_cts;
+
+struct gpiod_line_request *request = NULL;
+
+static void _spi_wait4cts(void) {
+ pthread_mutex_lock(&mutex);
+ while (!spi_cts) {
+ pthread_cond_wait(&cond, &mutex);
+ }
+ spi_cts = 0;
+ pthread_mutex_unlock(&mutex);
+}
+
+static int _spi_xchg(unsigned char *buffer) {
+ int rv;
+ uint16_t len_tx;
+ uint16_t len_rx;
+ struct spi_ioc_transfer tr;
+
+ memset(&tr, 0, sizeof(tr));
+ tr.tx_buf = (unsigned long)buffer;
+ tr.rx_buf = (unsigned long)buffer;
+ tr.speed_hz = spi_speed;
+
+ len_tx = (uint16_t)buffer[1] << 8;
+ len_tx |= (uint16_t)buffer[2] & 0xFF;
+ if (len_tx > SPI_MTU) return SPI_ERR;
+
+ if (buffer[0]) {
+ len_tx += SPI_SIZE_HDR;
+ // esp32 dma workaraund
+ if (len_tx < 8) {
+ len_tx = 8;
+ } else if (len_tx % 4 != 0) {
+ len_tx = (len_tx / 4 + 1) * 4;
+ }
+
+ tr.len = len_tx;
+ } else {
+ /* nothing to send, reset esp32 spi transaction */
+ tr.len = 1;
+
+ _spi_wait4cts();
+ rv = ioctl(spi_fd, SPI_IOC_MESSAGE(1), &tr);
+ if (rv < 0) return SPI_ERR_MSG;
+
+ /* receive SPI_SIZE_RECEIVE bytes in first transaction (estimate) */
+ len_tx = SPI_SIZE_RECEIVE + SPI_SIZE_HDR;
+ tr.len = len_tx;
+ buffer[1] = 0;
+ buffer[2] = 0;
+ }
+
+ _spi_wait4cts();
+ rv = ioctl(spi_fd, SPI_IOC_MESSAGE(1), &tr);
+ if (rv < 0) return SPI_ERR_MSG;
+
+ len_rx = (uint16_t)buffer[1] << 8;
+ len_rx |= (uint16_t)buffer[2] & 0xFF;
+ if (len_rx > SPI_MTU) return SPI_ERR;
+
+ len_rx += SPI_SIZE_HDR;
+ if (len_rx > len_tx) {
+ tr.tx_buf = (unsigned long)NULL;
+ tr.rx_buf = (unsigned long)(buffer + len_tx);
+
+ len_tx = len_rx - len_tx;
+ // esp32 dma workaraund
+ if (len_tx < 8) {
+ len_tx = 8;
+ } else if (len_tx % 4 != 0) {
+ len_tx = (len_tx / 4 + 1) * 4;
+ }
+
+ tr.len = len_tx;
+
+ _spi_wait4cts();
+ rv = ioctl(spi_fd, SPI_IOC_MESSAGE(1), &tr);
+ if (rv < 0) return SPI_ERR_MSG;
+ }
+
+ return SPI_OK;
+}
+
+static void *worker(void *arg) {
+ MSGQueue *bufq = &spi_bufq;
+ MSGQueue *msgq_in = &spi_msgq_in;
+ MSGQueue *msgq_out = &spi_msgq_out;
+ int rv;
+ unsigned char *buffer;
+
+ while (1) {
+ pthread_mutex_lock(&msgq_out->mutex);
+ buffer = msgq_pop(msgq_out);
+ if ((buffer == NULL) && (gpiod_line_request_get_value(request, SPI_GPIO_RTS) == GPIOD_LINE_VALUE_INACTIVE)) {
+ pthread_mutex_lock(&bufq->mutex);
+ buffer = msgq_pop(bufq);
+ pthread_mutex_unlock(&bufq->mutex);
+ }
+ if (buffer == NULL) {
+ pthread_cond_wait(&msgq_out->cond, &msgq_out->mutex);
+ buffer = msgq_pop(msgq_out);
+ }
+ pthread_mutex_unlock(&msgq_out->mutex);
+ if (buffer) {
+ rv = _spi_xchg(buffer);
+ if (rv || (buffer[0] == 0)) {
+ buffer[0] = 0;
+ buffer[1] = 0;
+ buffer[2] = 0;
+ pthread_mutex_lock(&bufq->mutex);
+ msgq_push(bufq, buffer);
+ pthread_mutex_unlock(&bufq->mutex);
+ } else {
+ pthread_mutex_lock(&msgq_in->mutex);
+ rv = msgq_push(msgq_in, buffer);
+ if (rv == MSGQ_OK) pthread_cond_signal(&msgq_in->cond);
+ pthread_mutex_unlock(&msgq_in->mutex);
+
+ if (rv) {
+ pthread_mutex_lock(&bufq->mutex);
+ msgq_push(bufq, buffer);
+ pthread_mutex_unlock(&bufq->mutex);
+ }
+ }
+ }
+ }
+
+ return NULL;
+}
+
+static void *rtscts_handler(void *arg) {
+ MSGQueue *msgq_out = &spi_msgq_out;
+ struct gpiod_edge_event_buffer *event_buffer;
+ struct gpiod_edge_event *event;
+ int rv;
+
+ event_buffer = gpiod_edge_event_buffer_new(1);
+
+ while (1) {
+ rv = gpiod_line_request_read_edge_events(request, event_buffer, 1);
+ if (rv != 1) continue;
+
+ event = gpiod_edge_event_buffer_get_event(event_buffer, 0);
+ switch (gpiod_edge_event_get_line_offset(event)) {
+ case SPI_GPIO_RTS: {
+ pthread_mutex_lock(&msgq_out->mutex);
+ pthread_cond_signal(&msgq_out->cond);
+ pthread_mutex_unlock(&msgq_out->mutex);
+ break;
+ }
+
+ case SPI_GPIO_CTS: {
+ pthread_mutex_lock(&mutex);
+ spi_cts = 1;
+ pthread_cond_signal(&cond);
+ pthread_mutex_unlock(&mutex);
+ break;
+ }
+ }
+ }
+
+ gpiod_edge_event_buffer_free(event_buffer);
+ return NULL;
+}
+
+static void *msg_handler(void *arg) {
+ MSGQueue *bufq = &spi_bufq;
+ MSGQueue *msgq_in = &spi_msgq_in;
+ unsigned char *buffer;
+ unsigned char mtype;
+ uint16_t len;
+ int rv;
+
+ while (1) {
+ pthread_mutex_lock(&msgq_in->mutex);
+ buffer = msgq_pop(msgq_in);
+ if (buffer == NULL) {
+ pthread_cond_wait(&msgq_in->cond, &msgq_in->mutex);
+ buffer = msgq_pop(msgq_in);
+ }
+ pthread_mutex_unlock(&msgq_in->mutex);
+ if (buffer) {
+ mtype = buffer[0];
+ len = (uint16_t)buffer[1] << 8;
+ len |= (uint16_t)buffer[2] & 0xFF;
+
+ switch (mtype) {
+ case SPI_MTYPE_TUN:
+ tun_write(buffer + SPI_SIZE_HDR, len);
+ break;
+ }
+ buffer[0] = 0;
+ buffer[1] = 0;
+ buffer[2] = 0;
+ pthread_mutex_lock(&bufq->mutex);
+ msgq_push(bufq, buffer);
+ pthread_mutex_unlock(&bufq->mutex);
+ }
+ }
+
+ return NULL;
+}
+
+static void *tun_handler(void *arg) {
+ unsigned char *buffer;
+ ssize_t len;
+
+ while (1) {
+ buffer = spi_alloc();
+ if (buffer == NULL) continue;
+
+ len = tun_read(buffer + SPI_SIZE_HDR, SPI_SIZE_BUF - SPI_SIZE_HDR);
+ if (len < 0) {
+ perror("tun read");
+ continue;
+ }
+ spi_xchg(SPI_MTYPE_TUN, buffer, len);
+ }
+
+ return NULL;
+}
+
+unsigned char *spi_alloc(void) {
+ MSGQueue *bufq = &spi_bufq;
+ unsigned char *buffer;
+
+ pthread_mutex_lock(&bufq->mutex);
+ buffer = msgq_pop(bufq);
+ pthread_mutex_unlock(&bufq->mutex);
+
+ return buffer;
+}
+
+void spi_free(unsigned char *buffer) {
+ MSGQueue *bufq = &spi_bufq;
+
+ buffer[0] = 0;
+ buffer[1] = 0;
+ buffer[2] = 0;
+ pthread_mutex_lock(&bufq->mutex);
+ msgq_push(bufq, buffer);
+ pthread_mutex_unlock(&bufq->mutex);
+}
+
+int spi_xchg(unsigned char mtype, unsigned char *buffer, uint16_t len) {
+ MSGQueue *bufq = &spi_bufq;
+ MSGQueue *msgq_out = &spi_msgq_out;
+ int rv;
+
+ buffer[0] = mtype;
+ buffer[1] = len >> 8;
+ buffer[2] = len & 0xFF;
+
+ pthread_mutex_lock(&msgq_out->mutex);
+ rv = msgq_push(msgq_out, buffer);
+ if (rv == MSGQ_OK) pthread_cond_signal(&msgq_out->cond);
+ pthread_mutex_unlock(&msgq_out->mutex);
+
+ if (rv) {
+ pthread_mutex_lock(&bufq->mutex);
+ msgq_push(bufq, buffer);
+ pthread_mutex_unlock(&bufq->mutex);
+ }
+
+ return rv;
+}
+
+int gpio_init(void) {
+ struct gpiod_chip *chip = NULL;
+ struct gpiod_line_settings *line_settings = NULL;
+ struct gpiod_line_config *line_cfg = NULL;
+ struct gpiod_request_config *req_cfg = NULL;
+ int rv;
+
+ unsigned int line_offsets[2] = { SPI_GPIO_RTS, SPI_GPIO_CTS };
+
+ chip = gpiod_chip_open(SPI_GPIO_DEV);
+ if (chip == NULL) goto gpio_init_fin;
+
+ line_settings = gpiod_line_settings_new();
+ if (line_settings == NULL) goto gpio_init_fin;
+
+ gpiod_line_settings_set_direction(line_settings, GPIOD_LINE_DIRECTION_INPUT);
+ gpiod_line_settings_set_edge_detection(line_settings, GPIOD_LINE_EDGE_FALLING);
+ gpiod_line_settings_set_bias(line_settings, GPIOD_LINE_BIAS_PULL_UP);
+
+ line_cfg = gpiod_line_config_new();
+ if (line_cfg == NULL) goto gpio_init_fin;
+
+ rv = gpiod_line_config_add_line_settings(line_cfg, line_offsets, 2, line_settings);
+ if (rv) goto gpio_init_fin;
+
+ req_cfg = gpiod_request_config_new();
+ if (req_cfg == NULL) goto gpio_init_fin;
+
+ gpiod_request_config_set_consumer(req_cfg, "rts-cts");
+
+ request = gpiod_chip_request_lines(chip, req_cfg, line_cfg);
+
+gpio_init_fin:
+ rv = (request ? SPI_OK : (chip ? SPI_ERR : SPI_ERR_OPEN));
+
+ if (req_cfg) gpiod_request_config_free(req_cfg);
+ if (line_cfg) gpiod_line_config_free(line_cfg);
+ if (line_settings) gpiod_line_settings_free(line_settings);
+ if (chip) gpiod_chip_close(chip);
+
+ return rv;
+}
+
+int spi_init(void) {
+ unsigned char *buffer;
+ int rv, i;
+
+ spi_fd = open(SPI_DEV, O_RDWR);
+ if (spi_fd < 0) return SPI_ERR_OPEN;
+
+ rv = ioctl(spi_fd, SPI_IOC_WR_MAX_SPEED_HZ, &spi_speed);
+ if (rv == -1) return SPI_ERR;
+
+ rv = msgq_init(&spi_bufq, spi_bufq_array, SPI_SIZE_BUFQ);
+ assert(rv == MSGQ_OK);
+
+ rv = msgq_init(&spi_msgq_in, spi_msgq_in_array, SPI_SIZE_MSGQ_IN);
+ assert(rv == MSGQ_OK);
+
+ rv = msgq_init(&spi_msgq_out, spi_msgq_out_array, SPI_SIZE_MSGQ_OUT);
+ assert(rv == MSGQ_OK);
+
+ for (i=0; i<SPI_SIZE_BUFQ; i++) {
+ buffer = malloc(SPI_SIZE_BUF);
+ assert(buffer);
+ msgq_push(&spi_bufq, buffer);
+ }
+
+ rv = pthread_mutex_init(&mutex, NULL);
+ assert(rv == 0);
+
+ rv = pthread_cond_init(&cond, NULL);
+ assert(rv == 0);
+
+ /* assret initial contitions */
+ pthread_mutex_lock(&mutex);
+ spi_cts = (gpiod_line_request_get_value(request, SPI_GPIO_CTS) == GPIOD_LINE_VALUE_INACTIVE);
+ pthread_mutex_unlock(&mutex);
+
+ rv = pthread_create(&worker_thd, NULL, worker, NULL);
+ assert(rv == 0);
+
+ rv = pthread_create(&rtscts_thd, NULL, rtscts_handler, NULL);
+ assert(rv == 0);
+
+ rv = pthread_create(&msg_handler_thd, NULL, msg_handler, NULL);
+ assert(rv == 0);
+
+ rv = pthread_create(&tun_handler_thd, NULL, tun_handler, NULL);
+ assert(rv == 0);
+
+ return SPI_OK;
+}
+
+int main(int argc, char *argv[]) {
+ int rv;
+
+ rv = tun_init(SPI_TUN_NAME);
+ if (rv) printf("TUN INIT ERR\n");
+
+ rv = gpio_init();
+ if (rv) printf("GPIO INIT ERR\n");
+
+ rv = spi_init();
+ if (rv) printf("SPI INIT ERR\n");
+
+ while (1);
+}
diff --git a/yocto/esp32d/spi.h b/yocto/esp32d/spi.h
new file mode 100644
index 0000000..4d9ff86
--- /dev/null
+++ b/yocto/esp32d/spi.h
@@ -0,0 +1,31 @@
+#include <stdint.h>
+
+#define SPI_DEV "/dev/spidev0"
+#define SPI_SPEED 10000000
+
+#define SPI_TUN_NAME "tun0"
+
+#define SPI_GPIO_DEV "/dev/gpiochip3"
+#define SPI_GPIO_CTS 28
+#define SPI_GPIO_RTS 25
+
+#define SPI_MTU 1500
+#define SPI_SIZE_HDR 3
+#define SPI_SIZE_BUF (SPI_MTU + SPI_SIZE_HDR)
+#define SPI_SIZE_RECEIVE 16 /* guestimate on number of bytes for transaction initiated by falling RTS */
+
+#define SPI_SIZE_BUFQ 64
+#define SPI_SIZE_MSGQ_IN 32
+#define SPI_SIZE_MSGQ_OUT 32
+
+#define SPI_MTYPE_TUN 1
+
+#define SPI_OK 0
+#define SPI_ERR -1
+#define SPI_ERR_OPEN -10
+#define SPI_ERR_MSG -11
+
+unsigned char *spi_alloc(void);
+void spi_free(unsigned char *buffer);
+int spi_xchg(unsigned char mtype, unsigned char *buffer, uint16_t len);
+int spi_init(void); \ No newline at end of file
diff --git a/yocto/esp32d/tun.c b/yocto/esp32d/tun.c
new file mode 100644
index 0000000..75043a3
--- /dev/null
+++ b/yocto/esp32d/tun.c
@@ -0,0 +1,84 @@
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+
+#include <linux/if.h>
+#include <linux/if_tun.h>
+
+#include <pthread.h>
+
+#include "spi.h"
+#include "tun.h"
+
+static pthread_t read_thd;
+
+static int tun_fd;
+static char tun_name[IFNAMSIZ];
+
+static int tun_alloc(char *dev, int flags) {
+ struct ifreq ifr;
+ int fd, err;
+ char *clonedev = "/dev/net/tun";
+
+ /* Arguments taken by the function:
+ *
+ * char *dev: the name of an interface (or '\0'). MUST have enough
+ * space to hold the interface name if '\0' is passed
+ * int flags: interface flags (eg, IFF_TUN etc.)
+ */
+
+ fd = open(clonedev, O_RDWR);
+ if (fd < 0) {
+ return fd;
+ }
+
+ memset(&ifr, 0, sizeof(ifr));
+ ifr.ifr_flags = flags; /* IFF_TUN or IFF_TAP, plus maybe IFF_NO_PI */
+
+ if (*dev) {
+ /* if a device name was specified, put it in the structure; otherwise,
+ * the kernel will try to allocate the "next" device of the
+ * specified type */
+ strncpy(ifr.ifr_name, dev, IFNAMSIZ);
+ }
+
+ /* try to create the device */
+ err = ioctl(fd, TUNSETIFF, (void *) &ifr);
+ if (err < 0) {
+ close(fd);
+ return err;
+ }
+
+ /* if the operation was successful, write back the name of the
+ * interface to the variable "dev", so the caller can know
+ * it. Note that the caller MUST reserve space in *dev (see calling
+ * code below) */
+ strcpy(dev, ifr.ifr_name);
+
+ /* this is the special file descriptor that the caller will use to talk
+ * with the virtual interface */
+ return fd;
+}
+
+ssize_t tun_read(unsigned char *buffer, size_t buf_size) {
+ return read(tun_fd, buffer, buf_size);
+}
+
+ssize_t tun_write(unsigned char *buffer, size_t buf_len) {
+ return write(tun_fd, buffer, buf_len);
+}
+
+int tun_init(char *name) {
+ int rv;
+
+ if (strlen(name) >= sizeof(tun_name) - 1) return -1;
+ strcpy(tun_name, name);
+
+ tun_fd = tun_alloc(tun_name, IFF_TUN | IFF_NO_PI);
+ if (tun_fd < 0) return -1;
+
+ return 0;
+}
diff --git a/yocto/esp32d/tun.h b/yocto/esp32d/tun.h
new file mode 100644
index 0000000..793a4c9
--- /dev/null
+++ b/yocto/esp32d/tun.h
@@ -0,0 +1,5 @@
+#include <sys/types.h>
+
+ssize_t tun_read(unsigned char *buffer, size_t buf_size);
+ssize_t tun_write(unsigned char *buffer, size_t buf_len);
+int tun_init(char *name); \ No newline at end of file
diff --git a/yocto/meta-mikrophone/conf/distro/mikrophone.conf b/yocto/meta-mikrophone/conf/distro/mikrophone.conf
new file mode 100644
index 0000000..efeba6e
--- /dev/null
+++ b/yocto/meta-mikrophone/conf/distro/mikrophone.conf
@@ -0,0 +1,20 @@
+# Toradex Distro for Wayland with XWayland.
+# Using the downstream kernel flavour.
+
+require conf/distro/include/tdx-base.inc
+
+DISTRO = "mikrophone"
+DISTRO_NAME = "mikroPhone distribution"
+DISTRO_FLAVOUR = ""
+
+IMX_DEFAULT_BSP = "nxp"
+
+# we use graphics, so set opengl
+DISTRO_FEATURES:append = " opengl"
+
+DISTRO_FEATURES:append = " wayland x11"
+
+# lxqt requires this
+DISTRO_FEATURES:append = " polkit"
+TASK_BASIC_SSHDAEMON = "openssh-sshd openssh-sftp openssh-sftp-server"
+IMAGE_FEATURES:append = " ssh-server-openssh"
diff --git a/yocto/meta-mikrophone/conf/layer.conf b/yocto/meta-mikrophone/conf/layer.conf
new file mode 100644
index 0000000..8abd100
--- /dev/null
+++ b/yocto/meta-mikrophone/conf/layer.conf
@@ -0,0 +1,13 @@
+# We have a conf and classes directory, add to BBPATH
+BBPATH .= ":${LAYERDIR}"
+
+# We have recipes-* directories, add to BBFILES
+BBFILES += "${LAYERDIR}/recipes-*/*/*.bb \
+ ${LAYERDIR}/recipes-*/*/*.bbappend"
+
+BBFILE_COLLECTIONS += "meta-mikrophone"
+BBFILE_PATTERN_meta-mikrophone = "^${LAYERDIR}/"
+BBFILE_PRIORITY_meta-mikrophone = "6"
+
+LAYERDEPENDS_meta-mikrophone = "core"
+LAYERSERIES_COMPAT_meta-mikrophone = "scarthgap"
diff --git a/yocto/meta-mikrophone/conf/machine/._verdin-imx8mp-mikrophone.conf b/yocto/meta-mikrophone/conf/machine/._verdin-imx8mp-mikrophone.conf
new file mode 100644
index 0000000..fe7655c
--- /dev/null
+++ b/yocto/meta-mikrophone/conf/machine/._verdin-imx8mp-mikrophone.conf
Binary files differ
diff --git a/yocto/meta-mikrophone/conf/machine/include/verdin-imx8mp.inc b/yocto/meta-mikrophone/conf/machine/include/verdin-imx8mp.inc
new file mode 100644
index 0000000..b64f4f1
--- /dev/null
+++ b/yocto/meta-mikrophone/conf/machine/include/verdin-imx8mp.inc
@@ -0,0 +1,14 @@
+# needed in recent builds for wifi and bt
+MACHINE_FIRMWARE:append = " firmware-nxp-wifi-nxp8997-sdio"
+
+# our device tree
+KERNEL_DEVICETREE:append = " \
+ ${KERNEL_DTB_PREFIX}imx8mp-verdin-wifi-mikrophone.dtb \
+ ${KERNEL_DTB_PREFIX}imx8mp-verdin-nonwifi-mikrophone.dtb \
+"
+# DTB for u-boot only
+UBOOT_DTB_NAME = "imx8mp-verdin-wifi-mikrophone.dtb"
+
+# for SDK only
+TOOLCHAIN_TARGET_TASK:append = " kernel-devsrc"
+TOOLCHAIN_TARGET_TASK:remove = "target-sdk-provides-dummy"
diff --git a/yocto/meta-mikrophone/recipes-bsp/u-boot/u-boot-toradex/imx8mp-verdin-mikrophone.dtsi b/yocto/meta-mikrophone/recipes-bsp/u-boot/u-boot-toradex/imx8mp-verdin-mikrophone.dtsi
new file mode 100644
index 0000000..6ce6362
--- /dev/null
+++ b/yocto/meta-mikrophone/recipes-bsp/u-boot/u-boot-toradex/imx8mp-verdin-mikrophone.dtsi
@@ -0,0 +1,111 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/*
+ * Copyright 2025 Uros Majstorovic
+ */
+
+/* Verdin SPI_1 */
+&ecspi1 {
+ status = "okay";
+};
+
+&eqos {
+ status = "disable";
+};
+
+&fec {
+ status = "disable";
+};
+
+&flexcan1 {
+ status = "disable";
+};
+
+&flexcan2 {
+ status = "disable";
+};
+
+/* Verdin QSPI_1 */
+&flexspi {
+ status = "disable";
+};
+
+/* Verdin I2C_2_DSI */
+&i2c2 {
+ status = "disabled";
+};
+
+&i2c3 {
+ status = "disabled";
+};
+
+/* Verdin I2C_1 */
+&i2c4 {
+ status = "okay";
+};
+
+/* Verdin PCIE_1 */
+&pcie {
+ status = "okay";
+};
+
+&pcie_phy {
+ status = "okay";
+};
+
+/* Verdin PWM_1 */
+&pwm1 {
+ status = "okay";
+};
+
+/* Verdin PWM_2 */
+&pwm2 {
+ status = "disabled";
+};
+
+/* Verdin PWM_3_DSI */
+&pwm3 {
+ status = "disabled";
+};
+
+&reg_usdhc2_vmmc {
+ vin-supply = <&reg_3p3v>;
+};
+
+/* Verdin UART_1 */
+&uart1 {
+ status = "disabled";
+};
+
+/* Verdin UART_2 */
+&uart2 {
+ status = "disabled";
+};
+
+/* Verdin UART_3, used as the Linux Console */
+&uart3 {
+ status = "okay";
+};
+
+/* Verdin USB_1 */
+&usb3_0 {
+ status = "okay";
+};
+
+&usb3_phy0 {
+ status = "okay";
+};
+
+/* Verdin USB_2 */
+&usb3_1 {
+ fsl,permanently-attached;
+ status = "okay";
+};
+
+&usb3_phy1 {
+ status = "okay";
+};
+
+/* Verdin SDCard */
+&usdhc2 {
+ status = "okay";
+};
diff --git a/yocto/meta-mikrophone/recipes-bsp/u-boot/u-boot-toradex/imx8mp-verdin-nonwifi-mikrophone.dts b/yocto/meta-mikrophone/recipes-bsp/u-boot/u-boot-toradex/imx8mp-verdin-nonwifi-mikrophone.dts
new file mode 100644
index 0000000..e8ba274
--- /dev/null
+++ b/yocto/meta-mikrophone/recipes-bsp/u-boot/u-boot-toradex/imx8mp-verdin-nonwifi-mikrophone.dts
@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/*
+ * Copyright 2025 Uros Majstorovic
+ */
+
+/dts-v1/;
+
+#include "imx8mp-verdin.dtsi"
+#include "imx8mp-verdin-nonwifi.dtsi"
+#include "imx8mp-verdin-mikrophone.dtsi"
+
+/ {
+ model = "Toradex Verdin iMX8M Plus on mikroPhone";
+ compatible = "toradex,verdin-imx8mp-nonwifi-mikrophone",
+ "toradex,verdin-imx8mp-nonwifi",
+ "toradex,verdin-imx8mp",
+ "fsl,imx8mp";
+};
diff --git a/yocto/meta-mikrophone/recipes-bsp/u-boot/u-boot-toradex/imx8mp-verdin-wifi-mikrophone.dts b/yocto/meta-mikrophone/recipes-bsp/u-boot/u-boot-toradex/imx8mp-verdin-wifi-mikrophone.dts
new file mode 100644
index 0000000..3b04ab5
--- /dev/null
+++ b/yocto/meta-mikrophone/recipes-bsp/u-boot/u-boot-toradex/imx8mp-verdin-wifi-mikrophone.dts
@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/*
+ * Copyright 2025 Uros Majstorovic
+ */
+
+/dts-v1/;
+
+#include "imx8mp-verdin.dtsi"
+#include "imx8mp-verdin-wifi.dtsi"
+#include "imx8mp-verdin-mikrophone.dtsi"
+
+/ {
+ model = "Toradex Verdin iMX8M Plus WB on mikroPhone";
+ compatible = "toradex,verdin-imx8mp-wifi-mikrophone",
+ "toradex,verdin-imx8mp-wifi",
+ "toradex,verdin-imx8mp",
+ "fsl,imx8mp";
+};
diff --git a/yocto/meta-mikrophone/recipes-bsp/u-boot/u-boot-toradex_%.bbappend b/yocto/meta-mikrophone/recipes-bsp/u-boot/u-boot-toradex_%.bbappend
new file mode 100644
index 0000000..0a6f719
--- /dev/null
+++ b/yocto/meta-mikrophone/recipes-bsp/u-boot/u-boot-toradex_%.bbappend
@@ -0,0 +1,19 @@
+FILESEXTRAPATHS:prepend := "${THISDIR}/u-boot-toradex:"
+
+SRC_URI += "\
+ file://imx8mp-verdin-mikrophone.dtsi \
+ file://imx8mp-verdin-wifi-mikrophone.dts \
+ file://imx8mp-verdin-nonwifi-mikrophone.dts \
+ "
+
+DTS_SRCDIR = "dts/upstream/src/arm64/freescale"
+
+do_configure:append() {
+ cp ${WORKDIR}/imx8mp-verdin-mikrophone.dtsi ${S}/${DTS_SRCDIR}
+ cp ${WORKDIR}/imx8mp-verdin-wifi-mikrophone.dts ${S}/${DTS_SRCDIR}
+ cp ${WORKDIR}/imx8mp-verdin-nonwifi-mikrophone.dts ${S}/${DTS_SRCDIR}
+ # Remove exisiting fdtfile, if there is one
+ sed -i '/"fdtfile=.*\\0" \\/d' ${S}/include/configs/verdin-imx8mp.h
+ # Add new fdtfile
+ sed -i 's/\("fdt_board=.*\\0" \\\)/\0\n\t"fdtfile=imx8mp-verdin-wifi-mikrophone.dtb\\0" \\/' ${S}/include/configs/verdin-imx8mp.h
+} \ No newline at end of file
diff --git a/yocto/meta-mikrophone/recipes-images/images/mikrophone-image.bb b/yocto/meta-mikrophone/recipes-images/images/mikrophone-image.bb
new file mode 100644
index 0000000..4a88221
--- /dev/null
+++ b/yocto/meta-mikrophone/recipes-images/images/mikrophone-image.bb
@@ -0,0 +1,74 @@
+inherit core-image
+
+SUMMARY = "mikroPhone image"
+DESCRIPTION = "mikroPhone image"
+
+LICENSE = "MIT"
+
+#Prefix to the resulting deployable tarball name
+export IMAGE_BASENAME = "mikroPhone-Image"
+MACHINE_NAME ?= "${MACHINE}"
+IMAGE_NAME = "${MACHINE_NAME}_${IMAGE_BASENAME}"
+
+IMAGE_FEATURES += " \
+ ${@bb.utils.contains('DISTRO_FEATURES', 'wayland', 'weston', '', d)} \
+"
+
+# Copy Licenses to image /usr/share/common-license
+COPY_LIC_MANIFEST ?= "1"
+COPY_LIC_DIRS ?= "1"
+
+add_rootfs_version () {
+ printf "${DISTRO_NAME} ${DISTRO_VERSION} (${DISTRO_CODENAME}) \\\n \\\l\n" > ${IMAGE_ROOTFS}/etc/issue
+ printf "${DISTRO_NAME} ${DISTRO_VERSION} (${DISTRO_CODENAME}) %%h\n" > ${IMAGE_ROOTFS}/etc/issue.net
+ printf "${IMAGE_NAME}\n\n" >> ${IMAGE_ROOTFS}/etc/issue
+ printf "${IMAGE_NAME}\n\n" >> ${IMAGE_ROOTFS}/etc/issue.net
+}
+
+add_home_root_symlink () {
+ ln -sf ${ROOT_HOME} ${IMAGE_ROOTFS}/home/root
+}
+
+# add the rootfs version to the welcome banner
+ROOTFS_POSTPROCESS_COMMAND += " add_rootfs_version; add_home_root_symlink;"
+
+IMAGE_LINGUAS = "en-us"
+#IMAGE_LINGUAS = "de-de fr-fr en-gb en-us pt-br es-es kn-in ml-in ta-in"
+
+CONMANPKGS ?= "connman connman-plugin-loopback connman-plugin-ethernet connman-plugin-wifi connman-client"
+
+IMAGE_INSTALL += " \
+ packagegroup-boot \
+ packagegroup-basic \
+ packagegroup-base-tdx-cli \
+ packagegroup-machine-tdx-cli \
+ packagegroup-wifi-tdx-cli \
+ packagegroup-wifi-fw-tdx-cli \
+ udev-extraconf \
+ ${CONMANPKGS} \
+ ${@bb.utils.contains('DISTRO_FEATURES', 'systemd', \
+ 'timestamp-service systemd-analyze', '', d)} \
+ ${@bb.utils.contains('DISTRO_FEATURES', 'x11 wayland', \
+ 'weston-xwayland xterm', '', d)} \
+ ${@bb.utils.contains('MACHINE_FEATURES', 'tpm2', \
+ 'packagegroup-tpm2-tdx-cli', '', d)} \
+ \
+ packagegroup-tdx-cli \
+ packagegroup-tdx-graphical \
+ packagegroup-fsl-isp \
+ \
+ bash \
+ coreutils \
+ less \
+ makedevs \
+ mime-support \
+ net-tools \
+ util-linux \
+ v4l-utils \
+ \
+ gpicview \
+ media-files \
+ \
+ gnupg \
+ weston weston-init wayland-terminal-launch \
+"
diff --git a/yocto/meta-mikrophone/recipes-kernel/linux/device-tree-overlays/mikroPhone-panel_overlay.dts b/yocto/meta-mikrophone/recipes-kernel/linux/device-tree-overlays/mikroPhone-panel_overlay.dts
new file mode 100644
index 0000000..bee2682
--- /dev/null
+++ b/yocto/meta-mikrophone/recipes-kernel/linux/device-tree-overlays/mikroPhone-panel_overlay.dts
@@ -0,0 +1,110 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/*
+ * Copyright 2025 Uros Majstorovic
+ */
+
+// adapted from: https://git.toradex.com/cgit/device-tree-overlays.git/tree/overlays/verdin-imx8mp_panel-cap-touch-10inch-lvds_overlay.dts?h=toradex_6.6-2.2.x-imx
+// Verdin iMX8M Plus single-channel LVDS
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/pwm/pwm.h>
+#include "freescale/imx8mp-pinfunc.h"
+
+/ {
+ compatible = "toradex,verdin-imx8mp";
+};
+
+&{/} {
+ backlight_lvds_native: backlight-lvds-native {
+ compatible = "pwm-backlight";
+ pinctrl-names = "default";
+ brightness-levels = <0 45 63 88 119 158 203 255>;
+ default-brightness-level = <4>;
+ /* Verdin PWM_1 (SODIMM 15) */
+ pwms = <&pwm1 0 6666667>;
+ };
+
+ panel-lvds-native {
+ compatible = "panel-lvds";
+ backlight = <&backlight_lvds_native>;
+ data-mapping = "vesa-24";
+ height-mm = <110>;
+ width-mm = <62>;
+
+ panel-timing {
+ clock-frequency = <36000000>;
+ hactive = <480>;
+ hfront-porch = <23 60 71>;
+ hsync-len = <15 40 47>;
+ hback-porch = <23 60 71>;
+
+ vactive = <854>;
+ vfront-porch = <5 7 10>;
+ vsync-len = <6 9 12>;
+ vback-porch = <5 7 10>;
+
+ hsync-active = <0>;
+ vsync-active = <0>;
+ de-active = <0>;
+ pixelclk-active = <1>; /* positive edge */
+ };
+
+ port {
+ panel_lvds_native_in: endpoint {
+ remote-endpoint = <&lvds_out>;
+ };
+ };
+ };
+};
+
+/* Verdin I2C_1 */
+&i2c4 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "okay";
+
+ gt911@5d {
+ compatible = "goodix,gt911";
+ reg = <0x5d>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&gpio1>;
+ /* Verdin GPIO_3 (SODIMM 210) */
+ interrupt-parent = <&gpio1>;
+ interrupts = <5 IRQ_TYPE_EDGE_FALLING>;
+ /* Verdin GPIO_4 (SODIMM 212) */
+ reset-gpios = <&gpio1 6 GPIO_ACTIVE_LOW>;
+ status = "okay";
+ };
+};
+
+&lcdif2 {
+ status = "okay";
+};
+
+&ldb {
+ status = "okay";
+
+ lvds-channel@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ fsl,data-mapping = "spwg";
+ fsl,data-width = <24>;
+ status = "okay";
+
+ port@1 {
+ reg = <1>;
+
+ lvds_out: endpoint {
+ remote-endpoint = <&panel_lvds_native_in>;
+ };
+ };
+ };
+};
+
+&ldb_phy {
+ status = "okay";
+};
diff --git a/yocto/meta-mikrophone/recipes-kernel/linux/device-tree-overlays_git.bbappend b/yocto/meta-mikrophone/recipes-kernel/linux/device-tree-overlays_git.bbappend
new file mode 100644
index 0000000..cae7974
--- /dev/null
+++ b/yocto/meta-mikrophone/recipes-kernel/linux/device-tree-overlays_git.bbappend
@@ -0,0 +1,15 @@
+FILESEXTRAPATHS:prepend := "${THISDIR}/device-tree-overlays:"
+
+MIKROPHONE_OVERLAYS_BINARY = "verdin-imx8mp_hdmi_overlay.dtbo mikroPhone-panel_overlay.dtbo"
+
+SRC_URI += " \
+ file://mikroPhone-panel_overlay.dts \
+"
+
+TEZI_EXTERNAL_KERNEL_DEVICETREE = "${MIKROPHONE_OVERLAYS_BINARY}"
+
+TEZI_EXTERNAL_KERNEL_DEVICETREE_BOOT = "${MIKROPHONE_OVERLAYS_BINARY}"
+
+do_collect_overlays:prepend() {
+ cp ${WORKDIR}/mikroPhone-panel_overlay.dts ${S}
+} \ No newline at end of file
diff --git a/yocto/meta-mikrophone/recipes-kernel/linux/linux-toradex%.bbappend b/yocto/meta-mikrophone/recipes-kernel/linux/linux-toradex%.bbappend
new file mode 100644
index 0000000..a706b06
--- /dev/null
+++ b/yocto/meta-mikrophone/recipes-kernel/linux/linux-toradex%.bbappend
@@ -0,0 +1,20 @@
+FILESEXTRAPATHS:prepend := "${THISDIR}/linux-toradex:"
+
+# Prevent the use of in-tree defconfig
+# unset KBUILD_DEFCONFIG
+
+SRC_URI += "\
+ file://imx8mp-verdin-mikrophone.dtsi \
+ file://imx8mp-verdin-wifi-mikrophone.dts \
+ file://imx8mp-verdin-nonwifi-mikrophone.dts \
+ file://kernel_lvds_freq.patch \
+ "
+
+# For arm64 bit freescale/NXP devices
+DTS_SRCDIR = "arch/arm64/boot/dts/freescale"
+
+do_configure:append() {
+ cp ${WORKDIR}/imx8mp-verdin-mikrophone.dtsi ${S}/${DTS_SRCDIR}
+ cp ${WORKDIR}/imx8mp-verdin-wifi-mikrophone.dts ${S}/${DTS_SRCDIR}
+ cp ${WORKDIR}/imx8mp-verdin-nonwifi-mikrophone.dts ${S}/${DTS_SRCDIR}
+} \ No newline at end of file
diff --git a/yocto/meta-mikrophone/recipes-kernel/linux/linux-toradex/imx8mp-verdin-mikrophone.dtsi b/yocto/meta-mikrophone/recipes-kernel/linux/linux-toradex/imx8mp-verdin-mikrophone.dtsi
new file mode 100644
index 0000000..7c23309
--- /dev/null
+++ b/yocto/meta-mikrophone/recipes-kernel/linux/linux-toradex/imx8mp-verdin-mikrophone.dtsi
@@ -0,0 +1,169 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/*
+ * Copyright 2025 Uros Majstorovic
+ */
+
+/* Verdin HDMI_1 Audio */
+&aud2htx {
+ status = "okay";
+};
+
+/* Verdin SPI_1 */
+&ecspi1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "okay";
+
+ spidev@0 {
+ /* Use compatible "rohm,dh2228fv" to bind spidev driver */
+ compatible = "rohm,dh2228fv";
+ reg = <0>;
+ spi-max-frequency = <50000000>;
+ };
+};
+
+&eqos {
+ status = "disabled";
+};
+
+&fec {
+ status = "disabled";
+};
+
+&flexcan1 {
+ status = "disabled";
+};
+
+&flexcan2 {
+ status = "disabled";
+};
+
+/* Verdin QSPI_1 */
+&flexspi {
+ status = "disabled";
+};
+
+&gpio4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ctrl_sleep_moci>;
+};
+
+/* Verdin I2C_2_DSI */
+&i2c2 {
+ status = "disabled";
+};
+
+/* CAM I2C, disabled for now */
+&i2c3 {
+ status = "disabled";
+};
+
+/* Verdin I2C_1 */
+&i2c4 {
+ status = "okay";
+};
+
+/* Verdin PCIE_1 */
+&pcie {
+ status = "okay";
+};
+
+&pcie_phy {
+ status = "okay";
+};
+
+/* Verdin PWM_1 */
+&pwm1 {
+ status = "okay";
+};
+
+/* Verdin PWM_2 */
+&pwm2 {
+ status = "disabled";
+};
+
+/* Verdin PWM_3_DSI */
+&pwm3 {
+ status = "disabled";
+};
+
+&reg_usdhc2_vmmc {
+ vin-supply = <&reg_3p3v>;
+};
+
+/* Verdin HDMI_1 Audio */
+&sound_hdmi {
+ status = "okay";
+};
+
+/* Verdin UART_1 */
+&uart1 {
+ status = "disabled";
+};
+
+/* Verdin UART_2 */
+&uart2 {
+ status = "disabled";
+};
+
+/* Verdin UART_3, used as the Linux Console */
+&uart3 {
+ status = "okay";
+};
+
+/* Verdin USB_1 */
+&usb3_0 {
+ status = "okay";
+};
+
+&usb3_phy0 {
+ status = "okay";
+};
+
+/* Verdin USB_2 */
+&usb3_1 {
+ // fsl,permanently-attached;
+ status = "okay";
+};
+
+&usb3_phy1 {
+ status = "okay";
+};
+
+/* Verdin SDCard */
+&usdhc2 {
+ status = "okay";
+};
+
+/* Video and graphics */
+&vpu_g1 {
+ status = "okay";
+};
+
+&vpu_g2 {
+ status = "okay";
+};
+
+&vpu_vc8000e {
+ status = "okay";
+};
+
+&vpu_v4l2 {
+ status = "okay";
+};
+
+&gpu_2d {
+ status = "okay";
+};
+
+&gpu_3d {
+ status = "okay";
+};
+
+&ml_vipsi {
+ status = "okay";
+};
+
+&mix_gpu_ml {
+ status = "okay";
+};
diff --git a/yocto/meta-mikrophone/recipes-kernel/linux/linux-toradex/imx8mp-verdin-nonwifi-mikrophone.dts b/yocto/meta-mikrophone/recipes-kernel/linux/linux-toradex/imx8mp-verdin-nonwifi-mikrophone.dts
new file mode 100644
index 0000000..91c08a7
--- /dev/null
+++ b/yocto/meta-mikrophone/recipes-kernel/linux/linux-toradex/imx8mp-verdin-nonwifi-mikrophone.dts
@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/*
+ * Copyright 2025 Uros Majstorovic
+ */
+
+/dts-v1/;
+
+#include "imx8mp-verdin.dtsi"
+#include "imx8mp-verdin-nonwifi.dtsi"
+#include "imx8mp-verdin-mikrophone.dtsi"
+
+/ {
+ model = "Toradex Verdin iMX8M Plus on mikroPhone";
+ compatible = "toradex,verdin-imx8mp-nonwifi-mikrophone",
+ "toradex,verdin-imx8mp-wifi",
+ "toradex,verdin-imx8mp",
+ "fsl,imx8mp";
+};
diff --git a/yocto/meta-mikrophone/recipes-kernel/linux/linux-toradex/imx8mp-verdin-wifi-mikrophone.dts b/yocto/meta-mikrophone/recipes-kernel/linux/linux-toradex/imx8mp-verdin-wifi-mikrophone.dts
new file mode 100644
index 0000000..35792e1
--- /dev/null
+++ b/yocto/meta-mikrophone/recipes-kernel/linux/linux-toradex/imx8mp-verdin-wifi-mikrophone.dts
@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/*
+ * Copyright 2025 Uros Majstorovic
+ */
+
+/dts-v1/;
+
+#include "imx8mp-verdin.dtsi"
+#include "imx8mp-verdin-wifi.dtsi"
+#include "imx8mp-verdin-mikrophone.dtsi"
+
+/ {
+ model = "Toradex Verdin iMX8M Plus WB on mikroPhone";
+ compatible = "toradex,verdin-imx8mp-wifi-mikrophone",
+ "toradex,verdin-imx8mp-wifi",
+ "toradex,verdin-imx8mp",
+ "fsl,imx8mp";
+};
diff --git a/yocto/meta-mikrophone/recipes-kernel/linux/linux-toradex/kernel_lvds_freq.patch b/yocto/meta-mikrophone/recipes-kernel/linux/linux-toradex/kernel_lvds_freq.patch
new file mode 100644
index 0000000..9955bc4
--- /dev/null
+++ b/yocto/meta-mikrophone/recipes-kernel/linux/linux-toradex/kernel_lvds_freq.patch
@@ -0,0 +1,62 @@
+diff --git a/arch/arm64/boot/dts/freescale/imx8mp.dtsi b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
+index 55adf1bf45d9..c875474e6c45 100644
+--- a/arch/arm64/boot/dts/freescale/imx8mp.dtsi
++++ b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
+@@ -752,7 +752,7 @@ clk: clock-controller@30380000 {
+ <800000000>,
+ <393216000>,
+ <361267200>,
+- <1039500000>;
++ <252000000>;
+ };
+
+ src: reset-controller@30390000 {
+diff --git a/drivers/clk/imx/clk-pll14xx.c b/drivers/clk/imx/clk-pll14xx.c
+index 6c17786ecb9f..8c9840f08c0e 100644
+--- a/drivers/clk/imx/clk-pll14xx.c
++++ b/drivers/clk/imx/clk-pll14xx.c
+@@ -75,6 +75,7 @@ static const struct imx_pll14xx_rate_table imx_pll1443x_tbl[] = {
+ PLL_1443X_RATE(49152000U, 393, 3, 6, 0x374c),
+ PLL_1443X_RATE(45158400U, 241, 2, 6, 0xd845),
+ PLL_1443X_RATE(40960000U, 109, 1, 6, 0x3a07),
++ PLL_1443X_RATE(252000000U, 84, 2, 2, 0),
+ };
+
+ struct imx_pll14xx_clk imx_1443x_pll = {
+diff --git a/drivers/gpu/drm/imx/imx8mp-ldb.c b/drivers/gpu/drm/imx/imx8mp-ldb.c
+index e3f5c5e6e842..55dbafa863cf 100644
+--- a/drivers/gpu/drm/imx/imx8mp-ldb.c
++++ b/drivers/gpu/drm/imx/imx8mp-ldb.c
+@@ -186,15 +186,6 @@ imx8mp_ldb_encoder_atomic_check(struct drm_encoder *encoder,
+ return -EINVAL;
+ }
+
+- /*
+- * Due to limited video PLL frequency points on i.MX8mp,
+- * we do mode fixup here in case any mode is unsupported.
+- */
+- if (ldb->dual)
+- mode->clock = mode->clock > 100000 ? 148500 : 74250;
+- else
+- mode->clock = 74250;
+-
+ return 0;
+ }
+
+@@ -212,16 +203,6 @@ imx8mp_ldb_encoder_mode_valid(struct drm_encoder *encoder,
+ if (ldb_ch->panel)
+ return MODE_OK;
+
+- /*
+- * Due to limited video PLL frequency points on i.MX8mp,
+- * we do mode valid check here.
+- */
+- if (ldb->dual && mode->clock != 74250 && mode->clock != 148500)
+- return MODE_NOCLOCK;
+-
+- if (!ldb->dual && mode->clock != 74250)
+- return MODE_NOCLOCK;
+-
+ return MODE_OK;
+ }
+
diff --git a/yocto/overlays/mikroPhone-panel_overlay.dts b/yocto/overlays/mikroPhone-panel_overlay.dts
index 0bc14b3..bee2682 100644
--- a/yocto/overlays/mikroPhone-panel_overlay.dts
+++ b/yocto/overlays/mikroPhone-panel_overlay.dts
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
/*
- * Copyright 2023 Toradex
+ * Copyright 2025 Uros Majstorovic
*/
// adapted from: https://git.toradex.com/cgit/device-tree-overlays.git/tree/overlays/verdin-imx8mp_panel-cap-touch-10inch-lvds_overlay.dts?h=toradex_6.6-2.2.x-imx
@@ -32,8 +32,8 @@
compatible = "panel-lvds";
backlight = <&backlight_lvds_native>;
data-mapping = "vesa-24";
- height-mm = <136>;
- width-mm = <217>;
+ height-mm = <110>;
+ width-mm = <62>;
panel-timing {
clock-frequency = <36000000>;
@@ -61,16 +61,8 @@
};
};
-&gpu_2d {
- status = "okay";
-};
-
-&gpu_3d {
- status = "okay";
-};
-
/* Verdin I2C_1 */
-&i2c1 {
+&i2c4 {
#address-cells = <1>;
#size-cells = <0>;
status = "okay";
@@ -116,16 +108,3 @@
&ldb_phy {
status = "okay";
};
-
-&mix_gpu_ml {
- status = "okay";
-};
-
-&ml_vipsi {
- status = "okay";
-};
-
-/* Verdin PWM_2 */
-&pwm1 {
- status = "okay";
-};