Files
99_7018_lmx/cpu/br28/hw_fft.c
2025-10-29 13:10:02 +08:00

221 lines
5.9 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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;
}