Code: Select all
#define TAG "mic"
#define SAMPLE_RATE 8000
#define TP_MESH_SEND_ADDR "FFBF"
/*
* dma_buffer_size = dma_frame_num * slot_num * slot_bit_width / 8
* the `dma_frame_num` should be the multiple of `3` when the data bit width is 24.
* the `channel_num` should be 1 when the slot mode is mono
*/
#define I2S_BUFFER_SIZE 400
#define AT_CMD_BUFFER_SIZE (I2S_BUFFER_SIZE * 2 + 32)
uint8_t i2s_rx_buffer[I2S_BUFFER_SIZE] = {0};
char at_cmd_line[AT_CMD_BUFFER_SIZE] = {0};
void app_main(void) {
gpio_config_t io_conf = {
.pin_bit_mask = GPIO_NUM_18,
.mode = GPIO_MODE_OUTPUT,
.pull_up_en = GPIO_PULLUP_DISABLE,
.pull_down_en = GPIO_PULLDOWN_DISABLE,
.intr_type = GPIO_INTR_DISABLE,
};
gpio_config(&io_conf);
gpio_set_level(GPIO_NUM_18, 1);
ESP_LOGI(TAG, "GPIO configured");
i2s_chan_handle_t i2s_rx_handle;
i2s_chan_config_t i2s_rx_chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_1, I2S_ROLE_MASTER);
i2s_new_channel(&i2s_rx_chan_cfg, NULL, &i2s_rx_handle);
i2s_std_config_t i2s_rx_std_cfg = {
.clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(SAMPLE_RATE),
.slot_cfg = I2S_STD_PHILIPS_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_32BIT, I2S_SLOT_MODE_MONO),
.gpio_cfg = {
.mclk = I2S_GPIO_UNUSED,
.bclk = GPIO_NUM_5,
.ws = GPIO_NUM_4,
.dout = I2S_GPIO_UNUSED,
.din = GPIO_NUM_6,
.invert_flags = {
.mclk_inv = false,
.bclk_inv = false,
.ws_inv = false,
},
},
};
/* It is very important that the slot_mask needs to be configured according to the hardware design, otherwise the
* microphone cannot correctly obtain complete data. */
i2s_rx_std_cfg.slot_cfg.slot_mask = I2S_STD_SLOT_LEFT;
i2s_channel_init_std_mode(i2s_rx_handle, &i2s_rx_std_cfg);
i2s_channel_enable(i2s_rx_handle);
ESP_LOGI(TAG, "I2S configured");
uart_config_t uart_config = {
.baud_rate = 460800,
.data_bits = UART_DATA_8_BITS,
.parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
};
// Configure UART parameters
ESP_ERROR_CHECK(uart_param_config(UART_NUM_1, &uart_config));
ESP_ERROR_CHECK(uart_set_pin(UART_NUM_1, GPIO_NUM_17, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE));
ESP_ERROR_CHECK(uart_driver_install(UART_NUM_1, AT_CMD_BUFFER_SIZE, AT_CMD_BUFFER_SIZE * 5, 0, NULL, 0));
ESP_LOGI(TAG, "UART configured");
esp_err_t ret = ESP_OK;
vTaskDelay(pdMS_TO_TICKS(5000));
ESP_LOGI(TAG, "Start");
while (1) {
size_t bytes_read = 0;
ret = i2s_channel_read(i2s_rx_handle, i2s_rx_buffer, I2S_BUFFER_SIZE, &bytes_read, 100);
if (ret == ESP_OK) {
if (bytes_read > 0) {
ESP_LOGI(TAG, "I2S read %d bytes", bytes_read);
// for (size_t i = 0; i < bytes_read; i++) {
// printf("%d\n", i2s_rx_buffer[i]);
// }
// printf("\n");
// AT+SEND=<ADDR>,<LEN>,<DATA>,<TYPE>\r\n
int at_cmd_line_len = snprintf(at_cmd_line, sizeof(at_cmd_line), "AT+SEND=%s,%u,", TP_MESH_SEND_ADDR, (unsigned int)bytes_read);
char *uart_send_offset = at_cmd_line + at_cmd_line_len;
for (size_t i = 0; i < bytes_read; i++) {
uart_send_offset += sprintf(uart_send_offset, "%02X", i2s_rx_buffer[i]);
}
uart_send_offset += snprintf(uart_send_offset, AT_CMD_BUFFER_SIZE - (uart_send_offset - at_cmd_line), ",0\r\n");
at_cmd_line_len = uart_send_offset - at_cmd_line;
int byte_write = uart_write_bytes(UART_NUM_1, at_cmd_line, at_cmd_line_len);
if (byte_write != at_cmd_line_len) {
ESP_LOGW(TAG, "UART write only wrote %d of %d bytes", byte_write, at_cmd_line_len);
} else {
ESP_LOGI(TAG, "Sent successfully, wrote %d bytes", byte_write);
}
}
} else {
ESP_LOGE(TAG, "I2S read failed");
}
}
}
接收部分:
Code: Select all
#define TAG "speaker"
#define TAG_TPMESH "TPMESH"
#define SAMPLE_RATE 8000
#define TP_MESH_ADDR "FFBE"
/*
* dma_buffer_size = dma_frame_num * slot_num * slot_bit_width / 8
* the `dma_frame_num` should be the multiple of `3` when the data bit width is 24.
* the `channel_num` should be 1 when the slot mode is mono
*/
#define I2S_BUFFER_SIZE 400
#define AT_CMD_BUFFER_SIZE (I2S_BUFFER_SIZE * 2 + 32)
uint8_t i2s_tx_buffer[I2S_BUFFER_SIZE] = {0};
char at_cmd_line[AT_CMD_BUFFER_SIZE] = {0};
void app_main(void) {
/*
* dma_buffer_size = dma_frame_num * slot_num * slot_bit_width / 8.
* the `dma_frame_num` should be the multiple of `3` when the data bit width is 24, set by i2s_chan_config_t.
* the `channel_num` should be 1 when the slot mode is mono, set by i2s_std_config_t.
*/
i2s_chan_handle_t tx_handle;
i2s_chan_config_t tx_chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_0, I2S_ROLE_MASTER);
i2s_new_channel(&tx_chan_cfg, &tx_handle, NULL);
i2s_std_config_t tx_std_cfg = {
.clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(SAMPLE_RATE),
.slot_cfg = I2S_STD_PHILIPS_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_32BIT, I2S_SLOT_MODE_MONO),
.gpio_cfg = {
.mclk = I2S_GPIO_UNUSED,
.bclk = GPIO_NUM_15,
.ws = GPIO_NUM_16,
.dout = GPIO_NUM_7,
.din = I2S_GPIO_UNUSED,
.invert_flags = {
.mclk_inv = false,
.bclk_inv = false,
.ws_inv = false,
},
},
};
/* It is very important that the slot_mask needs to be configured according to the hardware design, otherwise the
* microphone cannot correctly obtain complete data. */
tx_std_cfg.slot_cfg.slot_mask = I2S_STD_SLOT_LEFT;
i2s_channel_init_std_mode(tx_handle, &tx_std_cfg);
i2s_channel_enable(tx_handle);
ESP_LOGI(TAG, "I2S configured");
uart_config_t uart_config = {
.baud_rate = 460800,
.data_bits = UART_DATA_8_BITS,
.parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
};
// Configure UART parameters
uart_param_config(UART_NUM_1, &uart_config);
uart_set_pin(UART_NUM_1, UART_PIN_NO_CHANGE, GPIO_NUM_18, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
uart_driver_install(UART_NUM_1, AT_CMD_BUFFER_SIZE, 0, 0, NULL, 0);
// xTaskCreate(uart_event_task, "uart_event_task", 4 * 1024, NULL, 12, NULL);
ESP_LOGI(TAG, "UART configured");
vTaskDelay(pdMS_TO_TICKS(5000));
ESP_LOGI(TAG, "Start");
while (1) {
int uart_read_len = 0;
uart_read_len = uart_read_bytes(UART_NUM_1, at_cmd_line, sizeof(at_cmd_line), pdMS_TO_TICKS(100));
if (uart_read_len > 0) {
ESP_LOGI(TAG, "UART read length: %d", uart_read_len);
printf("UART read data: %s\n", at_cmd_line);
if (strncmp(at_cmd_line, "AT+SEND=", 8) == 0) {
char dest[6], len[6], data[800];
char *param_start = at_cmd_line + sizeof("AT+SEND=") - 1;
if (sscanf(param_start, "%5[^,],%5[^,],%s", dest, len, data) == 3) {
size_t data_len = strlen(data);
uint8_t hex_data[400] = {0};
size_t hex_data_len = 0;
// Convert hex string to byte array
for (size_t i = 0; i < data_len; i += 2) {
if (i + 1 < data_len) {
char byte_str[3] = {data[i], data[i + 1], '\0'};
hex_data[hex_data_len++] = (uint8_t)strtol(byte_str, NULL, 16);
}
}
printf("Hex Data Array: ");
for (size_t i = 0; i < hex_data_len; i++) {
printf("0x%02X ", hex_data[i]);
}
printf("\n");
esp_err_t ret = i2s_channel_write(tx_handle, hex_data, hex_data_len, NULL, 100);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "I2S write failed");
}
} else {
ESP_LOGW(TAG_TPMESH, "Invalid format");
}
} else {
ESP_LOGW(TAG_TPMESH, "Invalid AT command");
}
}
}
}