Skip to content

Commit 8b9f237

Browse files
committed
Merge branch 'feature/i2s_add_expand_function' into 'master'
add a new i2s feature to expand the original i2s width See merge request idf/esp-idf!1617
2 parents e84df7a + f48ecb8 commit 8b9f237

File tree

2 files changed

+153
-45
lines changed

2 files changed

+153
-45
lines changed

components/driver/i2s.c

100644100755
Lines changed: 87 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ static const char* I2S_TAG = "I2S";
4242
ESP_LOGE(I2S_TAG,"%s:%d (%s):%s", __FILE__, __LINE__, __FUNCTION__, str); \
4343
return (ret); \
4444
}
45+
#define I2S_MAX_BUFFER_SIZE (4 * 1024 * 1024) //the maximum RAM can be allocated
4546
#define I2S_BASE_CLK (2*APB_CLK_FREQ)
4647
#define I2S_ENTER_CRITICAL_ISR() portENTER_CRITICAL_ISR(&i2s_spinlock[i2s_num])
4748
#define I2S_EXIT_CRITICAL_ISR() portEXIT_CRITICAL_ISR(&i2s_spinlock[i2s_num])
@@ -234,7 +235,7 @@ static esp_err_t i2s_apll_calculate_fi2s(int rate, int bits_per_sample, int *sdm
234235
float avg;
235236
float min_rate, max_rate, min_diff;
236237
if (rate/bits_per_sample/2/8 < APLL_I2S_MIN_RATE) {
237-
return ESP_FAIL;
238+
return ESP_ERR_INVALID_ARG;
238239
}
239240

240241
*sdm0 = 0;
@@ -309,7 +310,7 @@ esp_err_t i2s_set_clk(i2s_port_t i2s_num, uint32_t rate, i2s_bits_per_sample_t b
309310

310311
if (clkmdiv > 256) {
311312
ESP_LOGE(I2S_TAG, "clkmdiv is too large\r\n");
312-
return ESP_FAIL;
313+
return ESP_ERR_INVALID_ARG;
313314
}
314315

315316
// wait all on-going writing finish
@@ -365,7 +366,7 @@ esp_err_t i2s_set_clk(i2s_port_t i2s_num, uint32_t rate, i2s_bits_per_sample_t b
365366
if (p_i2s_obj[i2s_num]->tx == NULL) {
366367
ESP_LOGE(I2S_TAG, "Failed to create tx dma buffer");
367368
i2s_driver_uninstall(i2s_num);
368-
return ESP_FAIL;
369+
return ESP_ERR_NO_MEM;
369370
}
370371
I2S[i2s_num]->out_link.addr = (uint32_t) p_i2s_obj[i2s_num]->tx->desc[0];
371372

@@ -383,7 +384,7 @@ esp_err_t i2s_set_clk(i2s_port_t i2s_num, uint32_t rate, i2s_bits_per_sample_t b
383384
if (p_i2s_obj[i2s_num]->rx == NULL){
384385
ESP_LOGE(I2S_TAG, "Failed to create rx dma buffer");
385386
i2s_driver_uninstall(i2s_num);
386-
return ESP_FAIL;
387+
return ESP_ERR_NO_MEM;
387388
}
388389
I2S[i2s_num]->rx_eof_num = (p_i2s_obj[i2s_num]->dma_buf_len * p_i2s_obj[i2s_num]->channel_num * p_i2s_obj[i2s_num]->bytes_per_sample)/4;
389390
I2S[i2s_num]->in_link.addr = (uint32_t) p_i2s_obj[i2s_num]->rx->desc[0];
@@ -627,6 +628,7 @@ static i2s_dma_t *i2s_create_dma_queue(i2s_port_t i2s_num, int dma_buf_count, in
627628

628629
esp_err_t i2s_start(i2s_port_t i2s_num)
629630
{
631+
I2S_CHECK((i2s_num < I2S_NUM_MAX), "i2s_num error", ESP_ERR_INVALID_ARG);
630632
//start DMA link
631633
I2S_ENTER_CRITICAL();
632634
i2s_reset_fifo(i2s_num);
@@ -660,6 +662,7 @@ esp_err_t i2s_start(i2s_port_t i2s_num)
660662

661663
esp_err_t i2s_stop(i2s_port_t i2s_num)
662664
{
665+
I2S_CHECK((i2s_num < I2S_NUM_MAX), "i2s_num error", ESP_ERR_INVALID_ARG);
663666
I2S_ENTER_CRITICAL();
664667
esp_intr_disable(p_i2s_obj[i2s_num]->i2s_isr_handle);
665668
if (p_i2s_obj[i2s_num]->mode & I2S_MODE_TX) {
@@ -674,7 +677,7 @@ esp_err_t i2s_stop(i2s_port_t i2s_num)
674677
}
675678
I2S[i2s_num]->int_clr.val = I2S[i2s_num]->int_st.val; //clear pending interrupt
676679
I2S_EXIT_CRITICAL();
677-
return 0;
680+
return ESP_OK;
678681
}
679682

680683
esp_err_t i2s_set_dac_mode(i2s_dac_mode_t dac_mode)
@@ -996,6 +999,11 @@ esp_err_t i2s_zero_dma_buffer(i2s_port_t i2s_num)
996999
}
9971000
}
9981001
if (p_i2s_obj[i2s_num]->tx && p_i2s_obj[i2s_num]->tx->buf != NULL && p_i2s_obj[i2s_num]->tx->buf_size != 0) {
1002+
int bytes_left = (p_i2s_obj[i2s_num]->tx->buf_size - p_i2s_obj[i2s_num]->tx->rw_pos) % 4;
1003+
if (bytes_left) {
1004+
int zero_bytes = 0;
1005+
i2s_write_bytes(i2s_num, (const char *)&zero_bytes, bytes_left, portMAX_DELAY);
1006+
}
9991007
for (int i = 0; i < p_i2s_obj[i2s_num]->dma_buf_count; i++) {
10001008
memset(p_i2s_obj[i2s_num]->tx->buf[i], 0, p_i2s_obj[i2s_num]->tx->buf_size);
10011009
}
@@ -1014,7 +1022,7 @@ esp_err_t i2s_driver_install(i2s_port_t i2s_num, const i2s_config_t *i2s_config,
10141022
p_i2s_obj[i2s_num] = (i2s_obj_t*) malloc(sizeof(i2s_obj_t));
10151023
if (p_i2s_obj[i2s_num] == NULL) {
10161024
ESP_LOGE(I2S_TAG, "Malloc I2S driver error");
1017-
return ESP_FAIL;
1025+
return ESP_ERR_NO_MEM;
10181026
}
10191027
memset(p_i2s_obj[i2s_num], 0, sizeof(i2s_obj_t));
10201028

@@ -1062,15 +1070,15 @@ esp_err_t i2s_driver_install(i2s_port_t i2s_num, const i2s_config_t *i2s_config,
10621070
return i2s_set_clk(i2s_num, i2s_config->sample_rate, i2s_config->bits_per_sample, p_i2s_obj[i2s_num]->channel_num);
10631071
}
10641072

1065-
ESP_LOGE(I2S_TAG, "I2S driver already installed");
1066-
return ESP_ERR_INVALID_STATE;
1073+
ESP_LOGW(I2S_TAG, "I2S driver already installed");
1074+
return ESP_OK;
10671075
}
10681076

10691077
esp_err_t i2s_driver_uninstall(i2s_port_t i2s_num)
10701078
{
10711079
I2S_CHECK((i2s_num < I2S_NUM_MAX), "i2s_num error", ESP_ERR_INVALID_ARG);
10721080
if (p_i2s_obj[i2s_num] == NULL) {
1073-
ESP_LOGI(I2S_TAG, "ALREADY NULL");
1081+
ESP_LOGI(I2S_TAG, "already uninstalled");
10741082
return ESP_OK;
10751083
}
10761084
i2s_stop(i2s_num);
@@ -1109,10 +1117,9 @@ int i2s_write_bytes(i2s_port_t i2s_num, const char *src, size_t size, TickType_t
11091117
{
11101118
char *data_ptr;
11111119
int bytes_can_write, bytes_writen = 0;
1112-
I2S_CHECK((i2s_num < I2S_NUM_MAX), "i2s_num error", ESP_ERR_INVALID_ARG);
1113-
if (p_i2s_obj[i2s_num]->tx == NULL) {
1114-
return 0;
1115-
}
1120+
I2S_CHECK((i2s_num < I2S_NUM_MAX), "i2s_num error", ESP_FAIL);
1121+
I2S_CHECK((size < I2S_MAX_BUFFER_SIZE), "size is too large", ESP_FAIL);
1122+
I2S_CHECK((p_i2s_obj[i2s_num]->tx), "tx NULL", ESP_FAIL);
11161123
xSemaphoreTake(p_i2s_obj[i2s_num]->tx->mux, (portTickType)portMAX_DELAY);
11171124
while (size > 0) {
11181125
if (p_i2s_obj[i2s_num]->tx->rw_pos == p_i2s_obj[i2s_num]->tx->buf_size || p_i2s_obj[i2s_num]->tx->curr_ptr == NULL) {
@@ -1159,14 +1166,72 @@ esp_err_t i2s_adc_disable(i2s_port_t i2s_num)
11591166
return ESP_OK;
11601167
}
11611168

1169+
int i2s_write_expand(i2s_port_t i2s_num, const char *src, int size, int src_bits, int aim_bits, TickType_t ticks_to_wait)
1170+
{
1171+
char *data_ptr;
1172+
int bytes_can_write, bytes_writen = 0, tail;
1173+
I2S_CHECK((i2s_num < I2S_NUM_MAX), "i2s_num error", ESP_FAIL);
1174+
I2S_CHECK((size > 0), "size must greater than zero", ESP_FAIL);
1175+
I2S_CHECK((aim_bits * size < I2S_MAX_BUFFER_SIZE), "size is too large", ESP_FAIL);
1176+
I2S_CHECK((aim_bits >= src_bits), "aim_bits musn't less than src_bits", ESP_FAIL);
1177+
I2S_CHECK((p_i2s_obj[i2s_num]->tx), "tx NULL", ESP_FAIL);
1178+
if (src_bits < I2S_BITS_PER_SAMPLE_8BIT || aim_bits < I2S_BITS_PER_SAMPLE_8BIT) {
1179+
ESP_LOGE(I2S_TAG,"bits musn't be less than 8, src_bits %d aim_bits %d", src_bits, aim_bits);
1180+
return ESP_FAIL;
1181+
}
1182+
if (src_bits > I2S_BITS_PER_SAMPLE_32BIT || aim_bits > I2S_BITS_PER_SAMPLE_32BIT) {
1183+
ESP_LOGE(I2S_TAG,"bits musn't be greater than 32, src_bits %d aim_bits %d", src_bits, aim_bits);
1184+
return ESP_FAIL;
1185+
}
1186+
if ((src_bits == I2S_BITS_PER_SAMPLE_16BIT || src_bits == I2S_BITS_PER_SAMPLE_32BIT) && (size % 2 != 0)) {
1187+
ESP_LOGE(I2S_TAG,"size must be a even number while src_bits is even, src_bits %d size %d", src_bits, size);
1188+
return ESP_FAIL;
1189+
}
1190+
if (src_bits == I2S_BITS_PER_SAMPLE_24BIT && (size % 3 != 0)) {
1191+
ESP_LOGE(I2S_TAG,"size must be a multiple of 3 while src_bits is 24, size %d", size);
1192+
return ESP_FAIL;
1193+
}
1194+
int src_bytes = src_bits / 8, aim_bytes = aim_bits / 8;
1195+
int zero_bytes = aim_bytes - src_bytes;
1196+
xSemaphoreTake(p_i2s_obj[i2s_num]->tx->mux, (portTickType)portMAX_DELAY);
1197+
size = size * aim_bytes / src_bytes;
1198+
ESP_LOGD(I2S_TAG,"aim_bytes %d src_bytes %d size %d", aim_bytes, src_bytes, size);
1199+
while (size > 0) {
1200+
if (p_i2s_obj[i2s_num]->tx->rw_pos == p_i2s_obj[i2s_num]->tx->buf_size || p_i2s_obj[i2s_num]->tx->curr_ptr == NULL) {
1201+
if (xQueueReceive(p_i2s_obj[i2s_num]->tx->queue, &p_i2s_obj[i2s_num]->tx->curr_ptr, ticks_to_wait) == pdFALSE) {
1202+
break;
1203+
}
1204+
p_i2s_obj[i2s_num]->tx->rw_pos = 0;
1205+
}
1206+
data_ptr = (char*)p_i2s_obj[i2s_num]->tx->curr_ptr;
1207+
data_ptr += p_i2s_obj[i2s_num]->tx->rw_pos;
1208+
bytes_can_write = p_i2s_obj[i2s_num]->tx->buf_size - p_i2s_obj[i2s_num]->tx->rw_pos;
1209+
if (bytes_can_write > size) {
1210+
bytes_can_write = size;
1211+
}
1212+
tail = bytes_can_write % aim_bytes;
1213+
bytes_can_write = bytes_can_write - tail;
1214+
1215+
memset(data_ptr, 0, bytes_can_write);
1216+
for (int j = 0; j < bytes_can_write; j += (aim_bytes - zero_bytes)) {
1217+
j += zero_bytes;
1218+
memcpy(&data_ptr[j], &src[bytes_writen], aim_bytes - zero_bytes);
1219+
bytes_writen += (aim_bytes - zero_bytes);
1220+
}
1221+
size -= bytes_can_write;
1222+
p_i2s_obj[i2s_num]->tx->rw_pos += bytes_can_write;
1223+
}
1224+
xSemaphoreGive(p_i2s_obj[i2s_num]->tx->mux);
1225+
return bytes_writen;
1226+
}
1227+
11621228
int i2s_read_bytes(i2s_port_t i2s_num, char* dest, size_t size, TickType_t ticks_to_wait)
11631229
{
11641230
char *data_ptr;
11651231
int bytes_can_read, byte_read = 0;
1166-
I2S_CHECK((i2s_num < I2S_NUM_MAX), "i2s_num error", ESP_ERR_INVALID_ARG);
1167-
if (p_i2s_obj[i2s_num]->rx == NULL) {
1168-
return 0;
1169-
}
1232+
I2S_CHECK((i2s_num < I2S_NUM_MAX), "i2s_num error", ESP_FAIL);
1233+
I2S_CHECK((size < I2S_MAX_BUFFER_SIZE), "size is too large", ESP_FAIL);
1234+
I2S_CHECK((p_i2s_obj[i2s_num]->rx), "rx NULL", ESP_FAIL);
11701235
xSemaphoreTake(p_i2s_obj[i2s_num]->rx->mux, (portTickType)portMAX_DELAY);
11711236
while (size > 0) {
11721237
if (p_i2s_obj[i2s_num]->rx->rw_pos == p_i2s_obj[i2s_num]->rx->buf_size || p_i2s_obj[i2s_num]->rx->curr_ptr == NULL) {
@@ -1190,14 +1255,15 @@ int i2s_read_bytes(i2s_port_t i2s_num, char* dest, size_t size, TickType_t ticks
11901255
xSemaphoreGive(p_i2s_obj[i2s_num]->rx->mux);
11911256
return byte_read;
11921257
}
1258+
11931259
int i2s_push_sample(i2s_port_t i2s_num, const char *sample, TickType_t ticks_to_wait)
11941260
{
11951261
int i, bytes_to_push = 0;
11961262
char *data_ptr;
1197-
I2S_CHECK((i2s_num < I2S_NUM_MAX), "i2s_num error", ESP_ERR_INVALID_ARG);
1263+
I2S_CHECK((i2s_num < I2S_NUM_MAX), "i2s_num error", ESP_FAIL);
11981264
if (p_i2s_obj[i2s_num]->tx->rw_pos == p_i2s_obj[i2s_num]->tx->buf_size || p_i2s_obj[i2s_num]->tx->curr_ptr == NULL) {
11991265
if (xQueueReceive(p_i2s_obj[i2s_num]->tx->queue, &p_i2s_obj[i2s_num]->tx->curr_ptr, ticks_to_wait) == pdFALSE) {
1200-
return 0;
1266+
return bytes_to_push;
12011267
}
12021268
ESP_LOGD(I2S_TAG, "rw_pos: %d, buf_size: %d, curr_ptr: %d", p_i2s_obj[i2s_num]->tx->rw_pos, p_i2s_obj[i2s_num]->tx->buf_size, (int)p_i2s_obj[i2s_num]->tx->curr_ptr);
12031269
p_i2s_obj[i2s_num]->tx->rw_pos = 0;
@@ -1216,10 +1282,10 @@ int i2s_pop_sample(i2s_port_t i2s_num, char *sample, TickType_t ticks_to_wait)
12161282
{
12171283
int i, bytes_to_pop = 0;
12181284
char *data_ptr;
1219-
I2S_CHECK((i2s_num < I2S_NUM_MAX), "i2s_num error", ESP_ERR_INVALID_ARG);
1285+
I2S_CHECK((i2s_num < I2S_NUM_MAX), "i2s_num error", ESP_FAIL);
12201286
if (p_i2s_obj[i2s_num]->rx->rw_pos == p_i2s_obj[i2s_num]->rx->buf_size || p_i2s_obj[i2s_num]->rx->curr_ptr == NULL) {
12211287
if (xQueueReceive(p_i2s_obj[i2s_num]->rx->queue, &p_i2s_obj[i2s_num]->rx->curr_ptr, ticks_to_wait) == pdFALSE) {
1222-
return 0;
1288+
return bytes_to_pop;
12231289
}
12241290
p_i2s_obj[i2s_num]->rx->rw_pos = 0;
12251291
}

0 commit comments

Comments
 (0)