793 lines
		
	
	
		
			25 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			793 lines
		
	
	
		
			25 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/****************************************************************************
 | 
						|
 | 
						|
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 "chip_reg_base.h"
 | 
						|
#include "hw_reg_api.h"
 | 
						|
 | 
						|
#include "afft_hw.h"
 | 
						|
#include "dbg_io.h"
 | 
						|
#include "gp_timer.h"
 | 
						|
#include "iot_irq.h"
 | 
						|
#include "iot_clock.h"
 | 
						|
 | 
						|
#include "os_mem_api.h"
 | 
						|
#include "iot_afft_api.h"
 | 
						|
#include "iot_io_api.h"
 | 
						|
#include "iot_errno_api.h"
 | 
						|
#include "iot_utils_api.h"
 | 
						|
 | 
						|
#include "dtest_printf.h"
 | 
						|
#include "fft_test_data_real.h"
 | 
						|
#include "fft_test_data_complex.h"
 | 
						|
#include "fft_test_data_float_real.h"
 | 
						|
#include "fft_test_data_float_complex.h"
 | 
						|
 | 
						|
#define DTEST_FFT_CASE_REAL_FFT             (1 << 0)
 | 
						|
#define DTEST_FFT_CASE_REAL_IFFT            (1 << 1)
 | 
						|
#define DTEST_FFT_CASE_COMPLEX_FFT          (1 << 2)
 | 
						|
#define DTEST_FFT_CASE_COMPLEX_IFFT         (1 << 3)
 | 
						|
#define DTEST_FFT_CASE_FLOAT_REAL_FFT       (1 << 4)
 | 
						|
#define DTEST_FFT_CASE_FLOAT_REAL_IFFT      (1 << 5)
 | 
						|
#define DTEST_FFT_CASE_FLOAT_COMPLEX_FFT    (1 << 6)
 | 
						|
#define DTEST_FFT_CASE_FLOAT_COMPLEX_IFFT   (1 << 7)
 | 
						|
#define DTEST_FFT_CASE_COMPLETE_INTERRUPT   (1 << 8)
 | 
						|
 | 
						|
#define DTEST_FFT_DATA_LEN_MAX              2048
 | 
						|
 | 
						|
#define DTEST_FFT_COMPARE_DEBUG             0
 | 
						|
//#define iot_printf(fmt, ...)
 | 
						|
 | 
						|
typedef enum {
 | 
						|
    DTEST_FFT_MODE_REAL_FFT = 0,
 | 
						|
    DTEST_FFT_MODE_REAL_IFFT,
 | 
						|
    DTEST_FFT_MODE_COMPLEX_FFT,
 | 
						|
    DTEST_FFT_MODE_COMPLEX_IFFT,
 | 
						|
    DTEST_FFT_MODE_FLOAT_REAL_FFT,
 | 
						|
    DTEST_FFT_MODE_FLOAT_REAL_IFFT,
 | 
						|
    DTEST_FFT_MODE_FLOAT_COMPLEX_FFT,
 | 
						|
    DTEST_FFT_MODE_FLOAT_COMPLEX_IFFT,
 | 
						|
    DTEST_FFT_MODE_MAX,
 | 
						|
} DTEST_FFT_MODE_E;
 | 
						|
 | 
						|
 | 
						|
typedef enum {
 | 
						|
    DTEST_FFT_SIZE_32 = 0,
 | 
						|
    DTEST_FFT_SIZE_64,
 | 
						|
    DTEST_FFT_SIZE_128,
 | 
						|
    DTEST_FFT_SIZE_256,
 | 
						|
    DTEST_FFT_SIZE_512,
 | 
						|
    DTEST_FFT_SIZE_1024,
 | 
						|
    DTEST_FFT_SIZE_2048,
 | 
						|
    DTEST_FFT_SIZE_MAX,
 | 
						|
} DTEST_FFT_SIZE_E;
 | 
						|
 | 
						|
/* copy form dtest\ada_test\math.c */
 | 
						|
static double dtest_fft_sqrt_double(double x)
 | 
						|
{
 | 
						|
    double m = 0.0, n, y;
 | 
						|
 | 
						|
    if (x < 0)
 | 
						|
        return -1;
 | 
						|
    if (x == 0)
 | 
						|
        return 0;
 | 
						|
 | 
						|
    n = x / 2;
 | 
						|
    while(m != n) {
 | 
						|
        m = n;
 | 
						|
        n = (m + x / m) / 2;
 | 
						|
    }
 | 
						|
    y = m;
 | 
						|
 | 
						|
    return (y + x / y) / 2;
 | 
						|
}
 | 
						|
 | 
						|
