summaryrefslogtreecommitdiff
path: root/code/esp32/components/eos/pcm.c
diff options
context:
space:
mode:
Diffstat (limited to 'code/esp32/components/eos/pcm.c')
-rw-r--r--code/esp32/components/eos/pcm.c135
1 files changed, 135 insertions, 0 deletions
diff --git a/code/esp32/components/eos/pcm.c b/code/esp32/components/eos/pcm.c
new file mode 100644
index 0000000..10f7914
--- /dev/null
+++ b/code/esp32/components/eos/pcm.c
@@ -0,0 +1,135 @@
+#include <stdio.h>
+#include <string.h>
+
+#include <freertos/FreeRTOS.h>
+#include <freertos/task.h>
+#include <freertos/queue.h>
+#include <driver/i2s.h>
+#include <esp_log.h>
+
+#include "eos.h"
+#include "modem.h"
+#include "fe310.h"
+
+static i2s_dev_t* I2S[I2S_NUM_MAX] = {&I2S0, &I2S1};
+
+#define BUF_SIZE 2048
+
+static QueueHandle_t i2s_queue;
+
+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;
+
+ while (1) {
+ // Waiting for I2S event.
+ if (xQueueReceive(i2s_queue, (void * )&event, (portTickType)portMAX_DELAY)) {
+ 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);
+ }
+
+ }
+ i2s_write(I2S_NUM_0, (const void *)data, BUF_SIZE, &size_out, 1000 / portTICK_RATE_MS);
+ break;
+ case I2S_EVENT_DMA_ERROR:
+ printf("*** I2S DMA ERROR ***");
+ 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);
+
+ int i;
+ for (i=0; i<BUF_SIZE; i+=16) {
+ data[i+3] = 0xaa;
+ data[i+2] = 0xff;
+ }
+ while(1) {
+ size_t size_out;
+ // i2s_read(I2S_NUM_0, (void *)data, BUF_SIZE, &size_out, 1000 / portTICK_RATE_MS);
+ // printf("!! I2S DATA IN: %d\n", size_out);
+ i2s_write(I2S_NUM_0, (const void *)data, BUF_SIZE, &size_out, 1000 / portTICK_RATE_MS);
+ printf("I2S DATA OUT: %d\n", size_out);
+ }
+ free(data);
+ vTaskDelete(NULL);
+}
+
+void eos_pcm_init(void) {
+ esp_err_t err;
+
+ i2s_config_t i2s_config = {
+ .mode = I2S_MODE_SLAVE | I2S_MODE_TX | I2S_MODE_RX,
+ .sample_rate = 32000,
+ .bits_per_sample = 32,
+ .channel_format = I2S_CHANNEL_FMT_ONLY_LEFT,
+ .communication_format = I2S_COMM_FORMAT_PCM | I2S_COMM_FORMAT_PCM_LONG,
+ .dma_buf_count = 4,
+ .dma_buf_len = 512,
+ .use_apll = true,
+ .fixed_mclk = 2048000 * 8,
+ .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1
+ };
+
+ i2s_pin_config_t pin_config = {
+ .bck_io_num = 33,
+ .ws_io_num = 4,
+ .data_out_num = 2,
+ .data_in_num = 34
+ };
+ err = i2s_driver_install(I2S_NUM_0, &i2s_config, 10, &i2s_queue); //install and start i2s driver
+ printf("I2S ERR: %d\n", err);
+ err = i2s_set_pin(I2S_NUM_0, &pin_config);
+ printf("I2S ERR: %d\n", err);
+ i2s_stop(I2S_NUM_0);
+ I2S[I2S_NUM_0]->conf.tx_mono = 1;
+ I2S[I2S_NUM_0]->conf.rx_mono = 1;
+ i2s_start(I2S_NUM_0);
+
+ // Create a task to handle i2s event from ISR
+ xTaskCreate(i2s_event_task, "i2s_event_task", 2048, NULL, EOS_PRIORITY_PCM, NULL);
+ // xTaskCreate(i2s_write_task, "i2s_write_task", 2048, NULL, EOS_PRIORITY_PCM, NULL);
+}
+
+ssize_t eos_pcm_write(void *data, size_t size) {
+ size_t size_out;
+
+ esp_err_t ret = i2s_write(I2S_NUM_0, (const void *)data, size, &size_out, portMAX_DELAY);
+ if (ret != ESP_OK) return EOS_ERR;
+ return size_out;
+}
+
+void eos_pcm_call(void) {
+ const char *s = "ATD0631942317;\r";
+
+ i2s_zero_dma_buffer(I2S_NUM_0);
+ eos_modem_write((void *)s, strlen(s));
+ vTaskDelay(1000 / portTICK_RATE_MS);
+ i2s_start(I2S_NUM_0);
+}
+