From 9804469a30a877a830e115361b0b78859eaa4d67 Mon Sep 17 00:00:00 2001 From: Uros Majstorovic Date: Wed, 11 Dec 2019 03:50:14 +0100 Subject: cell fixed; cell voice test passed --- code/esp32/components/eos/cell.c | 40 ++++++ code/esp32/components/eos/cell_modem.c | 31 +---- code/esp32/components/eos/cell_pcm.c | 222 ++++++++++++++++++++++--------- code/esp32/components/eos/include/cell.h | 17 ++- code/esp32/components/eos/include/eos.h | 2 +- code/esp32/components/eos/include/msgq.h | 11 ++ code/esp32/components/eos/include/net.h | 1 + code/esp32/components/eos/msgq.c | 31 ++++- code/esp32/components/eos/net.c | 52 +++----- code/esp32/main/app_main.c | 3 +- 10 files changed, 275 insertions(+), 135 deletions(-) create mode 100644 code/esp32/components/eos/cell.c (limited to 'code/esp32') diff --git a/code/esp32/components/eos/cell.c b/code/esp32/components/eos/cell.c new file mode 100644 index 0000000..49ddeda --- /dev/null +++ b/code/esp32/components/eos/cell.c @@ -0,0 +1,40 @@ +#include +#include + +#include + +#include "eos.h" +#include "net.h" +#include "cell.h" + +static void cell_handler(unsigned char _mtype, unsigned char *buffer, uint16_t size) { + uint8_t mtype = buffer[0]; + + switch (mtype) { + case EOS_CELL_MTYPE_DATA: + eos_modem_write(buffer+1, size-1); + break; + case EOS_CELL_MTYPE_DATA_START: + eos_modem_set_mode(EOS_CELL_UART_MODE_RELAY); + break; + case EOS_CELL_MTYPE_DATA_STOP: + eos_modem_set_mode(0); + break; + case EOS_CELL_MTYPE_AUDIO: + eos_pcm_push(buffer+1, size-1); + break; + case EOS_CELL_MTYPE_AUDIO_START: + eos_pcm_start(); + break; + case EOS_CELL_MTYPE_AUDIO_STOP: + eos_pcm_stop(); + break; + } +} + +void eos_cell_init(void) { + eos_pcm_init(); + eos_modem_init(); + eos_net_set_handler(EOS_NET_MTYPE_CELL, cell_handler); +} + diff --git a/code/esp32/components/eos/cell_modem.c b/code/esp32/components/eos/cell_modem.c index 2534eb1..af27093 100644 --- a/code/esp32/components/eos/cell_modem.c +++ b/code/esp32/components/eos/cell_modem.c @@ -22,18 +22,12 @@ #define UART_GPIO_DTR 32 #define UART_GPIO_RI 35 - -#define UART_EVENT_MODE_NONE 0 -#define UART_EVENT_MODE_PPP 1 -#define UART_EVENT_MODE_RELAY 2 - static QueueHandle_t uart_queue; -// static uint8_t *uart_data[UART_BUF_SIZE]; static const char *TAG = "EOS MODEM"; static void uart_event_task(void *pvParameters) { - char mode = 0; + char mode = EOS_CELL_UART_MODE_RELAY; uart_event_t event; size_t len; unsigned char *buf; @@ -47,10 +41,10 @@ static void uart_event_task(void *pvParameters) { /* Event of UART receiving data */ switch (mode) { - case UART_EVENT_MODE_PPP: + case EOS_CELL_UART_MODE_PPP: break; - case UART_EVENT_MODE_RELAY: + case EOS_CELL_UART_MODE_RELAY: buf = eos_net_alloc(); buf[0] = EOS_CELL_MTYPE_DATA; len = uart_read_bytes(UART_NUM_2, buf+1, MIN(event.size, EOS_NET_SIZE_BUF-1), 100 / portTICK_RATE_MS); @@ -76,22 +70,6 @@ static void uart_event_task(void *pvParameters) { vTaskDelete(NULL); } -static void modem_handler(unsigned char _mtype, unsigned char *buffer, uint16_t size) { - uint8_t mtype = buffer[0]; - - switch (mtype) { - case EOS_CELL_MTYPE_DATA: - eos_modem_write(buffer+1, size-1); - break; - case EOS_CELL_MTYPE_DATA_START: - eos_modem_set_mode(UART_EVENT_MODE_RELAY); - break; - case EOS_CELL_MTYPE_DATA_STOP: - eos_modem_set_mode(0); - break; - } -} - void eos_modem_init(void) { /* Configure parameters of an UART driver, * communication pins and install the driver */ @@ -117,8 +95,6 @@ void eos_modem_init(void) { // Create a task to handle uart event from ISR xTaskCreate(uart_event_task, "uart_event", EOS_TASK_SSIZE_UART, NULL, EOS_TASK_PRIORITY_UART, NULL); - - eos_net_set_handler(EOS_NET_MTYPE_CELL, modem_handler); ESP_LOGI(TAG, "INIT"); } @@ -128,6 +104,7 @@ ssize_t eos_modem_write(void *data, size_t size) { void eos_modem_set_mode(char mode) { uart_event_t evt; + evt.type = UART_EVENT_MAX; /* my type */ evt.size = mode; xQueueSend(uart_queue, (void *)&evt, portMAX_DELAY); diff --git a/code/esp32/components/eos/cell_pcm.c b/code/esp32/components/eos/cell_pcm.c index 961a322..426cd5f 100644 --- a/code/esp32/components/eos/cell_pcm.c +++ b/code/esp32/components/eos/cell_pcm.c @@ -10,29 +10,46 @@ #include "eos.h" #include "net.h" +#include "msgq.h" #include "cell.h" -static i2s_dev_t* I2S[I2S_NUM_MAX] = {&I2S0, &I2S1}; +#define PCM_MIC_WM 128 +#define PCM_HOLD_CNT_TX 2 +#define PCM_HOLD_CNT_RX 2 +#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 -#define BUF_SIZE 2048 +static EOSBufQ pcm_buf_q; +static unsigned char *pcm_bufq_array[PCM_SIZE_BUFQ]; -#define PCM_GPIO_BCK 33 -#define PCM_GPIO_WS 4 -#define PCM_GPIO_DIN 34 -#define PCM_GPIO_DOUT 2 +static EOSMsgQ pcm_evt_q; +static EOSMsgItem pcm_evtq_array[PCM_SIZE_BUFQ]; + +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) { - size_t size_out; i2s_event_t event; - // Reserve a buffer and process incoming data - uint8_t *data = (uint8_t *) malloc(BUF_SIZE); - - int first = 1; - uint8_t *data_first = NULL; + unsigned char *buf; + unsigned char _type; + size_t bytes_w; + ssize_t bytes_r; + uint16_t bytes_e; + ssize_t hold_bytes_r = 0; + unsigned char *hold_buf = NULL; + static char hold_cnt_tx = 0; + static char hold_cnt_rx = 0; while (1) { // Waiting for I2S event. @@ -40,65 +57,64 @@ static void i2s_event_task(void *pvParameters) { switch (event.type) { case I2S_EVENT_RX_DONE: // Event of I2S receiving data - // printf("*** I2S DATA RECEIVED: %d\n ***", event.size); - i2s_read(I2S_NUM_0, (void *)data, BUF_SIZE, &size_out, 1000 / portTICK_RATE_MS); - if (first) { - if (data_first) { - first = 0; - i2s_write(I2S_NUM_0, (const void *)data_first, BUF_SIZE, &size_out, 1000 / portTICK_RATE_MS); - free(data_first); - data_first = NULL; - } else { - data_first = (uint8_t *) malloc(BUF_SIZE); - memcpy(data_first, data, BUF_SIZE); + if (!hold_cnt_rx) { + buf = eos_net_alloc(); + buf[0] = EOS_CELL_MTYPE_AUDIO; + bytes_r = eos_pcm_read(buf + 1, PCM_MIC_WM); + eos_net_send(EOS_NET_MTYPE_CELL, buf, bytes_r + 1, 0); + } else { + hold_cnt_rx--; + if (hold_buf == NULL) { + hold_buf = eos_net_alloc(); + hold_buf[0] = EOS_CELL_MTYPE_AUDIO; } + hold_bytes_r += eos_pcm_read(hold_buf + 1 + hold_bytes_r, PCM_MIC_WM); + if (hold_cnt_rx == 0) eos_net_send(EOS_NET_MTYPE_CELL, hold_buf, hold_bytes_r + 1, 0); + } + + if (!hold_cnt_tx) { + xSemaphoreTake(mutex, portMAX_DELAY); + eos_msgq_pop(&pcm_evt_q, &_type, &buf, &bytes_e, NULL); + xSemaphoreGive(mutex); + if (buf) { + i2s_write(I2S_NUM_0, (const void *)buf, bytes_e, &bytes_w, portMAX_DELAY); + xSemaphoreTake(mutex, portMAX_DELAY); + eos_bufq_push(&pcm_buf_q, buf); + xSemaphoreGive(mutex); + } + } else { + hold_cnt_tx--; } - i2s_write(I2S_NUM_0, (const void *)data, BUF_SIZE, &size_out, 1000 / portTICK_RATE_MS); break; case I2S_EVENT_DMA_ERROR: ESP_LOGE(TAG, "*** I2S DMA ERROR ***"); break; + case I2S_EVENT_MAX: + hold_cnt_tx = PCM_HOLD_CNT_TX; + hold_cnt_rx = PCM_HOLD_CNT_RX; + hold_bytes_r = 0; + hold_buf = NULL; + break; default: break; } } } - free(data); vTaskDelete(NULL); } -/* -static void i2s_write_task(void *pvParameters) { - uint8_t *data = (uint8_t *) malloc(BUF_SIZE); - memset(data, 0x0, BUF_SIZE); - +void eos_pcm_init(void) { int i; - for (i=0; iconf.tx_mono = 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_MIC_WM) return EOS_ERR; - esp_err_t ret = i2s_write(I2S_NUM_0, (const void *)data, size, &size_out, portMAX_DELAY); + esp_err_t ret = i2s_read(I2S_NUM_0, (void *)buf, size * 4, &bytes_r, portMAX_DELAY); if (ret != ESP_OK) return EOS_ERR; - return size_out; + + for (i=0; i PCM_MIC_WM) return EOS_ERR; + + memset(buf, 0, PCM_SIZE_BUF); + for (i=0; i PCM_MIC_WM) return EOS_ERR; + + xSemaphoreTake(mutex, portMAX_DELAY); + buf = eos_bufq_pop(&pcm_buf_q); + xSemaphoreGive(mutex); + if (buf == NULL) return EOS_ERR_EMPTY; + + esize = eos_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, 0); + if (rv) eos_bufq_push(&pcm_buf_q, buf); + xSemaphoreGive(mutex); + + return rv; } -/* -void eos_pcm_call(void) { - const char *s = "ATD0631942317;\r"; +void eos_pcm_start(void) { + i2s_event_t evt; + evt.type = I2S_EVENT_MAX; /* my type */ + xQueueSend(i2s_queue, (void *)&evt, portMAX_DELAY); i2s_zero_dma_buffer(I2S_NUM_0); - eos_modem_write((void *)s, strlen(s)); - vTaskDelay(1000 / portTICK_RATE_MS); i2s_start(I2S_NUM_0); } -*/ + +void eos_pcm_stop(void) { + i2s_stop(I2S_NUM_0); +} diff --git a/code/esp32/components/eos/include/cell.h b/code/esp32/components/eos/include/cell.h index 61da67a..f3eb89d 100644 --- a/code/esp32/components/eos/include/cell.h +++ b/code/esp32/components/eos/include/cell.h @@ -6,13 +6,22 @@ #define EOS_CELL_MTYPE_DATA_START 2 #define EOS_CELL_MTYPE_DATA_STOP 3 -#define EOS_CELL_MTYPE_AUDIO_START 2 -#define EOS_CELL_MTYPE_AUDIO_STOP 3 +#define EOS_CELL_MTYPE_AUDIO_START 4 +#define EOS_CELL_MTYPE_AUDIO_STOP 5 + +#define EOS_CELL_UART_MODE_NONE 0 +#define EOS_CELL_UART_MODE_PPP 1 +#define EOS_CELL_UART_MODE_RELAY 2 void eos_pcm_init(void); -ssize_t eos_pcm_write(void *data, size_t size); -void eos_pcm_call(void); + +ssize_t eos_pcm_read(unsigned char *data, size_t size); +int eos_pcm_push(unsigned char *data, size_t size); +void eos_pcm_start(void); +void eos_pcm_stop(void); void eos_modem_init(void); ssize_t eos_modem_write(void *data, size_t size); void eos_modem_set_mode(char mode); + +void eos_cell_init(void); \ No newline at end of file diff --git a/code/esp32/components/eos/include/eos.h b/code/esp32/components/eos/include/eos.h index e9a67d4..97e1530 100644 --- a/code/esp32/components/eos/include/eos.h +++ b/code/esp32/components/eos/include/eos.h @@ -10,7 +10,7 @@ #define EOS_TASK_SSIZE_UART 4096 #define EOS_TASK_SSIZE_I2S 4096 -#define EOS_TASK_SSIZE_NET_XCHG 4096 +#define EOS_TASK_SSIZE_NET_XCHG 8192 #define EOS_TASK_SSIZE_UDP_RCVR 4096 diff --git a/code/esp32/components/eos/include/msgq.h b/code/esp32/components/eos/include/msgq.h index 9c9c757..f5d5a31 100644 --- a/code/esp32/components/eos/include/msgq.h +++ b/code/esp32/components/eos/include/msgq.h @@ -17,3 +17,14 @@ typedef struct EOSMsgQ { void eos_msgq_init(EOSMsgQ *msgq, EOSMsgItem *array, uint8_t size); int eos_msgq_push(EOSMsgQ *msgq, unsigned char type, unsigned char *buffer, uint16_t len, uint8_t flags); void eos_msgq_pop(EOSMsgQ *msgq, unsigned char *type, unsigned char **buffer, uint16_t *len, uint8_t *flags); + +typedef struct EOSBufQ { + uint8_t idx_r; + uint8_t idx_w; + uint8_t size; + unsigned char **array; +} EOSBufQ; + +void eos_bufq_init(EOSBufQ *bufq, unsigned char **array, uint8_t size); +int eos_bufq_push(EOSBufQ *bufq, unsigned char *buffer); +unsigned char *eos_bufq_pop(EOSBufQ *bufq); diff --git a/code/esp32/components/eos/include/net.h b/code/esp32/components/eos/include/net.h index abf2893..df1bd0d 100644 --- a/code/esp32/components/eos/include/net.h +++ b/code/esp32/components/eos/include/net.h @@ -23,5 +23,6 @@ typedef void (*eos_net_fptr_t) (unsigned char, unsigned char *, uint16_t); void eos_net_init(void); unsigned char *eos_net_alloc(void); +void eos_net_free(unsigned char *buf); int eos_net_send(unsigned char mtype, unsigned char *buffer, uint16_t len, uint8_t flags); void eos_net_set_handler(unsigned char mtype, eos_net_fptr_t handler); \ No newline at end of file diff --git a/code/esp32/components/eos/msgq.c b/code/esp32/components/eos/msgq.c index 30fb0ad..22430b4 100644 --- a/code/esp32/components/eos/msgq.c +++ b/code/esp32/components/eos/msgq.c @@ -3,19 +3,19 @@ #include "eos.h" #include "msgq.h" -#define EOS_MSGQ_IDX_MASK(IDX, SIZE) ((IDX) & ((SIZE) - 1)) +#define IDX_MASK(IDX, SIZE) ((IDX) & ((SIZE) - 1)) void eos_msgq_init(EOSMsgQ *msgq, EOSMsgItem *array, uint8_t size) { msgq->idx_r = 0; msgq->idx_w = 0; - msgq->array = array; msgq->size = size; + msgq->array = array; } int eos_msgq_push(EOSMsgQ *msgq, unsigned char type, unsigned char *buffer, uint16_t len, uint8_t flags) { if ((uint8_t)(msgq->idx_w - msgq->idx_r) == msgq->size) return EOS_ERR_FULL; - uint8_t idx = EOS_MSGQ_IDX_MASK(msgq->idx_w, msgq->size); + uint8_t idx = IDX_MASK(msgq->idx_w, msgq->size); msgq->array[idx].type = type; msgq->array[idx].buffer = buffer; msgq->array[idx].len = len; @@ -28,13 +28,34 @@ void eos_msgq_pop(EOSMsgQ *msgq, unsigned char *type, unsigned char **buffer, ui if (msgq->idx_r == msgq->idx_w) { *type = 0; *buffer = NULL; + *len = 0; + if (flags) *flags = 0; } else { - uint8_t idx = EOS_MSGQ_IDX_MASK(msgq->idx_r, msgq->size); + uint8_t idx = IDX_MASK(msgq->idx_r, msgq->size); *type = msgq->array[idx].type; *buffer = msgq->array[idx].buffer; *len = msgq->array[idx].len; - *flags = msgq->array[idx].flags; + if (flags) *flags = msgq->array[idx].flags; msgq->idx_r++; } } +void eos_bufq_init(EOSBufQ *bufq, unsigned char **array, uint8_t size) { + bufq->idx_r = 0; + bufq->idx_w = 0; + bufq->size = size; + bufq->array = array; +} + +int eos_bufq_push(EOSBufQ *bufq, unsigned char *buffer) { + if ((uint8_t)(bufq->idx_w - bufq->idx_r) == bufq->size) return EOS_ERR_FULL; + + bufq->array[IDX_MASK(bufq->idx_w++, bufq->size)] = buffer; + return EOS_OK; +} + +unsigned char *eos_bufq_pop(EOSBufQ *bufq) { + if (bufq->idx_r == bufq->idx_w) return NULL; + + return bufq->array[IDX_MASK(bufq->idx_r++, bufq->size)]; +} diff --git a/code/esp32/components/eos/net.c b/code/esp32/components/eos/net.c index be4d0f1..a372e3a 100644 --- a/code/esp32/components/eos/net.c +++ b/code/esp32/components/eos/net.c @@ -19,10 +19,6 @@ #include "msgq.h" #include "net.h" -#define MIN(X, Y) (((X) < (Y)) ? (X) : (Y)) -#define MAX(X, Y) (((X) > (Y)) ? (X) : (Y)) -#define NET_BUFQ_IDX_MASK(IDX) ((IDX) & (EOS_NET_SIZE_BUFQ - 1)) - #define SPI_GPIO_RTS 22 #define SPI_GPIO_CTS 21 #define SPI_GPIO_MOSI 23 @@ -30,13 +26,8 @@ #define SPI_GPIO_SCLK 18 #define SPI_GPIO_CS 5 -typedef struct EOSNetBufQ { - uint8_t idx_r; - uint8_t idx_w; - unsigned char *array[EOS_NET_SIZE_BUFQ]; -} EOSNetBufQ; - -static EOSNetBufQ net_buf_q; +static EOSBufQ net_buf_q; +static unsigned char *net_bufq_array[EOS_NET_SIZE_BUFQ]; static EOSMsgQ net_send_q; static EOSMsgItem net_sndq_array[EOS_NET_SIZE_SNDQ]; @@ -52,25 +43,6 @@ static void bad_handler(unsigned char mtype, unsigned char *buffer, uint16_t len ESP_LOGE(TAG, "NET RECV: bad handler: %d", mtype); } -static void net_bufq_init(void) { - int i; - - net_buf_q.idx_r = 0; - net_buf_q.idx_w = EOS_NET_SIZE_BUFQ; - for (i=0; i> 3)); + // ESP_LOGI(TAG, "RECV:%d", (buf_recv[0] >> 3)); repeat = 0; if (buf_recv[0] != 0) { mtype = (buf_recv[0] >> 3); @@ -184,8 +156,11 @@ void eos_net_init(void) { ret=spi_slave_initialize(HSPI_HOST, &buscfg, &slvcfg, 1); assert(ret==ESP_OK); - net_bufq_init(); 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