Skip to content

Commit

Permalink
Merge pull request #939 from me-no-dev/esp8266
Browse files Browse the repository at this point in the history
I2S Optimizations
  • Loading branch information
igrr committed Oct 29, 2015
2 parents 2f474f0 + bd5b5d3 commit 342c4ae
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 6 deletions.
28 changes: 25 additions & 3 deletions cores/esp8266/core_esp8266_i2s.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,16 @@ static uint32_t i2s_slc_queue[SLC_BUF_CNT-1];
static uint8_t i2s_slc_queue_len;
static uint32_t *i2s_slc_buf_pntr[SLC_BUF_CNT]; //Pointer to the I2S DMA buffer data
static struct slc_queue_item i2s_slc_items[SLC_BUF_CNT]; //I2S DMA buffer descriptors
static uint32_t *i2s_curr_slc_buf=NULL;//current buffer for writing
static int i2s_curr_slc_buf_pos=0; //position in the current buffer

bool ICACHE_FLASH_ATTR i2s_is_full(){
return (i2s_curr_slc_buf_pos==SLC_BUF_LEN || i2s_curr_slc_buf==NULL) && (i2s_slc_queue_len == 0);
}

bool ICACHE_FLASH_ATTR i2s_is_empty(){
return (i2s_slc_queue_len >= SLC_BUF_CNT-1);
}

uint32_t ICACHE_FLASH_ATTR i2s_slc_queue_next_item(){ //pop the top off the queue
uint8_t i;
Expand All @@ -73,7 +83,7 @@ void ICACHE_FLASH_ATTR i2s_slc_isr(void) {
if (slc_intr_status & SLCIRXEOF) {
ETS_SLC_INTR_DISABLE();
struct slc_queue_item *finished_item = (struct slc_queue_item*)SLCRXEDA;

memset((void *)finished_item->buf_ptr, 0x00, SLC_BUF_LEN * 4);//zero the buffer so it is mute in case of underflow
if (i2s_slc_queue_len >= SLC_BUF_CNT-1) { //All buffers are empty. This means we have an underflow
i2s_slc_queue_next_item(); //free space for finished_item
}
Expand Down Expand Up @@ -142,8 +152,6 @@ void ICACHE_FLASH_ATTR i2s_slc_end(){
//at least the current sample rate. You can also call it quicker: it will suspend the calling
//thread if the buffer is full and resume when there's room again.

static uint32_t *i2s_curr_slc_buf=NULL;
static int i2s_curr_slc_buf_pos=0;
bool ICACHE_FLASH_ATTR i2s_write_sample(uint32_t sample) {
if (i2s_curr_slc_buf_pos==SLC_BUF_LEN || i2s_curr_slc_buf==NULL) {
if(i2s_slc_queue_len == 0){
Expand All @@ -165,6 +173,20 @@ bool ICACHE_FLASH_ATTR i2s_write_sample(uint32_t sample) {
return true;
}

bool ICACHE_FLASH_ATTR i2s_write_sample_nb(uint32_t sample) {
if (i2s_curr_slc_buf_pos==SLC_BUF_LEN || i2s_curr_slc_buf==NULL) {
if(i2s_slc_queue_len == 0){
return false;
}
ETS_SLC_INTR_DISABLE();
i2s_curr_slc_buf = (uint32_t *)i2s_slc_queue_next_item();
ETS_SLC_INTR_ENABLE();
i2s_curr_slc_buf_pos=0;
}
i2s_curr_slc_buf[i2s_curr_slc_buf_pos++]=sample;
return true;
}

bool ICACHE_FLASH_ATTR i2s_write_lr(int16_t left, int16_t right){
int sample = right & 0xFFFF;
sample = sample << 16;
Expand Down
9 changes: 6 additions & 3 deletions cores/esp8266/i2s.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,12 @@ extern "C" {

void i2s_begin();
void i2s_end();
void i2s_set_rate(uint32_t rate);
bool i2s_write_sample(uint32_t sample);
bool i2s_write_lr(int16_t left, int16_t right);
void i2s_set_rate(uint32_t rate);//Sample Rate in Hz (ex 44100, 48000)
bool i2s_write_sample(uint32_t sample);//32bit sample with channels being upper and lower 16 bits (blocking when DMA is full)
bool i2s_write_sample_nb(uint32_t sample);//same as above but does not block when DMA is full and returns false instead
bool i2s_write_lr(int16_t left, int16_t right);//combines both channels and calls i2s_write_sample with the result
bool i2s_is_full();//returns true if DMA is full and can not take more bytes (overflow)
bool i2s_is_empty();//returns true if DMA is empty (underflow)

#ifdef __cplusplus
}
Expand Down

0 comments on commit 342c4ae

Please sign in to comment.