From 53b7904443109da0aa06e3225cddc0bcbdf85b93 Mon Sep 17 00:00:00 2001 From: Uros Majstorovic Date: Fri, 27 Aug 2021 02:34:46 +0200 Subject: added spi driver for imx8; added lwip tun driver --- fw/esp32/components/eos/app.c | 225 ++++++++++++++++++++++++++++++++++ fw/esp32/components/eos/cell_modem.c | 2 +- fw/esp32/components/eos/cell_pcm.c | 2 +- fw/esp32/components/eos/cell_ussd.c | 2 +- fw/esp32/components/eos/include/app.h | 23 ++++ fw/esp32/components/eos/include/eos.h | 14 ++- fw/esp32/components/eos/include/net.h | 3 +- fw/esp32/components/eos/include/tun.h | 1 + fw/esp32/components/eos/net.c | 33 +++-- fw/esp32/components/eos/power.c | 1 - fw/esp32/components/eos/sock.c | 13 +- fw/esp32/components/eos/tun.c | 65 ++++++++++ fw/esp32/components/eos/wifi.c | 2 +- fw/esp32/main/app_main.c | 8 +- 14 files changed, 360 insertions(+), 34 deletions(-) create mode 100644 fw/esp32/components/eos/app.c create mode 100644 fw/esp32/components/eos/include/app.h create mode 100644 fw/esp32/components/eos/include/tun.h create mode 100644 fw/esp32/components/eos/tun.c (limited to 'fw/esp32') diff --git a/fw/esp32/components/eos/app.c b/fw/esp32/components/eos/app.c new file mode 100644 index 0000000..5f8cc43 --- /dev/null +++ b/fw/esp32/components/eos/app.c @@ -0,0 +1,225 @@ +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "eos.h" +#include "msgq.h" +#include "app.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_SIZE_BUF (EOS_APP_SIZE_BUF + 8) +#define SPI_SIZE_HDR 3 + +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 eos_app_fptr_t app_handler[EOS_APP_MAX_MTYPE]; + +static void bad_handler(unsigned char mtype, unsigned char *buffer, uint16_t len) { + ESP_LOGE(TAG, "bad handler: %d 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); +} + +// 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 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); + 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; + mtype_flags = 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); + } + } + vTaskDelete(NULL); +} + +void eos_app_init(void) { + 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 + +/* common */ +#define EOS_APP_MTU 1500 +#define EOS_APP_SIZE_BUF EOS_APP_MTU + +#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); + +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); diff --git a/fw/esp32/components/eos/include/eos.h b/fw/esp32/components/eos/include/eos.h index 7240c83..6f420ea 100644 --- a/fw/esp32/components/eos/include/eos.h +++ b/fw/esp32/components/eos/include/eos.h @@ -7,19 +7,21 @@ #define EOS_ERR_EMPTY -11 #define EOS_ERR_NOTFOUND -12 +#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_UART 1 #define EOS_TASK_PRIORITY_MODEM 1 #define EOS_TASK_PRIORITY_I2S 1 -#define EOS_TASK_PRIORITY_NET_XCHG 1 -#define EOS_TASK_PRIORITY_UDP_RCVR 1 -#define EOS_TASK_PRIORITY_PWR 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_UART 4096 #define EOS_TASK_SSIZE_MODEM 4096 #define EOS_TASK_SSIZE_I2S 4096 -#define EOS_TASK_SSIZE_NET_XCHG 8192 -#define EOS_TASK_SSIZE_UDP_RCVR 4096 -#define EOS_TASK_SSIZE_PWR 4096 #define EOS_TASK_SSIZE_CELL 4096 +#define EOS_TASK_SSIZE_PWR 4096 diff --git a/fw/esp32/components/eos/include/net.h b/fw/esp32/components/eos/include/net.h index f6b3700..cf0cb6b 100644 --- a/fw/esp32/components/eos/include/net.h +++ b/fw/esp32/components/eos/include/net.h @@ -1,7 +1,8 @@ #include /* common */ -#define EOS_NET_SIZE_BUF 1500 +#define EOS_NET_MTU 1500 +#define EOS_NET_SIZE_BUF EOS_NET_MTU #define EOS_NET_MTYPE_SOCK 1 #define EOS_NET_MTYPE_POWER 4 diff --git a/fw/esp32/components/eos/include/tun.h b/fw/esp32/components/eos/include/tun.h new file mode 100644 index 0000000..3acb2a6 --- /dev/null +++ b/fw/esp32/components/eos/include/tun.h @@ -0,0 +1 @@ +void eos_tun_init(void); \ No newline at end of file diff --git a/fw/esp32/components/eos/net.c b/fw/esp32/components/eos/net.c index e48d714..0491b41 100644 --- a/fw/esp32/components/eos/net.c +++ b/fw/esp32/components/eos/net.c @@ -25,7 +25,8 @@ #define SPI_GPIO_SCLK 18 #define SPI_GPIO_CS 5 -#define SPI_SIZE_BUF (EOS_NET_SIZE_BUF + 8) +#define SPI_SIZE_BUF (EOS_NET_SIZE_BUF + 4) +#define SPI_SIZE_HDR 3 static volatile char net_sleep = 0; @@ -40,7 +41,7 @@ static SemaphoreHandle_t semaph; static TaskHandle_t net_xchg_task_handle; static const char *TAG = "EOS NET"; -static eos_net_fptr_t mtype_handler[EOS_NET_MAX_MTYPE]; +static eos_net_fptr_t net_handler[EOS_NET_MAX_MTYPE]; static void bad_handler(unsigned char mtype, unsigned char *buffer, uint16_t len) { ESP_LOGE(TAG, "bad handler: %d len: %d", mtype, len); @@ -67,17 +68,18 @@ static void net_xchg_task(void *pvParameters) { 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; - spi_slave_transaction_t spi_tr; + + static spi_slave_transaction_t spi_tr; //Configuration for the SPI bus - spi_bus_config_t spi_bus_cfg = { + 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 - spi_slave_interface_config_t spi_slave_cfg = { + static spi_slave_interface_config_t spi_slave_cfg = { .mode = 0, .spics_io_num = SPI_GPIO_CS, .queue_size = 2, @@ -87,13 +89,13 @@ static void net_xchg_task(void *pvParameters) { }; //Initialize SPI slave interface - ret = spi_slave_initialize(VSPI_HOST, &spi_bus_cfg, &spi_slave_cfg, 1); + 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.length = SPI_SIZE_BUF * 8; spi_tr.tx_buffer = buf_send; spi_tr.rx_buffer = buf_recv; + spi_tr.length = SPI_SIZE_BUF * 8; if (eos_power_wakeup_cause()) { wake = 1; @@ -111,7 +113,7 @@ static void net_xchg_task(void *pvParameters) { buf_send[1] = len >> 8; buf_send[2] = len & 0xFF; if (buffer) { - memcpy(buf_send + 3, buffer, len); + memcpy(buf_send + SPI_SIZE_HDR, buffer, len); eos_bufq_push(&net_buf_q, buffer); xSemaphoreGive(semaph); } @@ -148,7 +150,10 @@ static void net_xchg_task(void *pvParameters) { eos_power_net_ready(); wake = 0; } + + if ((spi_tr.trans_len / 8) < SPI_SIZE_HDR) continue; if (buf_recv[0] == 0x00) continue; + if (buf_recv[0] == 0xFF) { // Sleep req if (buf_send[0] == 0) { int abort = 0; @@ -175,13 +180,14 @@ static void net_xchg_task(void *pvParameters) { } 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 + 3; - if ((mtype <= EOS_NET_MAX_MTYPE) && (len <= EOS_NET_SIZE_BUF)) { - mtype_handler[mtype-1](mtype, buffer, len); + buffer = buf_recv + SPI_SIZE_HDR; + if ((mtype <= EOS_NET_MAX_MTYPE) && (len <= EOS_NET_MTU)) { + net_handler[mtype - 1](mtype, buffer, len); } else { bad_handler(mtype, buffer, len); } @@ -225,7 +231,7 @@ void eos_net_init(void) { } for (i=0; i +#include + +#include +#include +#include +#include + +#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) { + unsigned char *buf; + struct pbuf *q; + + for (q = p; q != NULL; q = q->next) { + if (q->len > EOS_APP_MTU) continue; + + buf = eos_app_alloc(); + memcpy(buf, q->payload, q->len); + eos_app_send(EOS_APP_MTYPE_TUN, buf, q->len); + } + + return ERR_OK; +} + +static void ESP_IRAM_ATTR tun_input(unsigned char mtype, unsigned char *buffer, uint16_t len) { + struct netif *netif = &netif_tun; + struct pbuf *p; + int rv; + + if (!netif_is_up(netif)) return; + + p = pbuf_alloc(PBUF_RAW, len, PBUF_RAM); + if (p == NULL) return; + memcpy(p->payload, buffer, len); + rv = netif->input(p, netif); + if (rv != ERR_OK) { + pbuf_free(p); + } +} + +static err_t tun_init(struct netif *netif) { + netif->name[0] = 't'; + netif->name[1] = 'n'; + netif->hostname = NULL; + netif->output = tun_output; + netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_LINK_UP; + netif->mtu = 1500; + + return ERR_OK; +} + +void eos_tun_init(void) { + 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); + 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 05c91c1..d47ae3a 100755 --- a/fw/esp32/components/eos/wifi.c +++ b/fw/esp32/components/eos/wifi.c @@ -75,7 +75,7 @@ static void wifi_event_handler(void *arg, esp_event_base_t event_base, int32_t e for (i=0; i 32) continue; - if (p - rbuf + len + 1 > EOS_NET_SIZE_BUF) break; + if (p - rbuf + len + 1 > EOS_NET_MTU) break; strcpy((char *)p, (char *)scan_r[i].ssid); p += len + 1; } diff --git a/fw/esp32/main/app_main.c b/fw/esp32/main/app_main.c index 145739c..1ae7f7c 100644 --- a/fw/esp32/main/app_main.c +++ b/fw/esp32/main/app_main.c @@ -12,6 +12,8 @@ #include "_net.h" #include "wifi.h" #include "sock.h" +#include "app.h" +#include "tun.h" #include "power.h" #define ESP_INTR_FLAG_DEFAULT 0 @@ -36,7 +38,9 @@ void app_main() { eos_wifi_init(); eos_sock_init(); +#ifdef EOS_WITH_APP + eos_app_init(); + eos_tun_init(); +#endif eos_power_init(); } - - -- cgit v1.2.3