1324 lines
27 KiB
C
Executable File
1324 lines
27 KiB
C
Executable File
/****************************************************************************
|
|
*
|
|
* Copyright(c) 2019 by Aerospace C.Power (Chongqing) Microelectronics. ALL RIGHTS RESERVED.
|
|
*
|
|
* This Information is proprietary to Aerospace C.Power (Chongqing) Microelectronics and MAY NOT
|
|
* be copied by any method or incorporated into another program without
|
|
* the express written consent of Aerospace C.Power. This Information or any portion
|
|
* thereof remains the property of Aerospace C.Power. The Information contained herein
|
|
* is believed to be accurate and Aerospace C.Power assumes no responsibility or
|
|
* liability for its use in any way and conveys no license or title under
|
|
* any patent or copyright and makes no representation or warranty that this
|
|
* Information is free from patent or copyright infringement.
|
|
*
|
|
* ****************************************************************************/
|
|
#include "os_types.h"
|
|
#include "i2s.h"
|
|
#include "iot_errno.h"
|
|
#if 0
|
|
#include "i2s_reg.h"
|
|
#include "apb_glb_reg.h"
|
|
#include "hw_reg_api.h"
|
|
#include "gpio_mtx_reg.h"
|
|
#include "pin_rf.h"
|
|
#include "apb.h"
|
|
#include "gpio_mtx.h"
|
|
#include "apb_dma.h"
|
|
#include "chip_reg_base.h"
|
|
#include "ap_clk_core_rf.h"
|
|
#include "sadc.h"
|
|
#include "iot_io.h"
|
|
#include "clk.h"
|
|
|
|
#define REG_BIT(o) ( 1<<(o) )
|
|
#define I2S_REG(reg) (*(volatile int*)(I2S0_BASEADDR + (reg)))
|
|
#define I2S_BIT_SET(reg, bit) (I2S_REG(reg)|= REG_BIT(bit))
|
|
#define I2S_BIT_GET(reg, bit) ( (I2S_REG(reg) & REG_BIT(bit)) ? 1 : 0 )
|
|
#define I2S_BIT_CLR(reg, bit) ( I2S_REG(reg) &= (~ REG_BIT(bit)))
|
|
|
|
int i2s_clk_div(unsigned char port, uint32_t div)
|
|
{
|
|
uint32_t tmp;
|
|
unsigned int offset = port * 0x1000;
|
|
|
|
if(port == 4)
|
|
offset += 0xD000;
|
|
|
|
tmp = I2S0_READ_REG(CFG_I2SCONF_ADDR + offset);
|
|
REG_FIELD_SET(REG_BCK_DIV_NUM, tmp, div);
|
|
I2S0_WRITE_REG(CFG_I2SCONF_ADDR + offset, tmp);
|
|
return OK;
|
|
}
|
|
|
|
void i2s_clk_cfg(uint8_t port, uint32_t freq)
|
|
{
|
|
/* pll 300MHZ: freq = 300M * div_n/div_m * 1/i2s_div,
|
|
set default value: div_m = 0x249F, i2s_div = 2, sclk = 32 * lrck */
|
|
if (freq == 48000)
|
|
{
|
|
clk_i2s_dev_set(0, 125, 16);
|
|
i2s_clk_div(port, 25);
|
|
}
|
|
else if (freq == 16000)
|
|
{
|
|
clk_i2s_dev_set(0, 0x249f, 0x80);
|
|
i2s_clk_div(port, 8);
|
|
}
|
|
else
|
|
{
|
|
/* 9375*255*125 = 0x11cfc15d*/
|
|
//uint32_t div_m = 0;
|
|
//div_m = 0x11cfc15d/freq;
|
|
//clk_i2s_dev_set(0, div_m, 255);
|
|
i2s_clk_div(port, 48);
|
|
}
|
|
}
|
|
|
|
uint8_t i2s_bit_mode_set(unsigned char port, uint8_t bm)
|
|
{
|
|
I2S_CHECK(bm == I2S_BITS_16BIT || bm == I2S_BITS_24BIT);
|
|
|
|
uint32_t tmp;
|
|
unsigned int offset = port * 0x1000;
|
|
|
|
if(port == 4)
|
|
offset += 0xD000;
|
|
|
|
tmp = I2S0_READ_REG(CFG_I2SCONF_ADDR + offset);
|
|
REG_FIELD_SET(REG_BITS_MOD, tmp, bm);
|
|
I2S0_WRITE_REG(CFG_I2SCONF_ADDR + offset, tmp);
|
|
|
|
return ERR_OK;
|
|
}
|
|
|
|
int i2s_tx_msb_shift_set(unsigned char port, unsigned char en)
|
|
{
|
|
unsigned int offset = port * 0x1000;
|
|
|
|
if(port == 4)
|
|
offset += 0xD000;
|
|
|
|
if(en)
|
|
{
|
|
I2S_BIT_SET(CFG_I2SCONF_ADDR + offset,REG_TRANS_MSB_SHIFT_OFFSET);
|
|
}
|
|
else
|
|
{
|
|
I2S_BIT_CLR(CFG_I2SCONF_ADDR + offset,REG_TRANS_MSB_SHIFT_OFFSET);
|
|
}
|
|
return OK;
|
|
}
|
|
|
|
int i2s_rx_msb_shift_set(unsigned char port, unsigned char en)
|
|
{
|
|
unsigned int offset = port * 0x1000;
|
|
|
|
if(port == 4)
|
|
offset += 0xD000;
|
|
|
|
if(en)
|
|
{
|
|
I2S_BIT_SET(CFG_I2SCONF_ADDR + offset,REG_RECE_MSB_SHIFT_OFFSET);
|
|
}
|
|
else
|
|
{
|
|
I2S_BIT_CLR(CFG_I2SCONF_ADDR + offset,REG_RECE_MSB_SHIFT_OFFSET);
|
|
}
|
|
return OK;
|
|
}
|
|
|
|
|
|
int i2s_tx_start(unsigned char port)
|
|
{
|
|
unsigned int offset = port * 0x1000;
|
|
|
|
if(port == 4)
|
|
offset += 0xD000;
|
|
|
|
I2S_BIT_SET(CFG_I2SCONF_ADDR + offset, I2S_TX_START_OFFSET);
|
|
return OK;
|
|
}
|
|
|
|
int i2s_tx_stop(unsigned char port)
|
|
{
|
|
unsigned int offset = port * 0x1000;
|
|
|
|
if(port == 4)
|
|
offset += 0xD000;
|
|
|
|
I2S_BIT_CLR(CFG_I2SCONF_ADDR + offset, I2S_TX_START_OFFSET);
|
|
return OK;
|
|
}
|
|
|
|
int i2s_rx_start(unsigned char port)
|
|
{
|
|
unsigned int offset = port * 0x1000;
|
|
|
|
if(port == 4)
|
|
offset += 0xD000;
|
|
|
|
I2S_BIT_SET(CFG_I2SCONF_ADDR + offset, I2S_RX_START_OFFSET);
|
|
return OK;
|
|
}
|
|
|
|
int i2s_rx_stop(unsigned char port)
|
|
{
|
|
unsigned int offset = port * 0x1000;
|
|
|
|
if(port == 4)
|
|
offset += 0xD000;
|
|
|
|
I2S_BIT_CLR(CFG_I2SCONF_ADDR + offset, I2S_RX_START_OFFSET);
|
|
return OK;
|
|
}
|
|
|
|
|
|
int i2s_msb_right(unsigned char port, unsigned char en)
|
|
{
|
|
unsigned int offset = port * 0x1000;
|
|
|
|
if(port == 4)
|
|
offset += 0xD000;
|
|
|
|
if(en)
|
|
{
|
|
I2S_BIT_SET(CFG_I2SCONF_ADDR + offset,REG_MSB_RIGHT_OFFSET);
|
|
}
|
|
else
|
|
{
|
|
I2S_BIT_CLR(CFG_I2SCONF_ADDR + offset,REG_MSB_RIGHT_OFFSET);
|
|
}
|
|
return OK;
|
|
}
|
|
|
|
int i2s_right_first(unsigned char port, unsigned char en)
|
|
{
|
|
unsigned int offset = port * 0x1000;
|
|
|
|
if(port == 4)
|
|
offset += 0xD000;
|
|
|
|
if(en)
|
|
{
|
|
I2S_BIT_SET(CFG_I2SCONF_ADDR + offset,REG_RIGHT_FIRST_OFFSET);
|
|
}
|
|
else
|
|
{
|
|
I2S_BIT_CLR(CFG_I2SCONF_ADDR + offset,REG_RIGHT_FIRST_OFFSET);
|
|
}
|
|
|
|
return OK;
|
|
}
|
|
|
|
int i2s_transive_mode(unsigned char port, unsigned char dir,unsigned char mode)
|
|
{
|
|
unsigned int offset = port * 0x1000;
|
|
|
|
if(port == 4)
|
|
offset += 0xD000;
|
|
|
|
if(dir)
|
|
{
|
|
if(mode)
|
|
{
|
|
I2S_BIT_SET(CFG_I2SCONF_ADDR + offset, REG_TRANS_SLAVE_MOD_OFFSET);
|
|
}
|
|
else
|
|
{
|
|
I2S_BIT_CLR(CFG_I2SCONF_ADDR + offset, REG_TRANS_SLAVE_MOD_OFFSET);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if(mode)
|
|
{
|
|
I2S_BIT_SET(CFG_I2SCONF_ADDR + offset, REG_RECE_SLAVE_MOD_OFFSET);
|
|
}
|
|
else
|
|
{
|
|
I2S_BIT_CLR(CFG_I2SCONF_ADDR + offset, REG_RECE_SLAVE_MOD_OFFSET);
|
|
}
|
|
}
|
|
return OK;
|
|
}
|
|
|
|
int i2s_tx_fifo_reset(unsigned char port, unsigned char en)
|
|
{
|
|
unsigned int offset = port * 0x1000;
|
|
|
|
if(port == 4)
|
|
offset += 0xD000;
|
|
if(en)
|
|
{
|
|
I2S_BIT_SET(CFG_I2SCONF_ADDR + offset, I2S_TX_FIFO_RESET_OFFSET);
|
|
}
|
|
else
|
|
{
|
|
I2S_BIT_CLR(CFG_I2SCONF_ADDR + offset, I2S_TX_FIFO_RESET_OFFSET);
|
|
}
|
|
return OK;
|
|
}
|
|
|
|
int i2s_rx_fifo_reset(unsigned char port, unsigned char en)
|
|
{
|
|
unsigned int offset = port * 0x1000;
|
|
|
|
if(port == 4)
|
|
offset += 0xD000;
|
|
|
|
if(en)
|
|
{
|
|
I2S_BIT_SET(CFG_I2SCONF_ADDR + offset, I2S_RX_FIFO_RESET_OFFSET);
|
|
}
|
|
else
|
|
{
|
|
I2S_BIT_CLR(CFG_I2SCONF_ADDR + offset, I2S_RX_FIFO_RESET_OFFSET);
|
|
}
|
|
return OK;
|
|
}
|
|
|
|
int i2s_rx_reset(unsigned char port, unsigned char en)
|
|
{
|
|
unsigned int offset = port * 0x1000;
|
|
|
|
if(port == 4)
|
|
offset += 0xD000;
|
|
|
|
if(en)
|
|
{
|
|
I2S_BIT_SET(CFG_I2SCONF_ADDR + offset, I2S_RX_RESET_OFFSET);
|
|
}
|
|
else
|
|
{
|
|
I2S_BIT_CLR(CFG_I2SCONF_ADDR + offset, I2S_RX_RESET_OFFSET);
|
|
}
|
|
return OK;
|
|
}
|
|
|
|
int i2s_tx_reset(unsigned char port, unsigned char en)
|
|
{
|
|
unsigned int offset = port * 0x1000;
|
|
|
|
if(port == 4)
|
|
offset += 0xD000;
|
|
|
|
if(en)
|
|
{
|
|
I2S_BIT_SET(CFG_I2SCONF_ADDR + offset, I2S_TX_RESET_OFFSET);
|
|
}
|
|
else
|
|
{
|
|
I2S_BIT_CLR(CFG_I2SCONF_ADDR + offset, I2S_TX_RESET_OFFSET);
|
|
}
|
|
return OK;
|
|
}
|
|
|
|
int i2s_int_raw_get(unsigned char port)
|
|
{
|
|
unsigned int offset = port * 0x1000;
|
|
|
|
if(port == 4)
|
|
offset += 0xD000;
|
|
|
|
return (I2S_REG(CFG_I2SINT_RAW_ADDR + offset));
|
|
}
|
|
|
|
|
|
int i2s_int_raw_bit_get(unsigned char port, char offset)
|
|
{
|
|
unsigned int tmp_offset = port * 0x1000;
|
|
|
|
if(port == 4)
|
|
tmp_offset += 0xD000;
|
|
|
|
if(offset>5)
|
|
{
|
|
return -1;
|
|
}
|
|
return (I2S_BIT_GET(CFG_I2SINT_RAW_ADDR + tmp_offset, offset));
|
|
}
|
|
|
|
int i2s_int_status_get(unsigned char port)
|
|
{
|
|
unsigned int offset = port * 0x1000;
|
|
|
|
if(port == 4)
|
|
offset += 0xD000;
|
|
return (I2S_REG(CFG_I2SINT_ST_ADDR + offset));
|
|
}
|
|
|
|
int i2s_int_status_bit_get(unsigned char port, char offset)
|
|
{
|
|
unsigned int tmp_offset = port * 0x1000;
|
|
|
|
if(port == 4)
|
|
tmp_offset += 0xD000;
|
|
if(offset>5)
|
|
{
|
|
return -1;
|
|
}
|
|
return (I2S_BIT_GET(CFG_I2SINT_ST_ADDR + tmp_offset, offset));
|
|
}
|
|
|
|
int i2s_int_enable_set(unsigned char port, unsigned int mask)
|
|
{
|
|
unsigned int offset = port * 0x1000;
|
|
|
|
if(port == 4)
|
|
offset += 0xD000;
|
|
|
|
I2S_REG(CFG_I2SINT_ENA_ADDR + offset) = mask;
|
|
return OK;
|
|
}
|
|
|
|
int i2s_int_enable_bit_set(unsigned char port, unsigned char offset, unsigned char en)
|
|
{
|
|
unsigned int tmp_offset = port * 0x1000;
|
|
|
|
if(port == 4)
|
|
tmp_offset += 0xD000;
|
|
|
|
if(offset>5)
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
if(en)
|
|
{
|
|
I2S_BIT_SET(CFG_I2SINT_ENA_ADDR + tmp_offset, offset);
|
|
}
|
|
else
|
|
{
|
|
I2S_BIT_CLR(CFG_I2SINT_ENA_ADDR + tmp_offset, offset);
|
|
}
|
|
|
|
return OK;
|
|
}
|
|
|
|
int i2s_int_clear_set(unsigned char port, unsigned int mask)
|
|
{
|
|
unsigned int offset = port * 0x1000;
|
|
|
|
if(port == 4)
|
|
offset += 0xD000;
|
|
|
|
I2S_REG(CFG_I2SINT_CLR_ADDR + offset) = mask;
|
|
|
|
return OK;
|
|
}
|
|
|
|
int i2s_int_clear_bit_set(unsigned char port, unsigned char offset, unsigned char en)
|
|
{
|
|
unsigned int tmp_offset = port * 0x1000;
|
|
|
|
if(port == 4)
|
|
tmp_offset += 0xD000;
|
|
|
|
if(offset>5)
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
if(en)
|
|
{
|
|
I2S_BIT_SET(CFG_I2SINT_CLR_ADDR + tmp_offset, offset);
|
|
}
|
|
else
|
|
{
|
|
I2S_BIT_CLR(CFG_I2SINT_CLR_ADDR + tmp_offset, offset);
|
|
}
|
|
return OK;
|
|
}
|
|
|
|
int i2s_timing_set(unsigned char port, unsigned char offset,unsigned char val)
|
|
{
|
|
unsigned int tmp_offset = port * 0x1000;
|
|
|
|
if(port == 4)
|
|
tmp_offset += 0xD000;
|
|
|
|
if((val>3) || offset>19)
|
|
return -1;
|
|
|
|
if(val&0x01)
|
|
{
|
|
I2S_BIT_SET(CFG_I2SINT_CLR_ADDR + tmp_offset, offset);
|
|
}
|
|
else
|
|
{
|
|
I2S_BIT_CLR(CFG_I2SINT_CLR_ADDR + tmp_offset, offset);
|
|
}
|
|
|
|
if(val&0x02)
|
|
{
|
|
I2S_BIT_SET(CFG_I2SINT_CLR_ADDR + tmp_offset, offset+1);
|
|
}
|
|
else
|
|
{
|
|
I2S_BIT_CLR(CFG_I2SINT_CLR_ADDR + tmp_offset, offset+1);
|
|
}
|
|
|
|
return OK;
|
|
}
|
|
|
|
int i2s_fifo_cfg_set(unsigned char port, unsigned int mask)
|
|
{
|
|
unsigned int offset = port * 0x1000;
|
|
|
|
if(port == 4)
|
|
offset += 0xD000;
|
|
I2S_REG(CFG_I2S_FIFO_CONF_ADDR + offset) = mask;
|
|
|
|
return OK;
|
|
}
|
|
|
|
int i2s_fifo_rx_mode_set(unsigned char port, unsigned int mode)
|
|
{
|
|
unsigned int offset = port * 0x1000;
|
|
|
|
if(port == 4)
|
|
offset += 0xD000;
|
|
|
|
if(mode>3)
|
|
return -1;
|
|
|
|
I2S_REG(CFG_I2S_FIFO_CONF_ADDR + offset) &= ~ REG_I2S_RX_FIFO_MOD_MASK;
|
|
I2S_REG(CFG_I2S_FIFO_CONF_ADDR + offset) |= (mode<< REG_I2S_RX_FIFO_MOD_OFFSET);
|
|
return OK;
|
|
}
|
|
|
|
int i2s_fifo_tx_mode_set(unsigned char port, unsigned int mode)
|
|
{
|
|
unsigned int offset = port * 0x1000;
|
|
|
|
if(port == 4)
|
|
offset += 0xD000;
|
|
|
|
if(mode>3)
|
|
return -1;
|
|
|
|
I2S_REG(CFG_I2S_FIFO_CONF_ADDR + offset) &= ~ REG_I2S_TX_FIFO_MOD_MASK;
|
|
I2S_REG(CFG_I2S_FIFO_CONF_ADDR + offset) |= (mode<< REG_I2S_TX_FIFO_MOD_OFFSET);
|
|
return OK;
|
|
}
|
|
|
|
int i2s_dma_mode_en(unsigned char port, unsigned char en)
|
|
{
|
|
unsigned int offset = port * 0x1000;
|
|
|
|
if(port == 4)
|
|
offset += 0xD000;
|
|
|
|
if(en)
|
|
{
|
|
I2S_BIT_SET(CFG_I2S_FIFO_CONF_ADDR + offset, REG_I2S_DSCR_EN_OFFSET);
|
|
}
|
|
else
|
|
{
|
|
I2S_BIT_CLR(CFG_I2S_FIFO_CONF_ADDR + offset, REG_I2S_DSCR_EN_OFFSET);
|
|
}
|
|
return OK;
|
|
}
|
|
|
|
int i2s_tx_data_num_set(unsigned char port, unsigned char num)
|
|
{
|
|
unsigned int offset = port * 0x1000;
|
|
|
|
if(port == 4)
|
|
offset += 0xD000;
|
|
if (num> 0x3f)
|
|
return -1;
|
|
|
|
I2S_REG(CFG_I2S_FIFO_CONF_ADDR + offset) &= ~ REG_I2S_TX_DATA_NUM_MASK;
|
|
I2S_REG(CFG_I2S_FIFO_CONF_ADDR + offset) |= (num<< REG_I2S_TX_DATA_NUM_OFFSET);
|
|
return OK;
|
|
}
|
|
|
|
int i2s_rx_data_num_set(unsigned char port, unsigned char num)
|
|
{
|
|
unsigned int offset = port * 0x1000;
|
|
|
|
if(port == 4)
|
|
offset += 0xD000;
|
|
if (num> 0x3f)
|
|
return -1;
|
|
|
|
I2S_REG(CFG_I2S_FIFO_CONF_ADDR + offset) &= ~REG_I2S_RX_DATA_NUM_MASK;
|
|
I2S_REG(CFG_I2S_FIFO_CONF_ADDR + offset) |= (num<< REG_I2S_RX_DATA_NUM_OFFSET);
|
|
return OK;
|
|
}
|
|
|
|
|
|
int i2s_rx_eof_num_set(unsigned char port, unsigned int num)
|
|
{
|
|
unsigned int offset = port * 0x1000;
|
|
|
|
if(port == 4)
|
|
offset += 0xD000;
|
|
|
|
I2S_REG(CFG_I2SRXEOF_NUM_ADDR + offset) = num;
|
|
return OK;
|
|
}
|
|
|
|
|
|
int i2s_sigle_data_num_set(unsigned char port, unsigned int num)
|
|
{
|
|
unsigned int offset = port * 0x1000;
|
|
|
|
if(port == 4)
|
|
offset += 0xD000;
|
|
I2S_REG(CFG_I2SCONF_SIGLE_DATA_ADDR + offset) = num;
|
|
return OK;
|
|
}
|
|
|
|
int i2s_tx_chan_mode_set(unsigned char port, unsigned char mode)
|
|
{
|
|
unsigned int offset = port * 0x1000;
|
|
|
|
if(port == 4)
|
|
offset += 0xD000;
|
|
if (mode> 0x07)
|
|
return -1;
|
|
|
|
I2S_REG(CFG_I2SCONF_CHAN_ADDR + offset) &= ~REG_TX_CHAN_MOD_MASK;
|
|
I2S_REG(CFG_I2SCONF_CHAN_ADDR + offset) |= (mode<< REG_TX_CHAN_MOD_OFFSET);
|
|
return OK;
|
|
}
|
|
|
|
|
|
int i2s_rx_chan_mode_set(unsigned char port, unsigned char mode)
|
|
{
|
|
unsigned int offset = port * 0x1000;
|
|
|
|
if(port == 4)
|
|
offset += 0xD000;
|
|
|
|
if (mode> 0x04)
|
|
return -1;
|
|
|
|
I2S_REG(CFG_I2SCONF_CHAN_ADDR + offset) &= ~REG_RX_CHAN_MOD_MASK;
|
|
I2S_REG(CFG_I2SCONF_CHAN_ADDR + offset) |= (mode<< REG_RX_CHAN_MOD_OFFSET);
|
|
return OK;
|
|
}
|
|
|
|
|
|
int i2s_pdm_hp_bypass_en(unsigned char port, unsigned char en)
|
|
{
|
|
unsigned int offset = port * 0x1000;
|
|
|
|
if(port == 4)
|
|
offset += 0xD000;
|
|
if(en)
|
|
{
|
|
I2S_BIT_SET(CFG_PDM_CFG0_ADDR + offset, REG_PDM_SADC_HP_BYPASS_OFFSET);
|
|
}
|
|
else
|
|
{
|
|
I2S_BIT_CLR(CFG_PDM_CFG0_ADDR + offset, REG_PDM_SADC_HP_BYPASS_OFFSET);
|
|
}
|
|
return OK;
|
|
}
|
|
|
|
int i2s_pdm_sadc_64bit_en(unsigned char port, unsigned char en)
|
|
{
|
|
unsigned int offset = port * 0x1000;
|
|
|
|
if(port == 4)
|
|
offset += 0xD000;
|
|
if(en)
|
|
{
|
|
I2S_BIT_SET(CFG_PDM_CFG0_ADDR + offset, REG_PDM_SADC_64BIT_OFFSET);
|
|
}
|
|
else
|
|
{
|
|
I2S_BIT_CLR(CFG_PDM_CFG0_ADDR + offset, REG_PDM_SADC_64BIT_OFFSET);
|
|
}
|
|
return OK;
|
|
}
|
|
|
|
int i2s_pdm_sadc_dump_en(unsigned char en)
|
|
{
|
|
if(en)
|
|
{
|
|
I2S_BIT_SET(CFG_PDM_CFG0_ADDR, REG_PDM_SADC_DUMP_OFFSET);
|
|
}
|
|
else
|
|
{
|
|
I2S_BIT_CLR(CFG_PDM_CFG0_ADDR, REG_PDM_SADC_DUMP_OFFSET);
|
|
}
|
|
return OK;
|
|
}
|
|
|
|
int i2s_pdm_sadc_en(unsigned char en)
|
|
{
|
|
if(en)
|
|
{
|
|
I2S_BIT_SET(CFG_PDM_CFG0_ADDR, REG_PDM_SADC_EN_OFFSET);
|
|
}
|
|
else
|
|
{
|
|
I2S_BIT_CLR(CFG_PDM_CFG0_ADDR, REG_PDM_SADC_EN_OFFSET);
|
|
}
|
|
return OK;
|
|
}
|
|
|
|
|
|
int i2s_sinc_dsap(unsigned char port, unsigned char rate)
|
|
{
|
|
unsigned int offset = port * 0x1000;
|
|
|
|
if(port == 4)
|
|
offset += 0xD000;
|
|
|
|
if (rate> 0x04)
|
|
return -1;
|
|
|
|
I2S_REG(CFG_PDM_CFG0_ADDR + offset) &= ~REG_SINC_DSAMP_MASK;
|
|
I2S_REG(CFG_PDM_CFG0_ADDR + offset) |= (rate<< REG_SINC_DSAMP_OFFSET);
|
|
return OK;
|
|
}
|
|
|
|
int i2s_sinc_order(unsigned char port, unsigned char order)
|
|
{
|
|
unsigned int offset = port * 0x1000;
|
|
|
|
if(port == 4)
|
|
offset += 0xD000;
|
|
|
|
if (order> 0x04)
|
|
return -1;
|
|
|
|
I2S_REG(CFG_PDM_CFG0_ADDR + offset) &= ~REG_SINC_ORDER_MASK;
|
|
I2S_REG(CFG_PDM_CFG0_ADDR + offset) |= (order<< REG_SINC_ORDER_OFFSET);
|
|
return OK;
|
|
}
|
|
|
|
|
|
int i2s_pdm_slave_mod_en(unsigned char port, unsigned char dir, unsigned char en)
|
|
{
|
|
unsigned int offset = port * 0x1000;
|
|
|
|
if(port == 4)
|
|
offset += 0xD000;
|
|
|
|
if(en)
|
|
{
|
|
I2S_BIT_SET(CFG_PDM_RX_CFG_ADDR-4*dir + offset, REG_RX_SLAVE_MOD_OFFSET);
|
|
}
|
|
else
|
|
{
|
|
I2S_BIT_CLR(CFG_PDM_RX_CFG_ADDR-4*dir + offset, REG_RX_SLAVE_MOD_OFFSET);
|
|
}
|
|
return OK;
|
|
}
|
|
|
|
int i2s_pdm_tx_sd_scale(unsigned char port, unsigned char div)
|
|
{
|
|
unsigned int offset = port * 0x1000;
|
|
|
|
if(port == 4)
|
|
offset += 0xD000;
|
|
|
|
if (div> 0x04)
|
|
return -1;
|
|
|
|
I2S_REG(CFG_PDM_TX_CFG_ADDR + offset) &= ~(REG_PDM_TX_SD_SCALE_MASK);
|
|
I2S_REG(CFG_PDM_TX_CFG_ADDR + offset) |= (div<< REG_PDM_TX_SD_SCALE_OFFSET);
|
|
return OK;
|
|
}
|
|
|
|
int i2s_pdm_rx_hp_downsample(unsigned char port, unsigned char div)
|
|
{
|
|
unsigned int offset = port * 0x1000;
|
|
|
|
if(port == 4)
|
|
offset += 0xD000;
|
|
|
|
if (div> 0x04)
|
|
return -1;
|
|
|
|
I2S_REG(CFG_PDM_RX_CFG_ADDR + offset) &= ~(REG_RX_HP_DOWNSAMPLE_MASK);
|
|
I2S_REG(CFG_PDM_RX_CFG_ADDR + offset) |= (div<< REG_RX_HP_DOWNSAMPLE_OFFSET);
|
|
return OK;
|
|
}
|
|
|
|
|
|
int i2s_pdm_rx_tx_en(unsigned char port, unsigned char dir, unsigned char en)
|
|
{
|
|
unsigned int offset = port * 0x1000;
|
|
|
|
if(port == 4)
|
|
offset += 0xD000;
|
|
|
|
if(en)
|
|
{
|
|
I2S_BIT_SET(CFG_PDM_RX_CFG_ADDR-4*dir + offset, REG_PDM_RX_EN_OFFSET);
|
|
}
|
|
else
|
|
{
|
|
I2S_BIT_CLR(CFG_PDM_RX_CFG_ADDR-4*dir + offset, REG_PDM_RX_EN_OFFSET);
|
|
}
|
|
return OK;
|
|
}
|
|
|
|
int i2s_pdm_bck_div(unsigned char port, unsigned char dir, unsigned char div)
|
|
{
|
|
unsigned int offset = port * 0x1000;
|
|
|
|
if (dir> 0x01)
|
|
{ return -1;}
|
|
|
|
if(port == 4)
|
|
{offset += 0xD000;
|
|
}
|
|
|
|
I2S_REG(CFG_PDM_RX_CFG_ADDR-4*dir+offset) &= ~(REG_PDM_RX_BCK_DIV_MASK);
|
|
I2S_REG(CFG_PDM_RX_CFG_ADDR-4*dir+offset)|=(div<<REG_PDM_RX_BCK_DIV_OFFSET);
|
|
return OK;
|
|
}
|
|
|
|
void i2s_pdm_clk_cfg(uint8_t port, uint32_t freq)
|
|
{
|
|
// pll 300MHZ: 300M * div_n/div_m = FS * over_sample * pdm_div
|
|
// over_sample = 128
|
|
if (freq == 16000) {
|
|
clk_i2s_dev_set(0, 0x249f, 0x80);
|
|
i2s_pdm_bck_div(port, I2S_DIR_RX, 2);
|
|
} else if (freq == 32000) {
|
|
clk_i2s_dev_set(0, 0x249f, 0x80);
|
|
i2s_pdm_bck_div(port, I2S_DIR_RX, 1);
|
|
}
|
|
}
|
|
|
|
void i2s_pdm_set_lp_hp_scale(unsigned char port, uint32_t lp_hp)
|
|
{
|
|
unsigned int offset = port * 0x1000;
|
|
|
|
if(port == 4)
|
|
offset += 0xD000;
|
|
|
|
*(volatile int*)(I2S0_BASEADDR+0x34+offset) = lp_hp;
|
|
}
|
|
|
|
int i2s_pdm_sinc16(unsigned char port, unsigned char dir, unsigned char en)
|
|
{
|
|
unsigned int offset = port * 0x1000;
|
|
|
|
if(port == 4)
|
|
offset += 0xD000;
|
|
|
|
if(en)
|
|
{
|
|
I2S_BIT_SET(CFG_PDM_RX_CFG_ADDR-4*dir + offset, REG_PDM_RX_SINC16_OFFSET);
|
|
}
|
|
else
|
|
{
|
|
I2S_BIT_CLR(CFG_PDM_RX_CFG_ADDR-4*dir + offset, REG_PDM_RX_SINC16_OFFSET);
|
|
}
|
|
return OK;
|
|
}
|
|
|
|
|
|
int i2s_pdm_hp_bypass(unsigned char port, unsigned char dir, unsigned char en)
|
|
{
|
|
unsigned int offset = port * 0x1000;
|
|
|
|
if(port == 4)
|
|
offset += 0xD000;
|
|
|
|
if(en)
|
|
{
|
|
I2S_BIT_SET(CFG_PDM_RX_CFG_ADDR-4*dir + offset, REG_PDM_RX_HP_BYPASS_OFFSET);
|
|
}
|
|
else
|
|
{
|
|
I2S_BIT_CLR(CFG_PDM_RX_CFG_ADDR-4*dir + offset, REG_PDM_RX_HP_BYPASS_OFFSET);
|
|
}
|
|
return OK;
|
|
}
|
|
|
|
|
|
int i2s_pdm_phase(unsigned char port, unsigned char dir, unsigned char ph)
|
|
{
|
|
unsigned int offset = port * 0x1000;
|
|
|
|
if(port == 4)
|
|
offset += 0xD000;
|
|
|
|
if (ph> 0x04)
|
|
return -1;
|
|
|
|
I2S_REG(CFG_PDM_RX_CFG_ADDR-4*dir + offset) &= ~(REG_PDM_RX_PHASE_MASK);
|
|
I2S_REG(CFG_PDM_RX_CFG_ADDR-4*dir + offset) |= (ph<< REG_PDM_RX_PHASE_OFFSET);
|
|
return OK;
|
|
}
|
|
|
|
int i2s_apb_enable(uint8_t port)
|
|
{
|
|
switch(port)
|
|
{
|
|
case 4:
|
|
apb_enable(APB_IIS4);
|
|
break;
|
|
case 3:
|
|
apb_enable(APB_IIS3);
|
|
break;
|
|
case 2:
|
|
apb_enable(APB_IIS2);
|
|
break;
|
|
case 1:
|
|
apb_enable(APB_IIS1);
|
|
break;
|
|
case 0:
|
|
apb_enable(APB_IIS0);
|
|
break;
|
|
default:
|
|
return ERR_FAIL;
|
|
}
|
|
return OK;
|
|
}
|
|
|
|
uint8_t i2s_gpio_func_sel(uint8_t gpio)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
void i2s_gpio_sig_sel(uint8_t port, uint8_t mod, uint8_t *bck_id, uint8_t *data_id, uint8_t *ws_id)
|
|
{
|
|
if(mod == 0) //tx master
|
|
{
|
|
*bck_id = 27;
|
|
*data_id = 29;
|
|
*ws_id = 28;
|
|
|
|
switch (port)
|
|
{
|
|
case 1:
|
|
case 2:
|
|
case 3:
|
|
*bck_id = 102 + (port-1) * 6;
|
|
*data_id = 104 + (port-1) * 6;
|
|
*ws_id = 103 + (port-1) * 6;
|
|
break;
|
|
case 4:
|
|
*bck_id = 156;
|
|
*data_id = 158;
|
|
*ws_id = 157;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}else if(mod ==1){ //tx slave
|
|
*bck_id = 21;
|
|
*data_id = 29;
|
|
*ws_id = 22;
|
|
|
|
switch (port)
|
|
{
|
|
case 1:
|
|
case 2:
|
|
case 3:
|
|
*bck_id = 66 + (port-1) * 6;
|
|
*data_id = 104 + (port-1) * 6;
|
|
*ws_id = 67 + (port-1) * 6;
|
|
break;
|
|
case 4:
|
|
*bck_id = 104;
|
|
*data_id = 158;
|
|
*ws_id = 105;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}else if(mod ==2){ //rx master
|
|
*bck_id = 30;
|
|
*data_id = 26;
|
|
*ws_id = 31;
|
|
|
|
switch (port)
|
|
{
|
|
case 1:
|
|
case 2:
|
|
case 3:
|
|
*bck_id = 105 + (port-1) * 6;
|
|
*data_id = 71 + (port-1) * 6;
|
|
*ws_id = 106 + (port-1) * 6;
|
|
break;
|
|
case 4:
|
|
*bck_id = 153;
|
|
*data_id = 103;
|
|
*ws_id = 154;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}else if(mod == 3){ //rx slave
|
|
*bck_id = 24;
|
|
*data_id = 26;
|
|
*ws_id = 25;
|
|
|
|
switch (port)
|
|
{
|
|
case 1:
|
|
case 2:
|
|
case 3:
|
|
*bck_id = 69 + (port-1) * 6;
|
|
*data_id = 71 + (port-1) * 6;
|
|
*ws_id = 70 + (port-1) * 6;
|
|
break;
|
|
case 4:
|
|
*bck_id = 101;
|
|
*data_id = 103;
|
|
*ws_id = 102;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* i2s mclk */
|
|
void clk_i2s_mclk_set(uint32_t div, uint32_t m, uint32_t n)
|
|
{
|
|
uint32_t tmp;
|
|
tmp = AP_CLK_CORE_RF_READ_REG(CFG_MCLK_AUDIO_CFG_ADDR);
|
|
REG_FIELD_SET(MCLK_AUDIO_DIV, tmp, div);
|
|
REG_FIELD_SET(MCLK_AUDIO_DIV_M, tmp, m);
|
|
REG_FIELD_SET(MCLK_AUDIO_DIV_N, tmp, n);
|
|
AP_CLK_CORE_RF_WRITE_REG(CFG_MCLK_AUDIO_CFG_ADDR, tmp);
|
|
}
|
|
|
|
uint8_t i2s_set_mclk(uint8_t gpio, uint32_t clk)
|
|
{
|
|
apb_enable(APB_MCLK);
|
|
|
|
gpio_sig_info_t info =
|
|
{
|
|
1,
|
|
{
|
|
{IO_TYPE_OUT, 0, gpio, 0xff, 152}, // i2s mclk out
|
|
}
|
|
};
|
|
gpio_mtx_enable();
|
|
gpio_module_pin_select(&info);
|
|
gpio_module_sig_select(&info, GPIO_MTX_MODE_MATRIX);
|
|
|
|
// clk = 300m * div_n * (div+1)/ div_m
|
|
// mclk = 256 * FS, set div = 0
|
|
// m= n * (300m / clk)
|
|
|
|
if (clk == 4096*1000) {
|
|
clk_i2s_mclk_set(0, 0x249f, 0x80);
|
|
} else if (clk == 2048*1000) {
|
|
clk_i2s_mclk_set(0, 0x249f, 0x40);
|
|
} else {
|
|
return ERR_FAIL;
|
|
}
|
|
|
|
return ERR_OK;
|
|
}
|
|
|
|
/* i2s clock relationship:
|
|
MCK = 256 * FS
|
|
I2S_CLK = 32 * FS, 48 * FS,
|
|
PDM_CLK = 32 * FS * over_sample, 48 * FS * over_sample,
|
|
MCK = 8 * I2S_CLK = 8 * PDM_CLK,
|
|
set div = 7, so mclk_div_m mclk_div_n equal to i2s/pdm
|
|
|
|
*/
|
|
#endif
|
|
|
|
int i2s_clk_div(unsigned char port, uint32_t div)
|
|
{
|
|
return OK;
|
|
}
|
|
|
|
void i2s_clk_cfg(uint8_t port, uint32_t freq)
|
|
{
|
|
|
|
}
|
|
|
|
uint8_t i2s_bit_mode_set(unsigned char port, uint8_t bm)
|
|
{
|
|
return ERR_OK;
|
|
}
|
|
|
|
int i2s_tx_msb_shift_set(unsigned char port, unsigned char en)
|
|
{
|
|
return OK;
|
|
}
|
|
|
|
int i2s_rx_msb_shift_set(unsigned char port, unsigned char en)
|
|
{
|
|
return OK;
|
|
}
|
|
|
|
|
|
int i2s_tx_start(unsigned char port)
|
|
{
|
|
return OK;
|
|
}
|
|
|
|
int i2s_tx_stop(unsigned char port)
|
|
{
|
|
return OK;
|
|
}
|
|
|
|
int i2s_rx_start(unsigned char port)
|
|
{
|
|
return OK;
|
|
}
|
|
|
|
int i2s_rx_stop(unsigned char port)
|
|
{
|
|
return OK;
|
|
}
|
|
|
|
|
|
int i2s_msb_right(unsigned char port, unsigned char en)
|
|
{
|
|
return OK;
|
|
}
|
|
|
|
int i2s_right_first(unsigned char port, unsigned char en)
|
|
{
|
|
return OK;
|
|
}
|
|
|
|
int i2s_transive_mode(unsigned char port, unsigned char dir,unsigned char mode)
|
|
{
|
|
return OK;
|
|
}
|
|
|
|
int i2s_tx_fifo_reset(unsigned char port, unsigned char en)
|
|
{
|
|
return OK;
|
|
}
|
|
|
|
int i2s_rx_fifo_reset(unsigned char port, unsigned char en)
|
|
{
|
|
return OK;
|
|
}
|
|
|
|
int i2s_rx_reset(unsigned char port, unsigned char en)
|
|
{
|
|
return OK;
|
|
}
|
|
|
|
int i2s_tx_reset(unsigned char port, unsigned char en)
|
|
{
|
|
return OK;
|
|
}
|
|
|
|
int i2s_int_raw_get(unsigned char port)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
|
|
int i2s_int_raw_bit_get(unsigned char port, char offset)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
int i2s_int_status_get(unsigned char port)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
int i2s_int_status_bit_get(unsigned char port, char offset)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
int i2s_int_enable_set(unsigned char port, unsigned int mask)
|
|
{
|
|
return OK;
|
|
}
|
|
|
|
int i2s_int_enable_bit_set(unsigned char port, unsigned char offset, unsigned char en)
|
|
{
|
|
return OK;
|
|
}
|
|
|
|
int i2s_int_clear_set(unsigned char port, unsigned int mask)
|
|
{
|
|
return OK;
|
|
}
|
|
|
|
int i2s_int_clear_bit_set(unsigned char port, unsigned char offset, unsigned char en)
|
|
{
|
|
return OK;
|
|
}
|
|
|
|
int i2s_timing_set(unsigned char port, unsigned char offset,unsigned char val)
|
|
{
|
|
return OK;
|
|
}
|
|
|
|
int i2s_fifo_cfg_set(unsigned char port, unsigned int mask)
|
|
{
|
|
return OK;
|
|
}
|
|
|
|
int i2s_fifo_rx_mode_set(unsigned char port, unsigned int mode)
|
|
{
|
|
return OK;
|
|
}
|
|
|
|
int i2s_fifo_tx_mode_set(unsigned char port, unsigned int mode)
|
|
{
|
|
return OK;
|
|
}
|
|
|
|
int i2s_dma_mode_en(unsigned char port, unsigned char en)
|
|
{
|
|
return OK;
|
|
}
|
|
|
|
int i2s_tx_data_num_set(unsigned char port, unsigned char num)
|
|
{
|
|
return OK;
|
|
}
|
|
|
|
int i2s_rx_data_num_set(unsigned char port, unsigned char num)
|
|
{
|
|
return OK;
|
|
}
|
|
|
|
|
|
int i2s_rx_eof_num_set(unsigned char port, unsigned int num)
|
|
{
|
|
return OK;
|
|
}
|
|
|
|
|
|
int i2s_sigle_data_num_set(unsigned char port, unsigned int num)
|
|
{
|
|
return OK;
|
|
}
|
|
|
|
int i2s_tx_chan_mode_set(unsigned char port, unsigned char mode)
|
|
{
|
|
return OK;
|
|
}
|
|
|
|
|
|
int i2s_rx_chan_mode_set(unsigned char port, unsigned char mode)
|
|
{
|
|
return OK;
|
|
}
|
|
|
|
|
|
int i2s_pdm_hp_bypass_en(unsigned char port, unsigned char en)
|
|
{
|
|
return OK;
|
|
}
|
|
|
|
int i2s_pdm_sadc_64bit_en(unsigned char port, unsigned char en)
|
|
{
|
|
return OK;
|
|
}
|
|
|
|
int i2s_pdm_sadc_dump_en(unsigned char en)
|
|
{
|
|
return OK;
|
|
}
|
|
|
|
int i2s_pdm_sadc_en(unsigned char en)
|
|
{
|
|
return OK;
|
|
}
|
|
|
|
|
|
int i2s_sinc_dsap(unsigned char port, unsigned char rate)
|
|
{
|
|
return OK;
|
|
}
|
|
|
|
int i2s_sinc_order(unsigned char port, unsigned char order)
|
|
{
|
|
return OK;
|
|
}
|
|
|
|
|
|
int i2s_pdm_slave_mod_en(unsigned char port, unsigned char dir, unsigned char en)
|
|
{
|
|
return OK;
|
|
}
|
|
|
|
int i2s_pdm_tx_sd_scale(unsigned char port, unsigned char div)
|
|
{
|
|
return OK;
|
|
}
|
|
|
|
int i2s_pdm_rx_hp_downsample(unsigned char port, unsigned char div)
|
|
{
|
|
return OK;
|
|
}
|
|
|
|
|
|
int i2s_pdm_rx_tx_en(unsigned char port, unsigned char dir, unsigned char en)
|
|
{
|
|
return OK;
|
|
}
|
|
|
|
int i2s_pdm_bck_div(unsigned char port, unsigned char dir, unsigned char div)
|
|
{
|
|
return OK;
|
|
}
|
|
|
|
void i2s_pdm_clk_cfg(uint8_t port, uint32_t freq)
|
|
{
|
|
|
|
}
|
|
|
|
void i2s_pdm_set_lp_hp_scale(unsigned char port, uint32_t lp_hp)
|
|
{
|
|
|
|
}
|
|
|
|
int i2s_pdm_sinc16(unsigned char port, unsigned char dir, unsigned char en)
|
|
{
|
|
return OK;
|
|
}
|
|
|
|
|
|
int i2s_pdm_hp_bypass(unsigned char port, unsigned char dir, unsigned char en)
|
|
{
|
|
return OK;
|
|
}
|
|
|
|
|
|
int i2s_pdm_phase(unsigned char port, unsigned char dir, unsigned char ph)
|
|
{
|
|
return OK;
|
|
}
|
|
|
|
int i2s_apb_enable(uint8_t port)
|
|
{
|
|
return OK;
|
|
}
|
|
|
|
uint8_t i2s_gpio_func_sel(uint8_t gpio)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
void i2s_gpio_sig_sel(uint8_t port, uint8_t mod, uint8_t *bck_id, uint8_t *data_id, uint8_t *ws_id)
|
|
{
|
|
|
|
}
|
|
|
|
/* i2s mclk */
|
|
void clk_i2s_mclk_set(uint32_t div, uint32_t m, uint32_t n)
|
|
{
|
|
|
|
}
|
|
|
|
uint8_t i2s_set_mclk(uint8_t gpio, uint32_t clk)
|
|
{
|
|
return ERR_OK;
|
|
}
|
|
|