221 lines
5.9 KiB
C
221 lines
5.9 KiB
C
#include "includes.h"
|
||
|
||
/*FFT模块资源互斥方式配置*/
|
||
#define CRITICAL_NULL 0
|
||
#define CRITICAL_IRQ 1
|
||
#define CRITICAL_MUTEX 2
|
||
#define CRITICAL_SPIN_LOCK 3
|
||
#define FFT_CRITICAL_MODE CRITICAL_SPIN_LOCK
|
||
|
||
#if (FFT_CRITICAL_MODE == CRITICAL_MUTEX)
|
||
static OS_MUTEX fft_mutex;
|
||
#define FFT_CRITICAL_INIT() os_mutex_create(&fft_mutex)
|
||
#define FFT_ENTER_CRITICAL() os_mutex_pend(&fft_mutex, 0)
|
||
#define FFT_EXIT_CRITICAL() os_mutex_post(&fft_mutex)
|
||
#elif (FFT_CRITICAL_MODE == CRITICAL_IRQ)
|
||
#define FFT_CRITICAL_INIT(...)
|
||
#define FFT_ENTER_CRITICAL() local_irq_disable()
|
||
#define FFT_EXIT_CRITICAL() local_irq_enable()
|
||
#elif (FFT_CRITICAL_MODE == CRITICAL_SPIN_LOCK)
|
||
static spinlock_t fft_lock;
|
||
#define FFT_CRITICAL_INIT() spin_lock_init(&fft_lock)
|
||
#define FFT_ENTER_CRITICAL() spin_lock(&fft_lock)
|
||
#define FFT_EXIT_CRITICAL() spin_unlock(&fft_lock)
|
||
|
||
#endif /*FFT_CRITICAL_MODE*/
|
||
|
||
static volatile u8 fft_init = 0;
|
||
|
||
typedef struct {
|
||
unsigned int fft_config;
|
||
const int *in;
|
||
int *out;
|
||
} pi32v2_hw_fft_ctx;
|
||
|
||
#define FFT_ISR_IE 0
|
||
void hw_fft_wrap(pi32v2_hw_fft_ctx *ctx)
|
||
{
|
||
if (fft_init == 0) {
|
||
fft_init = 1;
|
||
FFT_CRITICAL_INIT();
|
||
}
|
||
FFT_ENTER_CRITICAL();
|
||
|
||
JL_FFT->CON = 0;
|
||
JL_FFT->CON |= 1 << 8;
|
||
JL_FFT->CADR = (unsigned int)ctx;
|
||
JL_FFT->CON = (1 << 8) | (0 << 6) | (FFT_ISR_IE << 2) | (0 << 1) | (1 << 0); //((1<<8)|(1<<0))
|
||
while ((JL_FFT->CON & (1 << 7)) == 0);
|
||
JL_FFT->CON |= (1 << 6);
|
||
|
||
FFT_EXIT_CRITICAL();
|
||
}
|
||
|
||
static int REAL_FFT_CONFIG[6] = {
|
||
809501970, 813696546, 822085426, 838862898, 872417602, 939526722,
|
||
};
|
||
|
||
/**** Real IFFT *******/
|
||
static int REAL_IFFT_CONFIG[6] = {
|
||
809501958, 1082131974, 822085382, 1107298310, 872417542, 1207962118,
|
||
};
|
||
|
||
/****************************
|
||
*
|
||
* Complex Support points
|
||
* 32\64\128\256\512\1024\2048
|
||
*
|
||
* *************************/
|
||
/**** Complex FFT *******/
|
||
static int COMPLEX_FFT_CONFIG[7] = {
|
||
538969360, 541066784, 545261344, 553650224, 570427696, 603982400, 671091520,
|
||
};
|
||
|
||
/**** Complex IFFT *******/
|
||
static int COMPLEX_IFFT_CONFIG[7] = {
|
||
1075840276, 809502212, 1082132244, 822085636, 1107298580, 872417796, 1207962388,
|
||
};
|
||
|
||
|
||
|
||
/*********************************************************************
|
||
* hw_fft_config
|
||
* Description: 根据配置生成 FFT_config
|
||
* Arguments : N 运算数据量;
|
||
log2N 运算数据量的对数值
|
||
is_same_addr 输入输出是否同一个地址,0:否,1:是
|
||
is_ifft 运算类型 0:FFT运算, 1:IFFT运算
|
||
is_real 运算数据的类型 1:实数, 0:复数
|
||
* Return : ConfgPars 写入FFT寄存器
|
||
* Note(s) : None.
|
||
*********************************************************************/
|
||
unsigned int hw_fft_config(int N, int log2N, int is_same_addr, int is_ifft, int is_real)
|
||
{
|
||
unsigned int ConfgPars;
|
||
ConfgPars = 0;
|
||
if (is_real == 1) {
|
||
if (is_ifft == 0) {
|
||
ConfgPars = REAL_FFT_CONFIG[log2N - 6];
|
||
ConfgPars |= is_same_addr;
|
||
} else {
|
||
ConfgPars = REAL_IFFT_CONFIG[log2N - 6];
|
||
ConfgPars |= is_same_addr;
|
||
}
|
||
} else {
|
||
if (is_ifft == 0) {
|
||
ConfgPars = COMPLEX_FFT_CONFIG[log2N - 5];
|
||
ConfgPars |= is_same_addr;
|
||
} else {
|
||
ConfgPars = COMPLEX_IFFT_CONFIG[log2N - 5];
|
||
ConfgPars |= is_same_addr;
|
||
}
|
||
}
|
||
/* printf("ConfgPars%x\n",ConfgPars); */
|
||
return ConfgPars;
|
||
}
|
||
|
||
/*********************************************************************
|
||
* hw_fft_run
|
||
* Description: fft/ifft运算函数
|
||
* Arguments :fft_config FFT运算配置寄存器值
|
||
in 输入数据地址(满足4byte对其,以及非const类型)
|
||
out 输出数据地址
|
||
* Return : void
|
||
* Note(s) : None.
|
||
*********************************************************************/
|
||
void hw_fft_run(unsigned int fft_config, const int *in, int *out)
|
||
{
|
||
pi32v2_hw_fft_ctx ctx;
|
||
ctx.fft_config = fft_config;
|
||
ctx.in = in;
|
||
ctx.out = out;
|
||
hw_fft_wrap(&ctx);
|
||
}
|
||
|
||
//////////////////////////////////////////////////////////////////////////
|
||
// VECTOR
|
||
//////////////////////////////////////////////////////////////////////////
|
||
|
||
typedef struct {
|
||
unsigned long vector_con;
|
||
unsigned long vector_xadr;
|
||
unsigned long vector_yadr;
|
||
unsigned long vector_zadr;
|
||
unsigned long vector_config0;
|
||
unsigned long vector_config1;
|
||
unsigned long vector_config2;
|
||
unsigned long null;
|
||
} hwvec_ctx_t;
|
||
|
||
static hwvec_ctx_t g_vector_core_set __attribute__((aligned(16)));
|
||
|
||
//__attribute__ ((always_inline)) inline
|
||
void hwvec_exec(
|
||
void *xptr,
|
||
void *yptr,
|
||
void *zptr,
|
||
short x_inc,
|
||
short y_inc,
|
||
short z_inc,
|
||
short nlen,
|
||
short nloop,
|
||
char q,
|
||
long config,
|
||
long const_dat
|
||
)
|
||
{
|
||
|
||
if (fft_init == 0) {
|
||
fft_init = 1;
|
||
FFT_CRITICAL_INIT();
|
||
}
|
||
|
||
FFT_ENTER_CRITICAL();
|
||
|
||
g_vector_core_set.vector_con = config;
|
||
g_vector_core_set.vector_config0 = (q << 24) | (nloop << 12) | (nlen);
|
||
g_vector_core_set.vector_config1 = (z_inc << 20) | (y_inc << 10) | x_inc;
|
||
//printf("nlen0:%d,nloop:%d,q:%d,config:%d,%d\n",nlen,nloop,q,config,const_dat);
|
||
|
||
g_vector_core_set.vector_xadr = (unsigned long)xptr;
|
||
g_vector_core_set.vector_yadr = (unsigned long)yptr;
|
||
g_vector_core_set.vector_zadr = (unsigned long)zptr;
|
||
|
||
JL_FFT->CONST = const_dat;
|
||
|
||
JL_FFT->CADR = (unsigned long)(&g_vector_core_set);
|
||
|
||
|
||
// nu clr vector ie en
|
||
JL_FFT->CON = (1 << 8) | (1 << 6) | (1 << 3) | (1 << 2) | (1 << 0);
|
||
|
||
|
||
lp_waiting((int *)&JL_FFT->CON, BIT(7), BIT(6), 116);
|
||
|
||
FFT_EXIT_CRITICAL();
|
||
}
|
||
|
||
u8 fft_wrap_for_ldac_enable(void)
|
||
{
|
||
return 1;
|
||
}
|
||
|
||
int _FFT_wrap_(int cfg, int *in, int *out)
|
||
{
|
||
//init pi32v2 fft hardware
|
||
pi32v2_hw_fft_ctx ctx;
|
||
if (in == out) {
|
||
cfg |= 1;
|
||
}
|
||
|
||
ctx.fft_config = cfg;
|
||
ctx.in = in;
|
||
ctx.out = out;
|
||
hw_fft_wrap(&ctx);
|
||
|
||
return 0;
|
||
}
|
||
|
||
|
||
|