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:
parent
d112dfa476
commit
f9110f51c2
@ -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();
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user