1
0
mirror of https://github.com/esp8266/Arduino.git synced 2025-04-19 23:22:16 +03:00

Add I2S callback on DMA read (#4205)

Add optional callback after every DMA buffer interrupt for lower delay, better timing control of I2S output.
This commit is contained in:
Kristijan Gjoshev 2018-03-19 17:25:34 +01:00 committed by Earle F. Philhower, III
parent d112dfa476
commit f9110f51c2
2 changed files with 7 additions and 1 deletions

View File

@ -56,6 +56,7 @@ static uint32_t *i2s_slc_buf_pntr[SLC_BUF_CNT]; //Pointer to the I2S DMA buffer
static struct slc_queue_item i2s_slc_items[SLC_BUF_CNT]; //I2S DMA buffer descriptors 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 uint32_t *i2s_curr_slc_buf=NULL;//current buffer for writing
static int i2s_curr_slc_buf_pos=0; //position in the current buffer static int i2s_curr_slc_buf_pos=0; //position in the current buffer
static void (*i2s_callback) (void)=0; //Callback function should be defined as 'void ICACHE_FLASH_ATTR function_name()', placing the function in IRAM for faster execution. Avoid long computational tasks in this function, use it to set flags and process later.
bool ICACHE_FLASH_ATTR i2s_is_full(){ 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); return (i2s_curr_slc_buf_pos==SLC_BUF_LEN || i2s_curr_slc_buf==NULL) && (i2s_slc_queue_len == 0);
@ -92,10 +93,15 @@ void ICACHE_FLASH_ATTR i2s_slc_isr(void) {
i2s_slc_queue_next_item(); //free space for finished_item i2s_slc_queue_next_item(); //free space for finished_item
} }
i2s_slc_queue[i2s_slc_queue_len++] = finished_item->buf_ptr; i2s_slc_queue[i2s_slc_queue_len++] = finished_item->buf_ptr;
if (i2s_callback) i2s_callback();
ETS_SLC_INTR_ENABLE(); ETS_SLC_INTR_ENABLE();
} }
} }
void i2s_set_callback(void (*callback) (void)){
i2s_callback = callback;
}
void ICACHE_FLASH_ATTR i2s_slc_begin(){ void ICACHE_FLASH_ATTR i2s_slc_begin(){
i2s_slc_queue_len = 0; i2s_slc_queue_len = 0;
int x, y; int x, y;
@ -248,7 +254,6 @@ float ICACHE_FLASH_ATTR i2s_get_real_rate(){
return (float)I2SBASEFREQ/32/((I2SC>>I2SBD) & I2SBDM)/((I2SC >> I2SCD) & I2SCDM); return (float)I2SBASEFREQ/32/((I2SC>>I2SBD) & I2SBDM)/((I2SC >> I2SCD) & I2SCDM);
} }
void ICACHE_FLASH_ATTR i2s_begin(){ void ICACHE_FLASH_ATTR i2s_begin(){
_i2s_sample_rate = 0; _i2s_sample_rate = 0;
i2s_slc_begin(); i2s_slc_begin();

View File

@ -51,6 +51,7 @@ bool i2s_write_lr(int16_t left, int16_t right);//combines both channels and call
bool i2s_is_full();//returns true if DMA is full and can not take more bytes (overflow) 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) bool i2s_is_empty();//returns true if DMA is empty (underflow)
int16_t i2s_available();// returns the number of samples than can be written before blocking int16_t i2s_available();// returns the number of samples than can be written before blocking
void i2s_set_callback(void (*callback) (void));
#ifdef __cplusplus #ifdef __cplusplus
} }