static uint32_t dtest_fft_result_compare(uint32_t *cal,
 | 
						|
    uint32_t *expect, uint32_t size, DTEST_FFT_MODE_E mode)
 | 
						|
{
 | 
						|
    int i, err_cnt = 0, index_max = 0;
 | 
						|
 | 
						|
    if (mode < DTEST_FFT_MODE_FLOAT_REAL_FFT) {
 | 
						|
        int data_max = 0, data_temp;
 | 
						|
        int64_t data_square;
 | 
						|
        int data_cal, data_exp, data_delta, data_standard;
 | 
						|
 | 
						|
        /* get max data */
 | 
						|
        for (i = 0; i < size; i++) {
 | 
						|
            data_temp = IOT_ABS((int)cal[i]);
 | 
						|
            if (data_temp >= data_max) {
 | 
						|
#if DTEST_FFT_COMPARE_DEBUG
 | 
						|
                iot_printf("find bigger int data:%d, index:%d\n", data_temp, i);
 | 
						|
#endif
 | 
						|
                index_max = i;
 | 
						|
                data_max = data_temp;
 | 
						|
            }
 | 
						|
        }
 | 
						|
        index_max = (index_max % 2) ? (index_max - 1) : index_max;
 | 
						|
        /* calculate sqrt root */
 | 
						|
        data_temp = IOT_ABS((int)cal[index_max]);
 | 
						|
        iot_printf("get max data index:%d, real part:%d, ", index_max, (int)data_temp);
 | 
						|
        data_square = (int64_t)data_temp * (int64_t)data_temp;
 | 
						|
        data_temp = IOT_ABS((int)cal[index_max + 1]);
 | 
						|
        iot_printf("imaginary part:%d\n\t", (int)data_temp);
 | 
						|
        data_square += (int64_t)data_temp * (int64_t)data_temp;
 | 
						|
        data_temp = iot_math_sqrt(data_square);
 | 
						|
        data_standard = data_temp * 5 / 10000;
 | 
						|
        iot_printf("square:(0x%x%08x) sqrt:%d, standard:%d\n",(int)(data_square >> 32),
 | 
						|
            (int)(data_square & 0xffffffff), data_temp, data_standard);
 | 
						|
 | 
						|
        for (i = 0; i < size; i++) {
 | 
						|
            data_cal = (int)cal[i];
 | 
						|
            data_exp = (int)expect[i];
 | 
						|
            data_delta = (data_cal > data_exp) ? (data_cal - data_exp) : (data_exp - data_cal);
 | 
						|
#if DTEST_FFT_COMPARE_DEBUG
 | 
						|
            iot_printf("data dump, i:%d, \tcal:%d, \texpect:%d, \tdelta:%d\n",
 | 
						|
                i, data_cal, data_exp, data_delta);
 | 
						|
#endif
 | 
						|
            if (data_delta > data_standard) {
 | 
						|
                err_cnt++;
 | 
						|
            }
 | 
						|
        }
 | 
						|
    } else {
 | 
						|
        float data_max = 0.0, data_temp;
 | 
						|
        double data_square;
 | 
						|
        float data_cal, data_exp, data_delta, data_standard;
 | 
						|
        float *p_cal = (float *)cal, *p_expect = (float *)expect;
 | 
						|
 | 
						|
        /* get max data */
 | 
						|
        for (i = 0; i < size; i++) {
 | 
						|
            data_temp = IOT_ABS(p_cal[i]);
 | 
						|
            if (data_temp >= data_max) {
 | 
						|
#if DTEST_FFT_COMPARE_DEBUG
 | 
						|
                iot_printf("find bigger float data:%f, index:%d\n", data_temp, i);
 | 
						|
#endif
 | 
						|
                index_max = i;
 | 
						|
                data_max = data_temp;
 | 
						|
            }
 | 
						|
        }
 | 
						|
        index_max = (index_max % 2) ? (index_max - 1) : index_max;
 | 
						|
        /* calculate sqrt root */
 | 
						|
        data_temp = IOT_ABS(p_cal[index_max]);
 | 
						|
        iot_printf("get max data index:%d, real part:%f, ", index_max, data_temp);
 | 
						|
        data_square = data_temp * data_temp;
 | 
						|
        data_temp = IOT_ABS(p_cal[index_max + 1]);
 | 
						|
        iot_printf("imaginary part:%f\n\t", data_temp);
 | 
						|
        data_square += data_temp * data_temp;
 | 
						|
        data_temp = (float)dtest_fft_sqrt_double(data_square);
 | 
						|
        data_standard = data_temp * 5 / 10000;
 | 
						|
        iot_printf("square:%lf sqrt:%f, standard:%f\n", data_square, data_temp, data_standard);
 | 
						|
 | 
						|
        for (i = 0; i < size; i++) {
 | 
						|
            data_cal = p_cal[i];
 | 
						|
            data_exp = p_expect[i];
 | 
						|
            data_delta = (data_cal > data_exp) ? (data_cal - data_exp) : (data_exp - data_cal);
 | 
						|
#if DTEST_FFT_COMPARE_DEBUG
 | 
						|
            iot_printf("data dump, i:%d, \tcal:%f, \texpect:%f, \tdelta:%f\n",
 | 
						|
                i, data_cal, data_exp, data_delta);
 | 
						|
#endif
 | 
						|
            if (data_delta > data_standard) {
 | 
						|
                err_cnt++;
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    iot_printf("compare data complete - %d/%d\n", err_cnt, size);
 | 
						|
    if(err_cnt) {
 | 
						|
        return ERR_FAIL;
 | 
						|
    } else {
 | 
						|
        return ERR_OK;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
#if 0
 | 
						|
static uint32_t time_s, time_e, time_d;
 | 
						|
static uint32_t result[DTEST_FFT_DATA_LEN_MAX] = {0};
 | 
						|
 | 
						|
static uint32_t dtest_fft_real_fft_64_test()
 | 
						|
{
 | 
						|
    dcase_start("real fft 64\n");
 | 
						|
 | 
						|
    os_mem_set(result, 0x00, sizeof(result));
 | 
						|
    time_s = gp_timer_get_current_val(0);
 | 
						|
    iot_afft_real_fft(result, (uint32_t*)dtest_fft_data_input_real_64, 64, AFFT_FMT_KL3_32BIT, AFFT_REAL_64, 1, 0, 0);
 | 
						|
    time_e = gp_timer_get_current_val(0);
 | 
						|
 | 
						|
    time_d = (time_e > time_s) ? (time_e - time_s) : (0xffffffff - time_s + time_e);
 | 
						|
    dprintf("real fft calculate complete, time %d us\n", time_d);
 | 
						|
 | 
						|
    if (dtest_fft_result_compare(result, (uint32_t *)dtest_fft_data_output_real_64, 64) != ERR_OK) {
 | 
						|
        dcase_failed();
 | 
						|
        return ERR_FAIL;
 | 
						|
    } else {
 | 
						|
        dcase_success();
 | 
						|
        return ERR_OK;
 | 
						|
    }
 | 
						|
}
 | 
						|
#endif
 | 
						|
 | 
						|
static uint32_t dtest_fft_test_com(DTEST_FFT_MODE_E mode, DTEST_FFT_SIZE_E size)
 | 
						|
{
 | 
						|
    uint32_t t_s_1, t_e_1, t_d_1, t_s_2, t_e_2, t_d_2, compare_result;
 | 
						|
    uint32_t result[DTEST_FFT_DATA_LEN_MAX] = {0};
 | 
						|
 | 
						|
    uint8_t fft_bit_cfg = AFFT_FMT_KL3_32BIT;
 | 
						|
    char ay_name[DTEST_FFT_MODE_MAX][32] = {"real fft", "real ifft", "complex fft", "complex ifft",
 | 
						|
        "float real fft", "float real ifft", "float complex fft", "float complex ifft"};
 | 
						|
    uint32_t ay_size[DTEST_FFT_SIZE_MAX] = {32, 64, 128, 256, 512, 1024, 2048};
 | 
						|
    /* The order of enumeration values in the adapter driver */
 | 
						|
    uint8_t ay_cfg_mode[4][DTEST_FFT_SIZE_MAX] = {
 | 
						|
        {0, AFFT_REAL_64, AFFT_REAL_128, AFFT_REAL_256, AFFT_REAL_512, AFFT_REAL_1024, AFFT_REAL_2048},
 | 
						|
        {AFFT_COMPLEX_32, AFFT_COMPLEX_64, AFFT_COMPLEX_128, AFFT_COMPLEX_256, AFFT_COMPLEX_512, AFFT_COMPLEX_1024, 0},
 | 
						|
        {0, AFFT_REAL_64, AFFT_REAL_128, AFFT_REAL_256, AFFT_REAL_512, AFFT_REAL_1024, AFFT_REAL_2048},
 | 
						|
        {AFFT_COMPLEX_32, AFFT_COMPLEX_64, AFFT_COMPLEX_128, AFFT_COMPLEX_256, AFFT_COMPLEX_512, AFFT_COMPLEX_1024, 0},
 | 
						|
    };
 | 
						|
    /* size0: 256r 128c,
 | 
						|
     * size1: 512r 256c,
 | 
						|
     * size2:1024r 512c,
 | 
						|
     * size3: 2048r 1024c,
 | 
						|
     * size4: 64r 32c,
 | 
						|
     * size5: 128r 64c */
 | 
						|
    uint32_t *ay_inbuf_ptr[DTEST_FFT_MODE_MAX][DTEST_FFT_SIZE_MAX] = {
 | 
						|
        /* real fft\ifft data */
 | 
						|
        {NULL, fft_size4_r_in, fft_size5_r_in, fft_size0_r_in, fft_size1_r_in, fft_size2_r_in, fft_size3_r_in},
 | 
						|
        {NULL, ifft_size4_r_in, ifft_size5_r_in, ifft_size0_r_in, ifft_size1_r_in, ifft_size2_r_in, ifft_size3_r_in},
 | 
						|
        /* complex fft\ifft data */
 | 
						|
        {fft_size4_c_in, fft_size5_c_in, fft_size0_c_in, fft_size1_c_in, fft_size2_c_in, fft_size3_c_in, NULL},
 | 
						|
        {ifft_size4_c_in, ifft_size5_c_in, ifft_size0_c_in, ifft_size1_c_in, ifft_size2_c_in, ifft_size3_c_in, NULL},
 | 
						|
        /* float real fft\ifft data */
 | 
						|
        {NULL, (uint32_t*)f_fft_size4_r_in, (uint32_t*)f_fft_size5_r_in, (uint32_t*)f_fft_size0_r_in,
 | 
						|
            (uint32_t*)f_fft_size1_r_in, (uint32_t*)f_fft_size2_r_in, (uint32_t*)f_fft_size3_r_in},
 | 
						|
        {NULL, (uint32_t*)f_ifft_size4_r_in, (uint32_t*)f_ifft_size5_r_in, (uint32_t*)f_ifft_size0_r_in,
 | 
						|
            (uint32_t*)f_ifft_size1_r_in, (uint32_t*)f_ifft_size2_r_in, (uint32_t*)f_ifft_size3_r_in},
 | 
						|
        /* float complex fft\ifft data */
 | 
						|
        {(uint32_t*)f_fft_size4_c_in, (uint32_t*)f_fft_size5_c_in, (uint32_t*)f_fft_size0_c_in,
 | 
						|
            (uint32_t*)f_fft_size1_c_in, (uint32_t*)f_fft_size2_c_in, (uint32_t*)f_fft_size3_c_in, NULL},
 | 
						|
        {(uint32_t*)f_ifft_size4_c_in, (uint32_t*)f_ifft_size5_c_in, (uint32_t*)f_ifft_size0_c_in,
 | 
						|
            (uint32_t*)f_ifft_size1_c_in, (uint32_t*)f_ifft_size2_c_in, (uint32_t*)f_ifft_size3_c_in, NULL},
 | 
						|
    };
 | 
						|
    uint32_t *ay_outbuf_ptr[DTEST_FFT_MODE_MAX][DTEST_FFT_SIZE_MAX] = {
 | 
						|
        /* real fft\ifft data */
 | 
						|
        {NULL, fft_size4_r_out, fft_size5_r_out, fft_size0_r_out, fft_size1_r_out, fft_size2_r_out, fft_size3_r_out},
 | 
						|
        {NULL, ifft_size4_r_out, ifft_size5_r_out, ifft_size0_r_out, ifft_size1_r_out, ifft_size2_r_out, ifft_size3_r_out},
 | 
						|
        /* complex fft\ifft data */
 | 
						|
        {fft_size4_c_out, fft_size5_c_out, fft_size0_c_out, fft_size1_c_out, fft_size2_c_out, fft_size3_c_out, NULL},
 | 
						|
        {ifft_size4_c_out, ifft_size5_c_out, ifft_size0_c_out, ifft_size1_c_out, ifft_size2_c_out, ifft_size3_c_out, NULL},
 | 
						|
        /* float real fft\ifft data */
 | 
						|
        {NULL, (uint32_t*)f_fft_size4_r_out, (uint32_t*)f_fft_size5_r_out, (uint32_t*)f_fft_size0_r_out,
 | 
						|
            (uint32_t*)f_fft_size1_r_out, (uint32_t*)f_fft_size2_r_out, (uint32_t*)f_fft_size3_r_out},
 | 
						|
        {NULL, (uint32_t*)f_ifft_size4_r_out, (uint32_t*)f_ifft_size5_r_out, (uint32_t*)f_ifft_size0_r_out,
 | 
						|
            (uint32_t*)f_ifft_size1_r_out, (uint32_t*)f_ifft_size2_r_out, (uint32_t*)f_ifft_size3_r_out},
 | 
						|
        /* complex fft\ifft data */
 | 
						|
        {(uint32_t*)f_fft_size4_c_out, (uint32_t*)f_fft_size5_c_out, (uint32_t*)f_fft_size0_c_out,
 | 
						|
            (uint32_t*)f_fft_size1_c_out, (uint32_t*)f_fft_size2_c_out, (uint32_t*)f_fft_size3_c_out, NULL},
 | 
						|
        {(uint32_t*)f_ifft_size4_c_out, (uint32_t*)f_ifft_size5_c_out, (uint32_t*)f_ifft_size0_c_out,
 | 
						|
            (uint32_t*)f_ifft_size1_c_out, (uint32_t*)f_ifft_size2_c_out, (uint32_t*)f_ifft_size3_c_out, NULL},
 | 
						|
    };
 | 
						|
    (void)ay_name;
 | 
						|
    (void)t_d_1;
 | 
						|
    (void)t_d_2;
 | 
						|
 | 
						|
    if (mode >= DTEST_FFT_MODE_MAX || size >= DTEST_FFT_SIZE_MAX) {
 | 
						|
        dprintf("parameter error, mode:%d, size:%d\n", mode, size);
 | 
						|
        return ERR_FAIL;
 | 
						|
    }
 | 
						|
    dprintf("%s, size:%d\n", ay_name[mode], ay_size[size]);
 | 
						|
 | 
						|
    if (mode >= DTEST_FFT_MODE_FLOAT_REAL_FFT) {
 | 
						|
        fft_bit_cfg = AFFT_FMT_KL3_FLOAT_32BIT;
 | 
						|
    }
 | 
						|
 | 
						|
    t_s_1 = gp_timer_get_current_val(0);
 | 
						|
    os_mem_set(result, 0x00, sizeof(result));
 | 
						|
 | 
						|
    t_s_2 = gp_timer_get_current_val(0);
 | 
						|
    switch (mode) {
 | 
						|
    case DTEST_FFT_MODE_REAL_FFT:
 | 
						|
    case DTEST_FFT_MODE_FLOAT_REAL_FFT:
 | 
						|
        iot_afft_real_fft(result, ay_inbuf_ptr[mode][size], ay_size[size],
 | 
						|
            fft_bit_cfg, ay_cfg_mode[mode / 2][size], 1, 0, 0);
 | 
						|
        break;
 | 
						|
    case DTEST_FFT_MODE_REAL_IFFT:
 | 
						|
    case DTEST_FFT_MODE_FLOAT_REAL_IFFT:
 | 
						|
        iot_afft_real_ifft(result, ay_inbuf_ptr[mode][size], ay_size[size],
 | 
						|
            fft_bit_cfg, ay_cfg_mode[mode / 2][size], 1, 0, 0);
 | 
						|
        break;
 | 
						|
    case DTEST_FFT_MODE_COMPLEX_FFT:
 | 
						|
    case DTEST_FFT_MODE_FLOAT_COMPLEX_FFT:
 | 
						|
        iot_afft_complex_fft(result, ay_inbuf_ptr[mode][size], ay_size[size],
 | 
						|
            fft_bit_cfg, ay_cfg_mode[mode / 2][size], 1, 0, 0);
 | 
						|
        break;
 | 
						|
    case DTEST_FFT_MODE_COMPLEX_IFFT:
 | 
						|
    case DTEST_FFT_MODE_FLOAT_COMPLEX_IFFT:
 | 
						|
        iot_afft_complex_ifft(result, ay_inbuf_ptr[mode][size], ay_size[size],
 | 
						|
            fft_bit_cfg, ay_cfg_mode[mode / 2][size], 1, 0, 0);
 | 
						|
        break;
 | 
						|
    default:
 | 
						|
        IOT_ASSERT(0);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    t_e_2 = gp_timer_get_current_val(0);
 | 
						|
 | 
						|
    compare_result = dtest_fft_result_compare(result, ay_outbuf_ptr[mode][size], ay_size[size], mode);
 | 
						|
    t_e_1 = gp_timer_get_current_val(0);
 | 
						|
 | 
						|
    t_d_1 = (t_e_1 > t_s_1) ? (t_e_1 - t_s_1) : (0xffffffff - t_s_1 + t_e_1);
 | 
						|
    t_d_2 = (t_e_2 > t_s_2) ? (t_e_2 - t_s_2) : (0xffffffff - t_s_2 + t_e_2);
 | 
						|
    dprintf("real fft calculate complete, time fft:%dus, total:%dus\n", t_d_2, t_d_1);
 | 
						|
 | 
						|
    if (compare_result != ERR_OK) {
 | 
						|
        return ERR_FAIL;
 | 
						|
    } else {
 | 
						|
        return ERR_OK;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
static uint32_t dtest_fft_real_fft_test()
 | 
						|
{
 | 
						|
    dcase_start("real fft\n");
 | 
						|
 | 
						|
    if (dtest_fft_test_com(DTEST_FFT_MODE_REAL_FFT, DTEST_FFT_SIZE_64) != ERR_OK) {
 | 
						|
        goto fail;
 | 
						|
    }
 | 
						|
 | 
						|
    if (dtest_fft_test_com(DTEST_FFT_MODE_REAL_FFT, DTEST_FFT_SIZE_128) != ERR_OK) {
 | 
						|
        goto fail;
 | 
						|
    }
 | 
						|
 | 
						|
    if (dtest_fft_test_com(DTEST_FFT_MODE_REAL_FFT, DTEST_FFT_SIZE_256) != ERR_OK) {
 | 
						|
        goto fail;
 | 
						|
    }
 | 
						|
 | 
						|
    if (dtest_fft_test_com(DTEST_FFT_MODE_REAL_FFT, DTEST_FFT_SIZE_512) != ERR_OK) {
 | 
						|
        goto fail;
 | 
						|
    }
 | 
						|
 | 
						|
    if (dtest_fft_test_com(DTEST_FFT_MODE_REAL_FFT, DTEST_FFT_SIZE_1024) != ERR_OK) {
 | 
						|
        goto fail;
 | 
						|
    }
 | 
						|
 | 
						|
    if (dtest_fft_test_com(DTEST_FFT_MODE_REAL_FFT, DTEST_FFT_SIZE_2048) != ERR_OK) {
 | 
						|
        goto fail;
 | 
						|
    }
 | 
						|
 | 
						|
    dcase_success();
 | 
						|
    return ERR_OK;
 | 
						|
fail:
 | 
						|
    dcase_failed();
 | 
						|
    return ERR_FAIL;
 | 
						|
}
 | 
						|
 | 
						|
static uint32_t dtest_fft_real_ifft_test()
 | 
						|
{
 | 
						|
    dcase_start("real ifft\n");
 | 
						|
 | 
						|
    if (dtest_fft_test_com(DTEST_FFT_MODE_REAL_IFFT, DTEST_FFT_SIZE_64) != ERR_OK) {
 | 
						|
        goto fail;
 | 
						|
    }
 | 
						|
 | 
						|
    if (dtest_fft_test_com(DTEST_FFT_MODE_REAL_IFFT, DTEST_FFT_SIZE_128) != ERR_OK) {
 | 
						|
        goto fail;
 | 
						|
    }
 | 
						|
 | 
						|
    if (dtest_fft_test_com(DTEST_FFT_MODE_REAL_IFFT, DTEST_FFT_SIZE_256) != ERR_OK) {
 | 
						|
        goto fail;
 | 
						|
    }
 | 
						|
 | 
						|
    if (dtest_fft_test_com(DTEST_FFT_MODE_REAL_IFFT, DTEST_FFT_SIZE_512) != ERR_OK) {
 | 
						|
        goto fail;
 | 
						|
    }
 | 
						|
 | 
						|
    if (dtest_fft_test_com(DTEST_FFT_MODE_REAL_IFFT, DTEST_FFT_SIZE_1024) != ERR_OK) {
 | 
						|
        goto fail;
 | 
						|
    }
 | 
						|
 | 
						|
    if (dtest_fft_test_com(DTEST_FFT_MODE_REAL_IFFT, DTEST_FFT_SIZE_2048) != ERR_OK) {
 | 
						|
        goto fail;
 | 
						|
    }
 | 
						|
 | 
						|
    dcase_success();
 | 
						|
    return ERR_OK;
 | 
						|
fail:
 | 
						|
    dcase_failed();
 | 
						|
    return ERR_FAIL;
 | 
						|
}
 | 
						|
 | 
						|
static uint32_t dtest_fft_complex_fft_test()
 | 
						|
{
 | 
						|
    dcase_start("complex fft\n");
 | 
						|
 | 
						|
    if (dtest_fft_test_com(DTEST_FFT_MODE_COMPLEX_FFT, DTEST_FFT_SIZE_32) != ERR_OK) {
 | 
						|
        goto fail;
 | 
						|
    }
 | 
						|
 | 
						|
    if (dtest_fft_test_com(DTEST_FFT_MODE_COMPLEX_FFT, DTEST_FFT_SIZE_64) != ERR_OK) {
 | 
						|
        goto fail;
 | 
						|
    }
 | 
						|
 | 
						|
    if (dtest_fft_test_com(DTEST_FFT_MODE_COMPLEX_FFT, DTEST_FFT_SIZE_128) != ERR_OK) {
 | 
						|
        goto fail;
 | 
						|
    }
 | 
						|
 | 
						|
    if (dtest_fft_test_com(DTEST_FFT_MODE_COMPLEX_FFT, DTEST_FFT_SIZE_256) != ERR_OK) {
 | 
						|
        goto fail;
 | 
						|
    }
 | 
						|
 | 
						|
    if (dtest_fft_test_com(DTEST_FFT_MODE_COMPLEX_FFT, DTEST_FFT_SIZE_512) != ERR_OK) {
 | 
						|
        goto fail;
 | 
						|
    }
 | 
						|
 | 
						|
    if (dtest_fft_test_com(DTEST_FFT_MODE_COMPLEX_FFT, DTEST_FFT_SIZE_1024) != ERR_OK) {
 | 
						|
        goto fail;
 | 
						|
    }
 | 
						|
 | 
						|
    dcase_success();
 | 
						|
    return ERR_OK;
 | 
						|
fail:
 | 
						|
    dcase_failed();
 | 
						|
    return ERR_FAIL;
 | 
						|
}
 | 
						|
 | 
						|
static uint32_t dtest_fft_complex_ifft_test()
 | 
						|
{
 | 
						|
    dcase_start("complex ifft\n");
 | 
						|
 | 
						|
    if (dtest_fft_test_com(DTEST_FFT_MODE_COMPLEX_IFFT, DTEST_FFT_SIZE_32) != ERR_OK) {
 | 
						|
        goto fail;
 | 
						|
    }
 | 
						|
 | 
						|
    if (dtest_fft_test_com(DTEST_FFT_MODE_COMPLEX_IFFT, DTEST_FFT_SIZE_64) != ERR_OK) {
 | 
						|
        goto fail;
 | 
						|
    }
 | 
						|
 | 
						|
    if (dtest_fft_test_com(DTEST_FFT_MODE_COMPLEX_IFFT, DTEST_FFT_SIZE_128) != ERR_OK) {
 | 
						|
        goto fail;
 | 
						|
    }
 | 
						|
 | 
						|
    if (dtest_fft_test_com(DTEST_FFT_MODE_COMPLEX_IFFT, DTEST_FFT_SIZE_256) != ERR_OK) {
 | 
						|
        goto fail;
 | 
						|
    }
 | 
						|
 | 
						|
    if (dtest_fft_test_com(DTEST_FFT_MODE_COMPLEX_IFFT, DTEST_FFT_SIZE_512) != ERR_OK) {
 | 
						|
        goto fail;
 | 
						|
    }
 | 
						|
 | 
						|
    if (dtest_fft_test_com(DTEST_FFT_MODE_COMPLEX_IFFT, DTEST_FFT_SIZE_1024) != ERR_OK) {
 | 
						|
        goto fail;
 | 
						|
    }
 | 
						|
 | 
						|
    dcase_success();
 | 
						|
    return ERR_OK;
 | 
						|
fail:
 | 
						|
    dcase_failed();
 | 
						|
    return ERR_FAIL;
 | 
						|
}
 | 
						|
 | 
						|
static uint32_t dtest_fft_float_real_fft_test()
 | 
						|
{
 | 
						|
    dcase_start("float real fft\n");
 | 
						|
 | 
						|
    if (dtest_fft_test_com(DTEST_FFT_MODE_FLOAT_REAL_FFT, DTEST_FFT_SIZE_64) != ERR_OK) {
 | 
						|
        goto fail;
 | 
						|
    }
 | 
						|
 | 
						|
    if (dtest_fft_test_com(DTEST_FFT_MODE_FLOAT_REAL_FFT, DTEST_FFT_SIZE_128) != ERR_OK) {
 | 
						|
        goto fail;
 | 
						|
    }
 | 
						|
 | 
						|
    if (dtest_fft_test_com(DTEST_FFT_MODE_FLOAT_REAL_FFT, DTEST_FFT_SIZE_256) != ERR_OK) {
 | 
						|
        goto fail;
 | 
						|
    }
 | 
						|
 | 
						|
    if (dtest_fft_test_com(DTEST_FFT_MODE_FLOAT_REAL_FFT, DTEST_FFT_SIZE_512) != ERR_OK) {
 | 
						|
        goto fail;
 | 
						|
    }
 | 
						|
 | 
						|
    if (dtest_fft_test_com(DTEST_FFT_MODE_FLOAT_REAL_FFT, DTEST_FFT_SIZE_1024) != ERR_OK) {
 | 
						|
        goto fail;
 | 
						|
    }
 | 
						|
 | 
						|
    if (dtest_fft_test_com(DTEST_FFT_MODE_FLOAT_REAL_FFT, DTEST_FFT_SIZE_2048) != ERR_OK) {
 | 
						|
        goto fail;
 | 
						|
    }
 | 
						|
 | 
						|
    dcase_success();
 | 
						|
    return ERR_OK;
 | 
						|
fail:
 | 
						|
    dcase_failed();
 | 
						|
    return ERR_FAIL;
 | 
						|
}
 | 
						|
 | 
						|
static uint32_t dtest_fft_float_real_ifft_test()
 | 
						|
{
 | 
						|
    dcase_start("float real ifft\n");
 | 
						|
 | 
						|
    if (dtest_fft_test_com(DTEST_FFT_MODE_FLOAT_REAL_IFFT, DTEST_FFT_SIZE_64) != ERR_OK) {
 | 
						|
        goto fail;
 | 
						|
    }
 | 
						|
 | 
						|
    if (dtest_fft_test_com(DTEST_FFT_MODE_FLOAT_REAL_IFFT, DTEST_FFT_SIZE_128) != ERR_OK) {
 | 
						|
        goto fail;
 | 
						|
    }
 | 
						|
 | 
						|
    if (dtest_fft_test_com(DTEST_FFT_MODE_FLOAT_REAL_IFFT, DTEST_FFT_SIZE_256) != ERR_OK) {
 | 
						|
        goto fail;
 | 
						|
    }
 | 
						|
 | 
						|
    if (dtest_fft_test_com(DTEST_FFT_MODE_FLOAT_REAL_IFFT, DTEST_FFT_SIZE_512) != ERR_OK) {
 | 
						|
        goto fail;
 | 
						|
    }
 | 
						|
 | 
						|
    if (dtest_fft_test_com(DTEST_FFT_MODE_FLOAT_REAL_IFFT, DTEST_FFT_SIZE_1024) != ERR_OK) {
 | 
						|
        goto fail;
 | 
						|
    }
 | 
						|
 | 
						|
    if (dtest_fft_test_com(DTEST_FFT_MODE_FLOAT_REAL_IFFT, DTEST_FFT_SIZE_2048) != ERR_OK) {
 | 
						|
        goto fail;
 | 
						|
    }
 | 
						|
 | 
						|
    dcase_success();
 | 
						|
    return ERR_OK;
 | 
						|
fail:
 | 
						|
    dcase_failed();
 | 
						|
    return ERR_FAIL;
 | 
						|
}
 | 
						|
 | 
						|
static uint32_t dtest_fft_float_complex_fft_test()
 | 
						|
{
 | 
						|
    dcase_start("float complex fft\n");
 | 
						|
 | 
						|
    if (dtest_fft_test_com(DTEST_FFT_MODE_FLOAT_COMPLEX_FFT, DTEST_FFT_SIZE_32) != ERR_OK) {
 | 
						|
        goto fail;
 | 
						|
    }
 | 
						|
 | 
						|
    if (dtest_fft_test_com(DTEST_FFT_MODE_FLOAT_COMPLEX_FFT, DTEST_FFT_SIZE_64) != ERR_OK) {
 | 
						|
        goto fail;
 | 
						|
    }
 | 
						|
 | 
						|
    if (dtest_fft_test_com(DTEST_FFT_MODE_FLOAT_COMPLEX_FFT, DTEST_FFT_SIZE_128) != ERR_OK) {
 | 
						|
        goto fail;
 | 
						|
    }
 | 
						|
 | 
						|
    if (dtest_fft_test_com(DTEST_FFT_MODE_FLOAT_COMPLEX_FFT, DTEST_FFT_SIZE_256) != ERR_OK) {
 | 
						|
        goto fail;
 | 
						|
    }
 | 
						|
 | 
						|
    if (dtest_fft_test_com(DTEST_FFT_MODE_FLOAT_COMPLEX_FFT, DTEST_FFT_SIZE_512) != ERR_OK) {
 | 
						|
        goto fail;
 | 
						|
    }
 | 
						|
 | 
						|
    if (dtest_fft_test_com(DTEST_FFT_MODE_FLOAT_COMPLEX_FFT, DTEST_FFT_SIZE_1024) != ERR_OK) {
 | 
						|
        goto fail;
 | 
						|
    }
 | 
						|
 | 
						|
    dcase_success();
 | 
						|
    return ERR_OK;
 | 
						|
fail:
 | 
						|
    dcase_failed();
 | 
						|
    return ERR_FAIL;
 | 
						|
}
 | 
						|
 | 
						|
static uint32_t dtest_fft_float_complex_ifft_test()
 | 
						|
{
 | 
						|
    dcase_start("float complex ifft\n");
 | 
						|
 | 
						|
    if (dtest_fft_test_com(DTEST_FFT_MODE_FLOAT_COMPLEX_IFFT, DTEST_FFT_SIZE_32) != ERR_OK) {
 | 
						|
        goto fail;
 | 
						|
    }
 | 
						|
 | 
						|
    if (dtest_fft_test_com(DTEST_FFT_MODE_FLOAT_COMPLEX_IFFT, DTEST_FFT_SIZE_64) != ERR_OK) {
 | 
						|
        goto fail;
 | 
						|
    }
 | 
						|
 | 
						|
    if (dtest_fft_test_com(DTEST_FFT_MODE_FLOAT_COMPLEX_IFFT, DTEST_FFT_SIZE_128) != ERR_OK) {
 | 
						|
        goto fail;
 | 
						|
    }
 | 
						|
 | 
						|
    if (dtest_fft_test_com(DTEST_FFT_MODE_FLOAT_COMPLEX_IFFT, DTEST_FFT_SIZE_256) != ERR_OK) {
 | 
						|
        goto fail;
 | 
						|
    }
 | 
						|
 | 
						|
    if (dtest_fft_test_com(DTEST_FFT_MODE_FLOAT_COMPLEX_IFFT, DTEST_FFT_SIZE_512) != ERR_OK) {
 | 
						|
        goto fail;
 | 
						|
    }
 | 
						|
 | 
						|
    if (dtest_fft_test_com(DTEST_FFT_MODE_FLOAT_COMPLEX_IFFT, DTEST_FFT_SIZE_1024) != ERR_OK) {
 | 
						|
        goto fail;
 | 
						|
    }
 | 
						|
 | 
						|
    dcase_success();
 | 
						|
    return ERR_OK;
 | 
						|
fail:
 | 
						|
    dcase_failed();
 | 
						|
    return ERR_FAIL;
 | 
						|
}
 | 
						|
 | 
						|
static uint8_t g_fft_interrupt_trig = 0;
 | 
						|
static iot_irq_t g_fft_irq;
 | 
						|
static uint32_t g_result[DTEST_FFT_DATA_LEN_MAX] = {0};
 | 
						|
uint32_t dtest_fft_interrupt_handle(uint32_t vector, iot_addrword_t data)
 | 
						|
{
 | 
						|
    dprintf("init trig, data:0x%08x, result:%p\n", data, g_result);
 | 
						|
 | 
						|
    if (vector != HAL_VECTOR_FFT) {
 | 
						|
        dprintf("interrupt vector error(%d- %d)\n", vector, HAL_VECTOR_FFT);
 | 
						|
        IOT_ASSERT(0);
 | 
						|
    }
 | 
						|
 | 
						|
    if (data != (iot_addrword_t)g_result) {
 | 
						|
        dprintf("interrupt param error\n");
 | 
						|
        IOT_ASSERT(0);
 | 
						|
    }
 | 
						|
 | 
						|
    uint32_t state = afft_interrupt_state_get();
 | 
						|
    uint32_t done = afft_get_done_bit();
 | 
						|
    (void)state;
 | 
						|
    (void)done;
 | 
						|
    dprintf("after fft cal, interrupt state:%d, done:%d\n", state, done);
 | 
						|
    if (state != 1 || done != 1) {
 | 
						|
        dprintf("fft status error\n");
 | 
						|
        IOT_ASSERT(0);
 | 
						|
    }
 | 
						|
 | 
						|
    afft_interrupt_state_clear();
 | 
						|
    afft_clr_done_bit();
 | 
						|
 | 
						|
    if (dtest_fft_result_compare(g_result, fft_size4_r_out, 64,
 | 
						|
        DTEST_FFT_MODE_REAL_FFT) == ERR_OK) {
 | 
						|
        g_fft_interrupt_trig = 1;
 | 
						|
    }
 | 
						|
 | 
						|
    return 0;
 | 
						|
}
 | 
						|
 | 
						|
static uint32_t dtest_fft_interrupt_test()
 | 
						|
{
 | 
						|
    uint32_t t_s, t_e, t_d;
 | 
						|
 | 
						|
    dcase_start("fft interrupt\n");
 | 
						|
 | 
						|
    /* reset fft module */
 | 
						|
 | 
						|
    /* clear interrupt state, and enable interrupt function */
 | 
						|
    afft_interrupt_enable(1);
 | 
						|
    uint32_t state = afft_interrupt_state_get();
 | 
						|
    uint32_t done = afft_get_done_bit();
 | 
						|
    (void)state;
 | 
						|
    (void)done;
 | 
						|
    dprintf("before fft cal, interrupt state:%d, done:%d\n", state, done);
 | 
						|
    afft_interrupt_state_clear();
 | 
						|
    afft_clr_done_bit();
 | 
						|
 | 
						|
    /* enable fft core interrupt */
 | 
						|
    g_fft_irq = iot_interrupt_create(HAL_VECTOR_FFT, HAL_INTR_PRI_5,
 | 
						|
        (iot_addrword_t)g_result, dtest_fft_interrupt_handle);
 | 
						|
    iot_interrupt_attach(g_fft_irq);
 | 
						|
    iot_interrupt_unmask(g_fft_irq);
 | 
						|
 | 
						|
    /* fft cal */
 | 
						|
    afft_cfg(AFFT_OP_FFT, AFFT_FMT_KL3_32BIT, AFFT_DATA_REAL, AFFT_REAL_64, 1, 0, 0);
 | 
						|
    afft_data_trans(fft_size4_r_in, 64, AFFT_BUF_INPUT, g_result);
 | 
						|
    afft_start();
 | 
						|
 | 
						|
    /* wait interrupt */
 | 
						|
    t_s = gp_timer_get_current_val(0);
 | 
						|
    dprintf("wait fft complete interrupt, start time:%d\n", t_s);
 | 
						|
    while (!g_fft_interrupt_trig) {
 | 
						|
        t_e = gp_timer_get_current_val(0);
 | 
						|
        t_d = (t_e > t_s) ? (t_e - t_s) : (0xffffffff - t_s + t_e);
 | 
						|
        if (t_d > 10000000) {    //1s
 | 
						|
            dprintf("fft interrupt timeout, use time:%d\n", t_d);
 | 
						|
            dcase_failed();
 | 
						|
            return ERR_FAIL;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    t_e = gp_timer_get_current_val(0);
 | 
						|
    t_d = (t_e > t_s) ? (t_e - t_s) : (0xffffffff - t_s + t_e);
 | 
						|
    dprintf("fft interupt compare complete, use time:%d\n", t_d);
 | 
						|
    dcase_success();
 | 
						|
    return ERR_OK;
 | 
						|
}
 | 
						|
 | 
						|
static void dtest_fft_main()
 | 
						|
{
 | 
						|
    uint32_t case_group = 0, failed_cnt = 0;
 | 
						|
    (void)case_group;
 | 
						|
 | 
						|
    dbg_uart_init();
 | 
						|
 | 
						|
    dconfig();
 | 
						|
    dstart();
 | 
						|
    dversion();
 | 
						|
 | 
						|
    if (dtest_get_case_group(&case_group) < 0) {
 | 
						|
        case_group = 0xffffffff;
 | 
						|
    }
 | 
						|
    dprintf("get case group:0x%08X\n", case_group);
 | 
						|
 | 
						|
    gp_timer_init();
 | 
						|
    gp_timer_set(0, 0xffffffff, 0);
 | 
						|
    gp_timer_start(0);
 | 
						|
 | 
						|
    iot_afft_init();
 | 
						|
 | 
						|
    if (case_group & DTEST_FFT_CASE_REAL_FFT) {
 | 
						|
        if (dtest_fft_real_fft_test() != ERR_OK) {
 | 
						|
            failed_cnt++;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    if (case_group & DTEST_FFT_CASE_REAL_IFFT) {
 | 
						|
        if (dtest_fft_real_ifft_test() != ERR_OK) {
 | 
						|
            failed_cnt++;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    if (case_group & DTEST_FFT_CASE_COMPLEX_FFT) {
 | 
						|
        if (dtest_fft_complex_fft_test() != ERR_OK) {
 | 
						|
            failed_cnt++;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    if (case_group & DTEST_FFT_CASE_COMPLEX_IFFT) {
 | 
						|
        if (dtest_fft_complex_ifft_test() != ERR_OK) {
 | 
						|
            failed_cnt++;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    if (case_group & DTEST_FFT_CASE_FLOAT_REAL_FFT) {
 | 
						|
        if (dtest_fft_float_real_fft_test() != ERR_OK) {
 | 
						|
            failed_cnt++;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    if (case_group & DTEST_FFT_CASE_FLOAT_REAL_IFFT) {
 | 
						|
        if (dtest_fft_float_real_ifft_test() != ERR_OK) {
 | 
						|
            failed_cnt++;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    if (case_group & DTEST_FFT_CASE_FLOAT_COMPLEX_FFT) {
 | 
						|
        if (dtest_fft_float_complex_fft_test() != ERR_OK) {
 | 
						|
            failed_cnt++;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    if (case_group & DTEST_FFT_CASE_FLOAT_COMPLEX_IFFT) {
 | 
						|
        if (dtest_fft_float_complex_ifft_test() != ERR_OK) {
 | 
						|
            failed_cnt++;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    if (case_group & DTEST_FFT_CASE_COMPLETE_INTERRUPT) {
 | 
						|
        if (dtest_fft_interrupt_test() != ERR_OK) {
 | 
						|
            failed_cnt++;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    if (failed_cnt) {
 | 
						|
        dprintf("fft dtest failed\n");
 | 
						|
    } else {
 | 
						|
        dprintf("fft dtest succeed\n");
 | 
						|
    }
 | 
						|
    dend();
 | 
						|
 | 
						|
    return;
 | 
						|
}
 | 
						|
 | 
						|
int main(void)
 | 
						|
{
 | 
						|
    dtest_fft_main();
 | 
						|
    return 0;
 | 
						|
}
 |