diff options
Diffstat (limited to 'code/esp32')
-rw-r--r-- | code/esp32/components/eos/include/net.h | 19 | ||||
-rw-r--r-- | code/esp32/components/eos/net.c | 208 |
2 files changed, 227 insertions, 0 deletions
diff --git a/code/esp32/components/eos/include/net.h b/code/esp32/components/eos/include/net.h new file mode 100644 index 0000000..21b12dc --- /dev/null +++ b/code/esp32/components/eos/include/net.h @@ -0,0 +1,19 @@ +#include <stdint.h> + +#define EOS_FE310_CMD_FLAG_ONEW 0x10 + +#define EOS_FE310_CMD_WIFI_CONNECT 1 +#define EOS_FE310_CMD_WIFI_DISCONNECT 2 +#define EOS_FE310_CMD_WIFI_SCAN 3 +#define EOS_FE310_CMD_WIFI_PKT 4 +#define EOS_FE310_CMD_MODEM_DATA 5 +#define EOS_FE310_CMD_MODEM_CALL 6 + +#define EOS_FE310_MAX_CMD 8 +#define EOS_FE310_SIZE_Q 64 +#define EOS_FE310_SIZE_BUF 2048 + +typedef void (*eos_fe310_fptr_t) (unsigned char, unsigned char *, uint16_t); + +void eos_fe310_init(void); +int eos_fe310_send(unsigned char cmd, unsigned char *buffer, uint16_t len); diff --git a/code/esp32/components/eos/net.c b/code/esp32/components/eos/net.c new file mode 100644 index 0000000..e9e3af4 --- /dev/null +++ b/code/esp32/components/eos/net.c @@ -0,0 +1,208 @@ +#include <stdio.h> +#include <stdint.h> +#include <stddef.h> +#include <string.h> + +#include <freertos/FreeRTOS.h> +#include <freertos/task.h> +#include <freertos/semphr.h> +// #include <freertos/heap_regions.h> + +#include <esp_system.h> +#include <esp_event.h> +#include <esp_event_loop.h> +#include <esp_log.h> +#include <esp_err.h> +#include <esp_heap_caps.h> +#include <driver/gpio.h> +#include <driver/spi_slave.h> + +#include "eos.h" +#include "msgq.h" +#include "transport.h" +#include "modem.h" +#include "pcm.h" +#include "fe310.h" + +static EOSMsgQ send_q; +static EOSMsgItem send_q_array[EOS_FE310_SIZE_Q]; + +#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 + +static SemaphoreHandle_t mutex; + +static const char *TAG = "EOS"; + +static eos_fe310_fptr_t cmd_handler[EOS_FE310_MAX_CMD]; + +static void bad_handler(unsigned char cmd, unsigned char *buffer, uint16_t len) { + ESP_LOGI(TAG, "FE310 RECV: bad handler: %d", cmd); +} + +static void transceiver(void *pvParameters) { + int repeat = 0; + unsigned char cmd = 0; + unsigned char *buffer; + uint16_t len; + unsigned char *buf_send = heap_caps_malloc(EOS_FE310_SIZE_BUF, MALLOC_CAP_DMA); + unsigned char *buf_recv = heap_caps_malloc(EOS_FE310_SIZE_BUF, MALLOC_CAP_DMA); + + spi_slave_transaction_t t; + memset(&t, 0, sizeof(t)); + + t.length = EOS_FE310_SIZE_BUF*8; + t.tx_buffer = buf_send; + t.rx_buffer = buf_recv; + for (;;) { + if (!repeat) { + xSemaphoreTake(mutex, portMAX_DELAY); + + eos_msgq_pop(&send_q, &cmd, &buffer, &len); + if (cmd) { + buf_send[0] = ((cmd << 3) | (len >> 8)) & 0xFF; + buf_send[1] = len & 0xFF; + if (buffer) memcpy(buf_send + 2, buffer, len); + } else { + WRITE_PERI_REG(GPIO_OUT_W1TC_REG, (1 << SPI_GPIO_RTS)); + buf_send[0] = 0; + buf_send[1] = 0; + } + + xSemaphoreGive(mutex); + } + + memset(buf_recv, 0, EOS_FE310_SIZE_BUF); + spi_slave_transmit(HSPI_HOST, &t, portMAX_DELAY); + repeat = 0; + if (buf_recv[0] != 0) { + cmd = (buf_recv[0] >> 3); + len = ((buf_recv[0] & 0x07) << 8); + len |= buf_recv[1]; + buffer = buf_recv + 2; + if (cmd & EOS_FE310_CMD_FLAG_ONEW) { + cmd &= ~EOS_FE310_CMD_FLAG_ONEW; + if (buf_send[0]) repeat = 1; + } + if (cmd < EOS_FE310_MAX_CMD) { + cmd_handler[cmd](cmd, buffer, len); + } else { + bad_handler(cmd, buffer, len); + } + } else { + // ESP_LOGI(TAG, "FE310 RECV NULL"); + } + // vTaskDelay(5000 / portTICK_PERIOD_MS); + } +} + +// 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) { + WRITE_PERI_REG(GPIO_OUT_W1TS_REG, (1 << SPI_GPIO_CTS)); +} + +// 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) { + WRITE_PERI_REG(GPIO_OUT_W1TC_REG, (1 << SPI_GPIO_CTS)); +} + +static void fe310_wifi_connect_handler(unsigned char cmd, unsigned char *buffer, uint16_t size) { + eos_wifi_connect((char *)buffer, (char *)(buffer+strlen((char *)buffer)+1)); +} + +static void fe310_wifi_pkt_handler(unsigned char cmd, unsigned char *buffer, uint16_t size) { + EOSNetAddr addr; + size_t addr_len = sizeof(addr.host) + sizeof(addr.port); + + memcpy(addr.host, buffer, sizeof(addr.host)); + memcpy(&addr.port, buffer+sizeof(addr.host), sizeof(addr.port)); + eos_wifi_send(buffer+addr_len, size-addr_len, &addr); +} + +static void fe310_modem_data_handler(unsigned char cmd, unsigned char *buffer, uint16_t size) { + eos_modem_write(buffer, size); +} + +static void fe310_modem_call_handler(unsigned char cmd, unsigned char *buffer, uint16_t size) { + eos_pcm_call(); +} + +static void fe310_set_handler(unsigned char cmd, eos_fe310_fptr_t handler) { + cmd_handler[cmd] = handler; +} + +void eos_fe310_init(void) { + esp_err_t ret; + + // 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.pin_bit_mask = (1 << SPI_GPIO_CTS); + gpio_config(&io_conf); + WRITE_PERI_REG(GPIO_OUT_W1TC_REG, (1 << SPI_GPIO_CTS)); + + io_conf.intr_type = GPIO_INTR_DISABLE; + io_conf.mode = GPIO_MODE_OUTPUT; + io_conf.pin_bit_mask = (1 << SPI_GPIO_RTS); + gpio_config(&io_conf); + WRITE_PERI_REG(GPIO_OUT_W1TC_REG, (1 << SPI_GPIO_RTS)); + + //Configuration for the SPI bus + spi_bus_config_t buscfg = { + .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 slvcfg = { + .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 + }; + + //Enable pull-ups on SPI lines so we don't detect rogue pulses when no master is connected. + gpio_set_pull_mode(SPI_GPIO_MOSI, GPIO_PULLUP_ONLY); + gpio_set_pull_mode(SPI_GPIO_SCLK, GPIO_PULLUP_ONLY); + gpio_set_pull_mode(SPI_GPIO_CS, GPIO_PULLUP_ONLY); + + int i; + for (i=0; i<EOS_FE310_MAX_CMD; i++) { + cmd_handler[i] = bad_handler; + } + + //Initialize SPI slave interface + ret=spi_slave_initialize(HSPI_HOST, &buscfg, &slvcfg, 1); + assert(ret==ESP_OK); + + eos_msgq_init(&send_q, send_q_array, EOS_FE310_SIZE_Q); + mutex = xSemaphoreCreateBinary(); + xSemaphoreGive(mutex); + xTaskCreate(&transceiver, "fe310_transceiver", 4096, NULL, EOS_PRIORITY_SPI, NULL); + // xTaskCreatePinnedToCore(&transceiver, "fe310_transceiver", 4096, NULL, EOS_PRIORITY_SPI, NULL, 1); + + fe310_set_handler(EOS_FE310_CMD_WIFI_CONNECT, fe310_wifi_connect_handler); + fe310_set_handler(EOS_FE310_CMD_WIFI_PKT, fe310_wifi_pkt_handler); + fe310_set_handler(EOS_FE310_CMD_MODEM_DATA, fe310_modem_data_handler); + fe310_set_handler(EOS_FE310_CMD_MODEM_CALL, fe310_modem_call_handler); +} + +int eos_fe310_send(unsigned char cmd, unsigned char *buffer, uint16_t len) { + xSemaphoreTake(mutex, portMAX_DELAY); + WRITE_PERI_REG(GPIO_OUT_W1TS_REG, (1 << SPI_GPIO_RTS)); + int rv = eos_msgq_push(&send_q, cmd, buffer, len); + xSemaphoreGive(mutex); + + return rv; +} + + |