diff options
Diffstat (limited to 'code/esp32/components/eos/net.c')
-rw-r--r-- | code/esp32/components/eos/net.c | 190 |
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); +} |