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--fw/esp32/components/eos/cell_pcm.c309
-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/i2c.h9
-rw-r--r--fw/fe310/eos/dev/Makefile11
-rw-r--r--fw/fe310/eos/dev/aon.c29
-rw-r--r--fw/fe310/eos/dev/aon.h4
-rw-r--r--fw/fe310/eos/dev/batt.c54
-rw-r--r--fw/fe310/eos/dev/batt.h4
-rw-r--r--fw/fe310/eos/dev/cam.h14
-rw-r--r--fw/fe310/eos/dev/cam_def.h65
-rw-r--r--fw/fe310/eos/dev/net.c41
-rw-r--r--fw/fe310/eos/dev/net.h7
-rw-r--r--fw/fe310/eos/dev/pwr.c48
-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.c38
-rw-r--r--fw/fe310/eos/dev/sdcard.h3
-rw-r--r--fw/fe310/eos/net/pwr.c80
-rw-r--r--fw/fe310/eos/net/pwr.h10
-rw-r--r--hw/library/usb.dcm3
-rw-r--r--hw/library/usb.lib44
-rw-r--r--yocto/README84
-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/recipes-images/images/mikrophone-image.bb74
39 files changed, 1136 insertions, 615 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..ed33fa0 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_async(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/fw/esp32/components/eos/cell_pcm.c b/fw/esp32/components/eos/cell_pcm.c
deleted file mode 100644
index b993021..0000000
--- a/fw/esp32/components/eos/cell_pcm.c
+++ /dev/null
@@ -1,309 +0,0 @@
-#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 <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 33
-#define PCM_GPIO_WS 4
-#define PCM_GPIO_DIN 34
-#define PCM_GPIO_DOUT 2
-
-#define PCM_ETYPE_WRITE 1
-
-static EOSBufQ pcm_buf_q;
-static unsigned char *pcm_bufq_array[PCM_SIZE_BUFQ];
-
-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;
- }
-
- case I2S_EVENT_DMA_ERROR: {
- ESP_LOGE(TAG, "*** I2S DMA ERROR ***");
- break;
- }
-
- case I2S_EVENT_MAX: {
- hold_cnt = PCM_HOLD_CNT_RX;
- break;
- }
-
- default:
- break;
- }
- }
- }
- 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;
- 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;
-
- for (i=0; i<size/2; i++) {
- data[i * 2] = buf[i * 8 + 3];
- data[i * 2 + 1] = buf[i * 8 + 2];
- }
-
- return bytes_r / 4;
-}
-
-static ssize_t pcm_expand(unsigned char *buf, unsigned char *data, size_t size) {
- int i;
-
- if (size > PCM_MIC_WM) return EOS_ERR;
-
- 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];
- }
-
- return size * 4;
-}
-
-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;
-
- eos_msgq_pop(&pcm_evt_q, &_type, &buf, &_len);
- } 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;
- }
-
- 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);
-
- 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);
-}
-
-void eos_cell_pcm_stop(void) {
- char active;
-
- xSemaphoreTake(mutex, portMAX_DELAY);
- active = pcm_active;
- pcm_active = 0;
- xSemaphoreGive(mutex);
-
- if (active) i2s_stop(I2S_NUM_0);
-}
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/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/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..3d8aaf6
--- /dev/null
+++ b/fw/fe310/eos/dev/aon.c
@@ -0,0 +1,29 @@
+#include <stdlib.h>
+#include <stdint.h>
+
+#include "eos.h"
+#include "soc/aon.h"
+
+#include "aon.h"
+
+#ifdef EOS_DEBUG
+#include <stdio.h>
+#endif
+
+#define AON_EVE_REG 0
+#define AON_EVE_MASK 0x03
+
+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(0, power_state);
+}
+
+uint8_t eos_aon_load4eve(void) {
+ return (eos_aon_get_reg(AON_EVE_REG) & AON_EVE_MASK);
+}
diff --git a/fw/fe310/eos/dev/aon.h b/fw/fe310/eos/dev/aon.h
new file mode 100644
index 0000000..22ba84a
--- /dev/null
+++ b/fw/fe310/eos/dev/aon.h
@@ -0,0 +1,4 @@
+#include <stdint.h>
+
+void eos_aon_save4eve(uint8_t power_state);
+uint8_t eos_aon_load4eve(void); \ No newline at end of file
diff --git a/fw/fe310/eos/dev/batt.c b/fw/fe310/eos/dev/batt.c
new file mode 100644
index 0000000..6f1eb97
--- /dev/null
+++ b/fw/fe310/eos/dev/batt.c
@@ -0,0 +1,54 @@
+#include <stdlib.h>
+#include <stdint.h>
+
+#include "eos.h"
+#include "soc/pwr.h"
+
+#include "drv/bq25895.h"
+
+#ifdef EOS_DEBUG
+#include <stdio.h>
+#endif
+
+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
+ printf("BQ25895:\n");
+ for (i=0; i<0x15; i++) {
+ rv = bq25895_reg_read(i, &data);
+ if (!rv) printf(" 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..5153464
--- /dev/null
+++ b/fw/fe310/eos/dev/cam.h
@@ -0,0 +1,14 @@
+#include "cam_def.h"
+#include "drv/ov2640.h"
+#include "drv/arducam.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
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/net.c b/fw/fe310/eos/dev/net.c
index d340e29..c8b90f3 100644
--- a/fw/fe310/eos/dev/net.c
+++ b/fw/fe310/eos/dev/net.c
@@ -3,13 +3,12 @@
#include "encoding.h"
#include "platform.h"
+#include "board.h"
#include "eos.h"
#include "msgq.h"
#include "event.h"
-#include "board.h"
-
#include "soc/interrupt.h"
#include "soc/timer.h"
#include "soc/pwr.h"
@@ -331,7 +330,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);
@@ -364,12 +363,15 @@ int eos_net_init(uint8_t wakeup_cause) {
return EOS_OK;
}
-int eos_net_run(uint8_t wakeup_cause) {
+int eos_net_run(void) {
+ uint8_t wakeup_cause;
+
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) {
+ if (wakeup_cause != EOS_PWR_WAKE_PIN) {
net_xchg_wake();
}
if (!(net_state_flags & NET_STATE_FLAG_CTS)) {
@@ -413,9 +415,9 @@ int eos_net_sleep(uint32_t timeout) {
if (rv) return rv;
- start = eos_time_get_tick();
+ start = eos_get_tick();
do {
- if (eos_time_delta_ms(start) > timeout) return EOS_ERR_TIMEOUT;
+ if (eos_tdelta_ms(start) > timeout) return EOS_ERR_TIMEOUT;
clear_csr(mstatus, MSTATUS_MIE);
eos_evtq_flush_isr();
done = (eos_msgq_len(&net_send_q) == 0);
@@ -428,7 +430,7 @@ int eos_net_sleep(uint32_t timeout) {
} while (!done);
while (!(GPIO_REG(GPIO_RISE_IP) & (1 << NET_PIN_CTS))) {
- if (eos_time_delta_ms(start) > timeout) {
+ if (eos_tdelta_ms(start) > timeout) {
rv = EOS_ERR_TIMEOUT;
break;
}
@@ -516,29 +518,28 @@ 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;
+ int sync = 0, dsel = 0;
unsigned char _type = *type;
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 & EOS_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;
+ if ((flags & EOS_NET_FLAG_ONEW) && !(net_state_flags & NET_STATE_FLAG_RUN)) sync = 1;
+ if (sync && !(net_state_flags & NET_STATE_FLAG_RUN)) {
set_csr(mstatus, MSTATUS_MIE);
- spi_dev = eos_spi_dev();
- _rv = eos_spi_deselect();
- if (_rv) return _rv;
+
+ rv = eos_spi_select(EOS_SPI_DEV_NET);
+ if (rv) return rv;
+
+ dsel = 1;
clear_csr(mstatus, MSTATUS_MIE);
}
- if (_sync) {
+ if (sync) {
net_pause();
net_wait4cts();
if (flags & EOS_NET_FLAG_SYNC) {
@@ -566,7 +567,7 @@ static int net_xchg(unsigned char *type, unsigned char *buffer, uint16_t *len, u
}
set_csr(mstatus, MSTATUS_MIE);
- if (spi_dev != EOS_SPI_DEV_NET) eos_spi_select(spi_dev);
+ if (dsel) eos_spi_deselect();
return rv;
}
diff --git a/fw/fe310/eos/dev/net.h b/fw/fe310/eos/dev/net.h
index 2482a32..ead88b6 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,7 +7,7 @@
#define EOS_NET_SIZE_BUF EOS_NET_MTU
#define EOS_NET_MTYPE_SOCK 1
-#define EOS_NET_MTYPE_RNG 3
+#define EOS_NET_MTYPE_RNG 3
#define EOS_NET_MTYPE_POWER 4
#define EOS_NET_MTYPE_WIFI 5
@@ -27,8 +28,8 @@
#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);
diff --git a/fw/fe310/eos/dev/pwr.c b/fw/fe310/eos/dev/pwr.c
new file mode 100644
index 0000000..c6537cb
--- /dev/null
+++ b/fw/fe310/eos/dev/pwr.c
@@ -0,0 +1,48 @@
+#include <stdlib.h>
+#include <stdint.h>
+
+#include "eos.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"
+
+#ifdef EOS_DEBUG
+#include <stdio.h>
+#endif
+
+void eos_pwr_sys_sleep(void) {
+ int rv;
+
+ rv = eos_lcd_sleep();
+#ifdef EOS_DEBUG
+ if (rv) printf("PWR SLEEP: LCD SLEEP ERR:%d\n", rv);
+#endif
+
+ rv = eos_ctp_sleep();
+#ifdef EOS_DEBUG
+ if (rv) printf("PWR SLEEP: CTP SLEEP ERR:%d\n", rv);
+#endif
+
+ rv = eos_eve_sleep();
+#ifdef EOS_DEBUG
+ if (rv) printf("PWR SLEEP: EVE SLEEP ERR:%d\n", rv);
+#endif
+
+ rv = eos_net_sleep(1000);
+#ifdef EOS_DEBUG
+ if (rv) printf("PWR SLEEP: NET SLEEP ERR:%d\n", rv);
+#endif
+
+ eos_flash_norm();
+
+ eos_pwr_sleep();
+}
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..1edad96
--- /dev/null
+++ b/fw/fe310/eos/dev/sdcard.c
@@ -0,0 +1,38 @@
+#include <stdlib.h>
+#include <stdint.h>
+
+#include "eos.h"
+
+#include "board.h"
+#include "spi.h"
+
+#include "drv/sdcard.h"
+#include "sdcard.h"
+
+#ifdef EOS_DEBUG
+#include <stdio.h>
+#endif
+
+void eos_sdc_insert(int sdc_det) {
+ int rv;
+
+ rv = EOS_OK;
+ if (sdc_det) {
+ 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(1000);
+ eos_spi_deselect();
+
+sdc_insert_fin:
+ eos_spi_set_div(EOS_SPI_DEV_SDC, SPI_DIV_SDC);
+ } else {
+ sdc_clear();
+ }
+
+#ifdef EOS_DEBUG
+ if (rv) printf("SDC INSERT ERR:%d\n", rv);
+#endif
+}
diff --git a/fw/fe310/eos/dev/sdcard.h b/fw/fe310/eos/dev/sdcard.h
new file mode 100644
index 0000000..cefc304
--- /dev/null
+++ b/fw/fe310/eos/dev/sdcard.h
@@ -0,0 +1,3 @@
+#include <stdint.h>
+
+void eos_sdc_insert(int sdc_det);
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/hw/library/usb.dcm b/hw/library/usb.dcm
deleted file mode 100644
index 5f3ed79..0000000
--- a/hw/library/usb.dcm
+++ /dev/null
@@ -1,3 +0,0 @@
-EESchema-DOCLIB Version 2.0
-#
-#End Doc 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/yocto/README b/yocto/README
index ef99121..f170e18 100644
--- a/yocto/README
+++ b/yocto/README
@@ -18,7 +18,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
@@ -76,11 +76,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 +91,43 @@ vi conf/local.conf
...
# set MACHINE:
MACHINE ?= "verdin-imx8mp"
+...
+# set debian packages
+PACKAGE_CLASSES ?= "package_deb"
+...
# append:
ACCEPT_FSL_EULA = "1"
TOOLCHAIN_TARGET_TASK:append = " kernel-devsrc"
+TOOLCHAIN_TARGET_TASK:remove = "target-sdk-provides-dummy"
+...
+
+- append mikrophone layer:
+vi conf/bblayers.conf
+# append to BBLAYERS variable:
...
+ ${TOPDIR}/../layers/meta-mikrophone \
+"
+
+# copy yocto/meta-mikrophone to ../layers/ dir from mikroPhone repo
- build:
-bitbake -k tdx-reference-minimal-image -c populate_sdk
+# bitbake -k tdx-reference-minimal-image
+# bitbake -k tdx-reference-minimal-image -c populate_sdk
+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
+- mikrophone distro.conf in: layers/meta-mikrophone/conf/distro/*.conf
+- mikrophone images in: layers/meta-mikrophone/recipes-images/images/*.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
u-boot
------
@@ -177,3 +204,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/recipes-images/images/mikrophone-image.bb b/yocto/meta-mikrophone/recipes-images/images/mikrophone-image.bb
new file mode 100644
index 0000000..a4ced94
--- /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 \
+"