Skip to content

Commit 0039dbc

Browse files
Move to 16bps per channel like xmit, clean up
Some I2S configuration and DMA tweaks makes 16 bits per sample per channel work, giving a basically identical interface as xmit. The received data values now span the full range of +/-32767 as well.
1 parent bc743d0 commit 0039dbc

File tree

3 files changed

+10
-38
lines changed

3 files changed

+10
-38
lines changed

cores/esp8266/core_esp8266_i2s.c

+7-21
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,6 @@ typedef struct i2s_state {
7070
static i2s_state_t *rx = NULL;
7171
static i2s_state_t *tx = NULL;
7272

73-
volatile uint32_t rx_irqs = 0;
74-
volatile uint32_t tx_irqs = 0;
75-
7673
// IOs used for I2S. Not defined in i2s.h, unfortunately.
7774
// Note these are internal IOs numbers and not pins on an
7875
// Arduino board. Users need to verify their particular wiring.
@@ -159,7 +156,6 @@ void ICACHE_RAM_ATTR i2s_slc_isr(void) {
159156
uint32_t slc_intr_status = SLCIS;
160157
SLCIC = 0xFFFFFFFF;
161158
if (slc_intr_status & SLCIRXEOF) {
162-
tx_irqs++;
163159
slc_queue_item_t *finished_item = (slc_queue_item_t *)SLCRXEDA;
164160
// Zero the buffer so it is mute in case of underflow
165161
ets_memset((void *)finished_item->buf_ptr, 0x00, SLC_BUF_LEN * 4);
@@ -173,7 +169,6 @@ void ICACHE_RAM_ATTR i2s_slc_isr(void) {
173169
}
174170
}
175171
if (slc_intr_status & SLCITXEOF) {
176-
rx_irqs++;
177172
slc_queue_item_t *finished_item = (slc_queue_item_t *)SLCTXEDA;
178173
// Set owner back to 1 (SW) or else RX stops. TX has no such restriction.
179174
finished_item->owner = 1;
@@ -210,16 +205,6 @@ static void _alloc_channel(i2s_state_t *ch) {
210205
}
211206
}
212207

213-
#if 0
214-
void dumprx()
215-
{
216-
for (int i=0; i<SLC_BUF_CNT; i++) {
217-
printf("%d: %d %d %d %d %d %d %p %p\n", i, 0, rx->slc_items[i].owner, rx->slc_items[i].eof, rx->slc_items[i].sub_sof, rx->slc_items[i].datalen, rx->slc_items[i].blocksize,
218-
rx->slc_items[i].buf_ptr, rx->slc_items[i].next_link_ptr);
219-
}
220-
}
221-
#endif
222-
223208
static void i2s_slc_begin() {
224209
if (tx) {
225210
_alloc_channel(tx);
@@ -327,7 +312,7 @@ bool i2s_write_lr(int16_t left, int16_t right){
327312
return i2s_write_sample(sample);
328313
}
329314

330-
bool i2s_read_sample(uint32_t *left, uint32_t *right, bool blocking) {
315+
bool i2s_read_sample(int16_t *left, int16_t *right, bool blocking) {
331316
if (rx->curr_slc_buf_pos==SLC_BUF_LEN || rx->curr_slc_buf==NULL) {
332317
if (rx->slc_queue_len == 0) {
333318
if (!blocking) return false;
@@ -345,8 +330,9 @@ bool i2s_read_sample(uint32_t *left, uint32_t *right, bool blocking) {
345330
rx->curr_slc_buf_pos=0;
346331
}
347332

348-
*left = rx->curr_slc_buf[rx->curr_slc_buf_pos++];
349-
*right = rx->curr_slc_buf[rx->curr_slc_buf_pos++];
333+
uint32_t sample = rx->curr_slc_buf[rx->curr_slc_buf_pos++];
334+
*left = sample & 0xffff;
335+
*right = sample >> 16;
350336

351337
return true;
352338
}
@@ -381,7 +367,7 @@ void i2s_set_dividers(uint8_t div1, uint8_t div2) {
381367
div1 &= I2SBDM;
382368
div2 &= I2SCDM;
383369

384-
// !trans master(?), !recv master(?), !bits mod(==16 bits/chanel), clear clock dividers
370+
// trans master(active low), recv master(active_low), !bits mod(==16 bits/chanel), clear clock dividers
385371
I2SC &= ~(I2STSM | I2SRSM | (I2SBMM << I2SBM) | (I2SBDM << I2SBD) | (I2SCDM << I2SCD));
386372

387373
// I2SRF = Send/recv right channel first (? may be swapped form I2S spec of WS=0 => left)
@@ -438,17 +424,17 @@ void i2s_rxtx_begin(bool enableRx, bool enableTx) {
438424

439425
// I2STXFMM, I2SRXFMM=0 => 16-bit, dual channel data shifted in/out
440426
I2SFC &= ~(I2SDE | (I2STXFMM << I2STXFM) | (I2SRXFMM << I2SRXFM)); // Set RX/TX FIFO_MOD=0 and disable DMA (FIFO only)
441-
I2SFC |= I2SDE | (rx ? 2/*24bpc, 2ch*/<<I2SRXFM : 0); // Enable DMA, set RX format 24(32bits), 2 channels
427+
I2SFC |= I2SDE; // Enable DMA
442428

443429
// I2STXCMM, I2SRXCMM=0 => Dual channel mode
444430
I2SCC &= ~((I2STXCMM << I2STXCM) | (I2SRXCMM << I2SRXCM)); // Set RX/TX CHAN_MOD=0
445431

446432
i2s_set_rate(44100);
447433

448434
if (rx) {
435+
// Need to prime the # of samples to receive in the engine
449436
I2SRXEN = SLC_BUF_LEN;
450437
}
451-
// I2SC |= (15<<I2SBM);
452438

453439
I2SC |= (rx?I2SRXS:0) | (tx?I2STXS:0); // Start transmission/reception
454440
}

cores/esp8266/i2s.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ float i2s_get_real_rate();//The actual Sample Rate on output
4949
bool i2s_write_sample(uint32_t sample);//32bit sample with channels being upper and lower 16 bits (blocking when DMA is full)
5050
bool i2s_write_sample_nb(uint32_t sample);//same as above but does not block when DMA is full and returns false instead
5151
bool i2s_write_lr(int16_t left, int16_t right);//combines both channels and calls i2s_write_sample with the result
52-
bool i2s_read_sample(uint32_t *left, uint32_t *right, bool blocking); // RX data, 2x32 bits, left-aligned
52+
bool i2s_read_sample(int16_t *left, int16_t *right, bool blocking); // RX data, 2x32 bits, left-aligned
5353
bool i2s_is_full();//returns true if DMA is full and can not take more bytes (overflow)
5454
bool i2s_is_empty();//returns true if DMA is empty (underflow)
5555
bool i2s_rx_is_full();

libraries/esp8266/examples/I2SInput/I2SInput.ino

+2-16
Original file line numberDiff line numberDiff line change
@@ -30,35 +30,21 @@
3030
#include <ESP8266WiFi.h>
3131
#include <i2s.h>
3232

33-
void dump() {
34-
Serial.printf("I2SC: %08x\n", I2SC);
35-
Serial.printf("I2SFC: %08x\n", I2SFC);
36-
Serial.printf("I2SCC: %08x\n", I2SCC);
37-
Serial.printf("I2SRXEN: %08x\n", I2SRXEN);
38-
Serial.printf("SLCC0: %08x\n", SLCC0);
39-
Serial.printf("SLCRXDC: %08x\n", SLCRXDC);
40-
Serial.printf("SLCTXL: %08x\n", SLCTXL);
41-
Serial.printf("SLCIE: %08x\n", SLCIE);
42-
}
43-
4433
void setup() {
4534
Serial.begin(115200);
4635
WiFi.forceSleepBegin();
4736
delay(500);
4837

4938
i2s_rxtx_begin(true, false); // Enable I2S RX
5039
i2s_set_rate(11025);
51-
dump();
5240

5341
delay(1000);
5442

5543
while (1) {
56-
uint32_t l, r;
44+
int16_t l, r;
5745
i2s_read_sample(&l, &r, true);
58-
int16_t lh = l >> 16;
59-
int16_t rh = r >> 16;
6046
char withScale[256];
61-
sprintf(withScale, "%d %d", lh, rh);
47+
sprintf(withScale, "%d %d", l, r);
6248
Serial.println(withScale);
6349
yield();
6450
}

0 commit comments

Comments
 (0)