summaryrefslogtreecommitdiff
path: root/code/esp32/components/eos/cell_pcm.c
blob: 961a3222a849fdf71435e6187ecb27311908735e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
#include <stdio.h>
#include <string.h>

#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#include <freertos/queue.h>
#include <driver/i2s.h>
#include <driver/gpio.h>
#include <esp_log.h>

#include "eos.h"
#include "net.h"
#include "cell.h"

static i2s_dev_t* I2S[I2S_NUM_MAX] = {&I2S0, &I2S1};

#define BUF_SIZE        2048

#define PCM_GPIO_BCK    33
#define PCM_GPIO_WS     4
#define PCM_GPIO_DIN    34
#define PCM_GPIO_DOUT   2

static QueueHandle_t i2s_queue;

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;

    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:
                    ESP_LOGE(TAG, "*** 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) {
    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     = PCM_GPIO_BCK,
        .ws_io_num      = PCM_GPIO_WS,
        .data_in_num    = PCM_GPIO_DIN,
        .data_out_num   = PCM_GPIO_DOUT
    };
    i2s_driver_install(I2S_NUM_0, &i2s_config, 10, &i2s_queue);   //install and start i2s driver
    i2s_stop(I2S_NUM_0);
    i2s_set_pin(I2S_NUM_0, &pin_config);
    gpio_matrix_in(pin_config.ws_io_num, I2S0I_WS_IN_IDX, 1);
    gpio_matrix_in(pin_config.bck_io_num, I2S0I_BCK_IN_IDX, 1);
    I2S[I2S_NUM_0]->conf.tx_mono = 1;
    I2S[I2S_NUM_0]->conf.rx_mono = 1;

    // Create a task to handle i2s event from ISR
    xTaskCreate(i2s_event_task, "i2s_event", EOS_TASK_SSIZE_I2S, NULL, EOS_TASK_PRIORITY_I2S, NULL);
    // xTaskCreate(i2s_write_task, "i2s_write_task", EOS_TASK_SSIZE_I2S, NULL, EOS_TASK_PRIORITY_I2S, NULL);
    ESP_LOGI(TAG, "INIT");
    i2s_start(I2S_NUM_0);
}

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);
}
*/