Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Audio aec dev #129

Merged
merged 16 commits into from
Jun 22, 2021
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion HAL/src/eoss3_hal_audio.c
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,9 @@ void post_first_pdm_dma_after_lpsd()
}
uint8_t *p_dest = (uint8_t *)o_hal_info.pdata_block_prev + offsetof(QAI_DataBlock_t, p_data);
voice_dmac_dst_set_addr0((int32_t)p_dest);
o_hal_info.pdata_block_prev->dbHeader.Tstart = xTaskGetTickCountFromISR();//g_seqNumber++;
//o_hal_info.pdata_block_prev->dbHeader.Tstart = xTaskGetTickCountFromISR();//g_seqNumber++;
//Note: This is not called by any ISR
o_hal_info.pdata_block_prev->dbHeader.Tstart = xTaskGetTickCount();

}
static void SetVoiceDmacConfig(bool fUsingLeftChannel, bool fUsingRightChannel, bool fUsingDualBuffers)
Expand Down
9 changes: 7 additions & 2 deletions Libraries/Audio/src/ql_audio.c
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ enum process_state LPSD_FSMAction(enum process_action pa, void* pv) {
case PACTION_START_ON:
if (LPSD_State == PSTATE_STOPPED) {
S3x_Clk_Enable(S3X_LPSD);
HAL_Audio_LPSD_Enable(true);
HAL_Audio_LPSD_Enable(true);
HAL_Audio_LPSD_Int(true);
}
LPSD_State = PSTATE_LPSD_ON;
Expand All @@ -183,7 +183,7 @@ enum process_state LPSD_FSMAction(enum process_action pa, void* pv) {
case PACTION_START_OFF:
if (LPSD_State == PSTATE_STOPPED) {
S3x_Clk_Enable(S3X_LPSD);
HAL_Audio_LPSD_Enable(true);
HAL_Audio_LPSD_Enable(true);
HAL_Audio_LPSD_Int(true);
}
LPSD_State = PSTATE_LPSD_OFF;
Expand Down Expand Up @@ -242,5 +242,10 @@ void QL_Audio_Voice_Stop(void)
HAL_Audio_Stop(&gPdmConnector, &Audio_Config_Local);
}

void QL_Audio_Voice_Start(void)
{
//S3x_Clk_Enable(S3X_LPSD);
HAL_Audio_Start(&gPdmConnector, 0, true, &Audio_Config_Local);
}


2 changes: 1 addition & 1 deletion Libraries/Power/src/s3x_clock.c
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ void s3x_clkd_update_all_src_div(UINT32_t rate, UINT32_t mode)
/* temp bumpup CPU to finish faster*/
if (S3clk[i].clkd_id == CLK_C10)
{
HAL_GPIO_Write(GPIO_1, 0);
//HAL_GPIO_Write(GPIO_1, 0);
div_reg = CRU_RVAL(0);
CRU_WVAL(0, 0);
}
Expand Down
12 changes: 9 additions & 3 deletions Libraries/Power/src/s3x_dfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ int S3x_Set_Policy(uint8_t policy, uint32_t src, uint32_t* pcruval)
S3x_Policy_Node dfs_policy = dfs_node[policy];
max = SIZEOF_ARRAY(dfs_policy.clk_domain);
for(i = 0; i < max ; i++){
if (i == 1) HAL_GPIO_Write(GPIO_1, 0);
//if (i == 1) HAL_GPIO_Write(GPIO_1, 0);
clkd = S3x_Id_To_Domain(dfs_policy.clk_domain[clkd_index[i]]);
ret = s3x_update_clk_rate(clkd, dfs_policy.rate[clkd_index[i]], src, pcruval);
//TIM 24 if (pcruval) CRU_WVAL(0x000, *pcruval); //TIM 24
Expand Down Expand Up @@ -317,7 +317,7 @@ uint32_t DFS_FreqCPUSleep(void) {
void DFS_SwitchToSleepPolicy(void)
{
uint32_t cruReg0x000SleepVal;

policyBeforeSleep = policyCurrent;
policyDuringSleep = (dfs_node[policyCurrent].policySleep == 0xFF) ? policyCurrent : dfs_node[policyCurrent].policySleep;

Expand All @@ -336,7 +336,7 @@ void DFS_SwitchToSleepPolicy(void)
//S3x_Reduce_Hsosc(policyMaxrate, acruval2, &icruval2);
S3x_Reduce_Hsosc(policyMaxrate);
}
HAL_GPIO_Write(GPIO_1, 1);
//HAL_GPIO_Write(GPIO_1, 1);
}

void DFS_RestoreFromSleep(void)
Expand Down Expand Up @@ -452,3 +452,9 @@ void s3x_disable_dfs(void) {
s3x_dfs_enable = DFS_DIS;
}

void print_dfs_policies(void)
{
printf("DFS:%d,%d,%d:", policyCurrent, policyBeforeSleep, policyDuringSleep);
//printf(":%d,%d::", policyMaxrate, dfs_min_policy);
printf(":%d::", s3x_dfs_enable);
}
62 changes: 55 additions & 7 deletions Tasks/I2S/src/ql_i2sTxTask.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,11 @@
//Single DMA Buffer size is directly related to the number of I2S interrupts
//Intention is to minimize the number of interrupts to as low as possible
//The minimum #interrupts (=66) are for 15ms DataBlock, with mono channel at 16K rate
#if (FEATURE_I2S_MASTER_DATA == 1)
#define I2S_MIN_DATA_BLOCK_BYTES (15*48*2) //in bytes 15ms mono, 16bit @48K sample buffer
#else
#define I2S_MIN_DATA_BLOCK_BYTES (15*16*2) //in bytes 15ms mono @16K sample buffer
#endif

//This will be size of one DMA buffer needed to keep 66 interrupts per second
//Note: DMA size must be multple of words
Expand Down Expand Up @@ -294,17 +298,17 @@ static int fill_i2s_DMA_buf_mono_16K(int buf_index, int offset, QAI_DataBlock_t
static int fill_i2s_DMA_buf(int buf_index, int offset, QAI_DataBlock_t *pIn)
{
int filled;
#if I2S_INTP_FACTOR == 3
#if (I2S_INTP_FACTOR == 3)

#if I2S_CHANNEL_COUNT == 2
#if (I2S_CHANNEL_COUNT == 2)
filled = fill_i2s_DMA_buf_stereo_48K(buf_index, offset, pIn);
#else
filled = fill_i2s_DMA_buf_mono_48K(buf_index, offset, pIn);
#endif //I2S_CHANNEL_COUNT

#else //16K channels

#if I2S_CHANNEL_COUNT == 2
#if (I2S_CHANNEL_COUNT == 2)
filled = fill_i2s_DMA_buf_stereo_16K(buf_index, offset, pIn);
#else
filled = fill_i2s_DMA_buf_mono_16K(buf_index, offset, pIn);
Expand All @@ -313,6 +317,29 @@ static int fill_i2s_DMA_buf(int buf_index, int offset, QAI_DataBlock_t *pIn)
#endif // I2S_INTP_FACTOR
return filled;
}
#if (FEATURE_I2S_MASTER_DATA == 1)
/* The left and right channels are copied interleaved for DMA
* Note: The loop uses the Stereo element count in the Data Block
*/
static int fill_i2s_DMA_buf_stereo_48K_32bit(uint8_t buf_index, int offset, QAI_DataBlock_t *pIn, int datablock_count)
{
int16_t *left = (int16_t *)&pIn->p_data; //interleaved left and right samples

int16_t *stereo = (int16_t *)&i2sDMABuffers[I2S_SINGLE_DMA_SIZE*buf_index + (offset/4)];
for(int i =0; i < pIn->dbHeader.numDataElements; i++)
{
*stereo++ = (int32_t)*left++; //first left
*stereo++ = (int32_t)*left++;
}

int bytes_copied = pIn->dbHeader.numDataElements*4;//4 since explicitly copying 2 16bit samples
configASSERT(bytes_copied == (I2S_SINGLE_DMA_SIZE * sizeof(uint32_t)/datablock_count));

return pIn->dbHeader.numDataElements*pIn->dbHeader.dataElementSize;
}
#endif


/* set the ISR for I2S transmit mode
* Need to handle 4 cases for stereo or mono, 16K or 48K I2S bus rate
*/
Expand Down Expand Up @@ -340,15 +367,19 @@ static void setup_i2s_tx(void)

#endif

#if (FEATURE_I2S_MASTER_DATA == 1)
p_i2s_cfg.i2s_wd_clk = 32;
#endif

/* setup the config and register ISR callback */
ret_val = HAL_I2S_Init(I2S_SLAVE_ASSP_TX, &p_i2s_cfg, I2S_SDMA_callback);
printf("ret_val=%x, HAL_SUCCESS=%x\n", ret_val, HAL_I2S_SUCCESS);
configASSERT(ret_val == HAL_I2S_SUCCESS)


#if ENABLE_I2S_48K_TRANSMIT == 1
#if (ENABLE_I2S_48K_TRANSMIT == 1)
int output_blk_size = 0;
#if ENABLE_I2S_STEREO_TRANSMIT == 1
#if (ENABLE_I2S_STEREO_TRANSMIT == 1)
//init stereo interpolator from 16K to 48K
output_blk_size = init_interpolate_by_3_stereo();

Expand Down Expand Up @@ -450,6 +481,13 @@ void i2sTaskHandler(void *pParameter)
BaseType_t qret;
QAI_DataBlock_t *pIn;
int queue_count;
int datablock_count;

#if (FEATURE_I2S_MASTER_DATA == 1)
datablock_count = 3*I2S_CHANNEL_COUNT; //since 48K = 3*16Khz
#else
datablock_count = I2S_CHANNEL_COUNT; //since 16Khz
#endif

init_i2s_buffers();
setup_i2s_tx();
Expand All @@ -474,7 +512,7 @@ void i2sTaskHandler(void *pParameter)
/* check how many data blocks are waiting in the Queue */
queue_count = uxQueueMessagesWaiting(I2SDataQ);
/* need 1 or 2 Data Blocks to create one DMA buffer */
if(queue_count < I2S_CHANNEL_COUNT)
if(queue_count < datablock_count)
{
vTaskDelay(3);//it may take upto 7.5ms for next datablock
continue;
Expand Down Expand Up @@ -506,20 +544,30 @@ void i2sTaskHandler(void *pParameter)
continue;
}
int offset = 0;
for(int i= 0;i < I2S_CHANNEL_COUNT; i++)
for(int i= 0;i < datablock_count; i++)
{
/* get a data blk from queue first */
qret = xQueueReceive(I2SDataQ, &pIn, 0);
configASSERT(qret == pdTRUE);

#if (FEATURE_I2S_MASTER_DATA == 1)
/* fill partial/full DMA buffer at 48KHz, 32bit samples*/
offset += fill_i2s_DMA_buf_stereo_48K_32bit(i2s_buf_wr_index, offset, pIn, datablock_count);
#else
/* fill partial/full DMA buffer */
offset += fill_i2s_DMA_buf(i2s_buf_wr_index, offset, pIn);
#endif

/* if in the queue, the usecount must greater than 0 */
if(pIn->dbHeader.numUseCount > 0)
datablk_mgr_release_generic(pIn);
}

#if (FEATURE_I2S_MASTER_DATA == 1)
extern int fill_i2s_queue(void);
fill_i2s_queue();
#endif

/* set state to filled */
set_i2s_buf_state(i2s_buf_wr_index++);
if(i2s_buf_wr_index >= I2S_DMA_BUFFER_COUNT)
Expand Down
4 changes: 3 additions & 1 deletion freertos_gateware/inc/eoss3_hal_fpga_FLL.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,16 @@ typedef struct
/* Note : These are added for Debug purposes only. Code should not depend on
* them, since they may be removed any time
*/
#if 0
__IO uint32_t WORD_COUNT_DIFF; /* 0x0C = difference between local and master word counts */
__IO uint32_t LSB_WORD_COUNTS; /* 0x10 = LSB bits of {Local[15:0]:Master[15:0]} word counts */
__IO uint32_t LOCAL_WORD_COUNT; /* 0x14 = Continuos count of Local Clks divided byt 64 = Local Word Count*/
__IO uint32_t MASTER_WORD_COUNT; /* 0x18 = Continuos count of Master Clks divided byt 64 = Master Word Count*/
__IO uint32_t MASTER_SAMPLE_COUNT; /* 0x1C = Master sample count at the given instance */

#endif
} FPGA_FLL_TypeDef;


#define FB_FLL_BASE (FPGA_PERIPH_BASE+0x1000)
#define FB_FLL ((FPGA_FLL_TypeDef *)FB_FLL_BASE)

Expand Down
65 changes: 65 additions & 0 deletions freertos_gateware/inc/eoss3_hal_fpga_decimation_fir.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*==========================================================
* Copyright 2021 QuickLogic Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*==========================================================*/

/*==========================================================
*
* File : eoss3_hal_fpga_decimation_fir.h
* Purpose: This file contains FIR functions for Rx data in fpga.
*
*=========================================================*/
#include "Fw_global_config.h"


#ifndef __EOSS3_HAL_FB_DECIMATION_FIR_H_
#define __EOSS3_HAL_FB_DECIMATION_FIR_H_

#include "eoss3_dev.h"

#define FB_DECIMATION_FIR_REG_OFFSET (FPGA_PERIPH_BASE + 0x4000 + 0x1000)
#define FB_DECIMATION_FIR_SDMA_BASE (FPGA_PERIPH_BASE + 0x4000)
#define FB_FIR_SDMA ((FIR_SDMA_TypeDef *) FB_DECIMATION_FIR_SDMA_BASE)

typedef struct
{
__IO uint32_t FIR_IER; /*0x00 I2S Enable Register */
__IO uint32_t FIR_ACSLIPR; /*0x04 ACSLIP Reset (deprecated)*/
__IO uint32_t FIR_ISR; /*0x08 Interrupt Status Register */
__IO uint32_t FIR_IEN; /*0x0C Interrupt Enable Register */
__IO uint32_t FIR_DFSTS; /*0x10 Decimation FIFO Status Register */
__IO uint32_t FIR_DFDREG; /*0x14 Decimation Data Register */
__IO uint32_t FIR_ACSLIP; /*0x18 ACSLIP Register (deprecated) */
__IO uint32_t FIR_DFRST; /*0x1C Decimation FIFO Reset Register */
__IO uint32_t FIR_DER; /*0x20 DMA Enable Register */
__IO uint32_t FIR_DSR; /*0x24 DMA Status Register */
__IO uint32_t FIR_DCNT; /*0x28 DMA Count Register */
__IO uint32_t FIR_ACSLTMR; /*0x2C ACSLIP Timer (deprecated) */
__IO uint32_t FIR_FDCR; /*0x30 FIR Decimation Control Register */
__IO uint32_t FIR_FDSR; /*0x34 FIR Decimation Status Register */

__IO uint32_t FIR_RSRVD1; /*0x38 Reserved 1 */
__IO uint32_t FIR_RSRVD2; /*0x3c Reserved 2 */
__IO uint32_t FIR_FIFO; /*0x40 FIR FIFO Status Register */

} FIR_SDMA_TypeDef;

extern void HAL_FIR_Decimation_FB_SDMA_Config(void);

extern uint8_t is_fir_fb_slave_dma_done_intr_set(void);
extern void fir_fb_slave_rx_dma_done_clear(void);
extern void fir_fb_slave_rx_dma_en(void);
extern void HAL_FIR_Decimation_Stop (void);

#endif //__EOSS3_HAL_FB_DECIMATION_FIR_H_
64 changes: 64 additions & 0 deletions freertos_gateware/inc/eoss3_hal_fpga_i2s_slave.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/*==========================================================
* Copyright 2021 QuickLogic Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*==========================================================*/

/*==========================================================
*
* File : eoss3_hal_fpga_i2s_slave.h
* Purpose: This file contains API declaration for I2S Slave
* Rx implemented in fpga.
*
*=========================================================*/
#include "Fw_global_config.h"


#ifndef __EOSS3_HAL_FB_I2S_SLAVE_H_
#define __EOSS3_HAL_FB_I2S_SLAVE_H_

#include "eoss3_dev.h"

#define FB_I2S_SDMA_BASE (FPGA_PERIPH_BASE + 0x2000)
#define FB_I2S_REG_OFFSET (FPGA_PERIPH_BASE + 0x2000 + 0x1000)
#define FB_I2S_SDMA ((I2S_SDMA_TypeDef *) FB_I2S_REG_OFFSET)

typedef struct
{
__IO uint32_t I2S_IER; /*0x00 I2S Enable Register */
__IO uint32_t I2S_ACSLIPR; /*0x04 ACSLIP Reset (deprecated)*/
__IO uint32_t I2S_ISR; /*0x08 Interrupt Status Register */
__IO uint32_t I2S_IEN; /*0x0C Interrupt Enable Register */
__IO uint32_t I2S_DFSTS; /*0x10 Decimation FIFO Status Register */
__IO uint32_t I2S_DFDREG; /*0x14 Decimation Data Register */
#if 0
__IO uint32_t I2S_ACSLIP; /*0x18 ACSLIP Register (deprecated) */
__IO uint32_t I2S_DFRST; /*0x1C Decimation FIFO Reset Register */
__IO uint32_t I2S_DER; /*0x20 DMA Enable Register */
__IO uint32_t I2S_DSR; /*0x24 DMA Status Register */
__IO uint32_t I2S_DCNT; /*0x28 DMA Count Register */
__IO uint32_t I2S_ACSLTMR; /*0x2C ACSLIP Timer (deprecated) */
__IO uint32_t I2S_FDCR; /*0x30 FIR Decimation Control Register */
__IO uint32_t I2S_FDSR; /*0x34 FIR Decimation Status Register */
#endif
} I2S_SDMA_TypeDef;


extern void eoss3_hal_fabric_i2s_slave_clks_disable();
extern void eoss3_hal_fabric_i2s_slave_clks_enable();

extern void HAL_FB_I2SRx_Ref_input_DmaStart(void);
extern void HAL_FB_I2SRx_Ref_input_DmaNext(void);


#endif //__EOSS3_HAL_FB_I2S_SLAVE_H_
Loading