summaryrefslogtreecommitdiff
path: root/code/esp32/components/eos/net.c
diff options
context:
space:
mode:
Diffstat (limited to 'code/esp32/components/eos/net.c')
-rw-r--r--code/esp32/components/eos/net.c190
1 files changed, 126 insertions, 64 deletions
diff --git a/code/esp32/components/eos/net.c b/code/esp32/components/eos/net.c
index 4eb4983..c5be1bf 100644
--- a/code/esp32/components/eos/net.c
+++ b/code/esp32/components/eos/net.c
@@ -15,6 +15,7 @@
#include "eos.h"
#include "msgq.h"
+#include "power.h"
#include "net.h"
#define SPI_GPIO_RTS 22
@@ -24,6 +25,10 @@
#define SPI_GPIO_SCLK 18
#define SPI_GPIO_CS 5
+#define SPI_SIZE_BUF (EOS_NET_SIZE_BUF + 8)
+
+static volatile char net_sleep;
+
static EOSBufQ net_buf_q;
static unsigned char *net_bufq_array[EOS_NET_SIZE_BUFQ];
@@ -32,40 +37,74 @@ 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 const char *TAG = "EOS NET";
static eos_net_fptr_t mtype_handler[EOS_NET_MAX_MTYPE];
static void bad_handler(unsigned char mtype, unsigned char *buffer, uint16_t len) {
- ESP_LOGE(TAG, "NET RECV: bad handler: %d", mtype);
+ 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 net_xchg_task(void *pvParameters) {
int repeat = 0;
+ int wake = 0;
unsigned char mtype = 0;
unsigned char *buffer;
uint16_t len;
uint8_t flags;
- unsigned char *buf_send = heap_caps_malloc(EOS_NET_SIZE_BUF, MALLOC_CAP_DMA);
- unsigned char *buf_recv = heap_caps_malloc(EOS_NET_SIZE_BUF, MALLOC_CAP_DMA);
+ 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;
- spi_slave_transaction_t t;
- memset(&t, 0, sizeof(t));
+ //Configuration for the SPI bus
+ 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
+ };
- t.length = EOS_NET_SIZE_BUF*8;
- t.tx_buffer = buf_send;
- t.rx_buffer = buf_recv;
- for (;;) {
+ //Configuration for the SPI slave interface
+ 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, 1);
+ 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;
+
+ while (1) {
if (!repeat) {
xSemaphoreTake(mutex, portMAX_DELAY);
eos_msgq_pop(&net_send_q, &mtype, &buffer, &len, &flags);
if (mtype) {
- buf_send[0] = ((mtype << 3) | (len >> 8)) & 0xFF;
- buf_send[1] = len & 0xFF;
+ buf_send[0] = mtype;
+ buf_send[1] = len >> 8;
+ buf_send[2] = len & 0xFF;
if (buffer) {
- memcpy(buf_send + 2, buffer, len);
+ memcpy(buf_send + 3, buffer, len);
if (flags & EOS_NET_FLAG_BFREE) {
free(buffer);
} else {
@@ -77,46 +116,69 @@ static void net_xchg_task(void *pvParameters) {
gpio_set_level(SPI_GPIO_RTS, 0);
buf_send[0] = 0;
buf_send[1] = 0;
+ buf_send[2] = 0;
}
xSemaphoreGive(mutex);
}
-
- memset(buf_recv, 0, EOS_NET_SIZE_BUF);
- spi_slave_transmit(HSPI_HOST, &t, portMAX_DELAY);
- // ESP_LOGI(TAG, "RECV:%d", (buf_recv[0] >> 3));
repeat = 0;
- if (buf_recv[0] != 0) {
- mtype = (buf_recv[0] >> 3);
- len = ((buf_recv[0] & 0x07) << 8);
- len |= buf_recv[1];
- buffer = buf_recv + 2;
- if (mtype & EOS_NET_MTYPE_FLAG_ONEW) {
- mtype &= ~EOS_NET_MTYPE_FLAG_ONEW;
- if (buf_send[0]) repeat = 1;
- }
- if (mtype <= EOS_NET_MAX_MTYPE) {
- mtype_handler[mtype-1](mtype, buffer, len);
- } else {
- bad_handler(mtype, buffer, len);
- }
+
+ buf_recv[0] = 0;
+ buf_recv[1] = 0;
+ buf_recv[2] = 0;
+ spi_slave_transmit(VSPI_HOST, &spi_tr, portMAX_DELAY);
+ // ESP_LOGD(TAG, "RECV:%d", buf_recv[0]);
+
+ if (wake) {
+ eos_power_1v8rdy();
+ wake = 0;
}
- }
-}
+ if (buf_recv[0] == 0x00) continue;
+ if (buf_recv[0] == 0xFF) { // Sleep req
+ if (buf_send[0] == 0) {
+ int abort = 0;
-// 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);
-}
+ xSemaphoreTake(mutex, portMAX_DELAY);
+ net_sleep = 1;
+ if (eos_msgq_len(&net_send_q)) abort = 1;
+ xSemaphoreGive(mutex);
-// 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);
+ spi_slave_free(VSPI_HOST);
+
+ eos_power_sleep();
+ if (abort) eos_power_wake(EOS_PWR_WAKE_MSG);
+
+ vTaskSuspend(NULL);
+
+ xSemaphoreTake(mutex, portMAX_DELAY);
+ net_sleep = 0;
+ xSemaphoreGive(mutex);
+
+ wake = 1;
+ repeat = 1;
+ spi_slave_initialize(VSPI_HOST, &spi_bus_cfg, &spi_slave_cfg, 1);
+ }
+ continue;
+ }
+ mtype = buf_recv[0];
+ len = (uint16_t)buf_recv[1] << 8;
+ len |= (uint16_t)buf_recv[2] & 0xFF;
+ buffer = buf_recv + 3;
+ if (mtype & EOS_NET_MTYPE_FLAG_ONEW) {
+ mtype &= ~EOS_NET_MTYPE_FLAG_ONEW;
+ if (buf_send[0]) repeat = 1;
+ }
+ if (mtype <= EOS_NET_MAX_MTYPE) {
+ mtype_handler[mtype-1](mtype, buffer, len);
+ } else {
+ bad_handler(mtype, buffer, len);
+ }
+ }
+ vTaskDelete(NULL);
}
void eos_net_init(void) {
int i;
- esp_err_t ret;
// Configuration for the handshake lines
gpio_config_t io_conf;
@@ -137,27 +199,6 @@ void eos_net_init(void) {
gpio_config(&io_conf);
gpio_set_level(SPI_GPIO_RTS, 0);
- //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
- };
-
- //Initialize SPI slave interface
- ret=spi_slave_initialize(HSPI_HOST, &buscfg, &slvcfg, 1);
- assert(ret==ESP_OK);
-
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++) {
@@ -171,7 +212,7 @@ void eos_net_init(void) {
semaph = xSemaphoreCreateCounting(EOS_NET_SIZE_BUFQ, EOS_NET_SIZE_BUFQ);
mutex = xSemaphoreCreateBinary();
xSemaphoreGive(mutex);
- xTaskCreate(&net_xchg_task, "net_xchg", EOS_TASK_SSIZE_NET_XCHG, NULL, EOS_TASK_PRIORITY_NET_XCHG, NULL);
+ xTaskCreate(&net_xchg_task, "net_xchg", EOS_TASK_SSIZE_NET_XCHG, NULL, EOS_TASK_PRIORITY_NET_XCHG, &net_xchg_task_handle);
ESP_LOGI(TAG, "INIT");
}
@@ -194,10 +235,11 @@ void eos_net_free(unsigned char *buf) {
}
int eos_net_send(unsigned char mtype, unsigned char *buffer, uint16_t len, uint8_t flags) {
- int rv;
+ int rv, sleep;
if (flags & EOS_NET_FLAG_BCOPY) xSemaphoreTake(semaph, portMAX_DELAY);
xSemaphoreTake(mutex, portMAX_DELAY);
+ sleep = net_sleep;
gpio_set_level(SPI_GPIO_RTS, 1);
if (flags & EOS_NET_FLAG_BCOPY) {
unsigned char *b = eos_bufq_pop(&net_buf_q);
@@ -207,6 +249,8 @@ int eos_net_send(unsigned char mtype, unsigned char *buffer, uint16_t len, uint8
rv = eos_msgq_push(&net_send_q, mtype, buffer, len, flags);
xSemaphoreGive(mutex);
+ if (sleep) eos_power_wake(EOS_PWR_WAKE_MSG);
+
return rv;
}
@@ -214,3 +258,21 @@ void eos_net_set_handler(unsigned char mtype, eos_net_fptr_t handler) {
mtype_handler[mtype-1] = handler;
}
+void eos_net_sleep_done(void) {
+ gpio_set_level(SPI_GPIO_CTS, 1);
+ vTaskDelay(200 / portTICK_PERIOD_MS);
+ gpio_set_level(SPI_GPIO_CTS, 0);
+}
+
+void eos_net_wake(uint8_t source) {
+ int sleep;
+
+ do {
+ vTaskResume(net_xchg_task_handle);
+ vTaskDelay(10 / portTICK_PERIOD_MS);
+
+ xSemaphoreTake(mutex, portMAX_DELAY);
+ sleep = net_sleep;
+ xSemaphoreGive(mutex);
+ } while (sleep);
+}