diff --git a/APP_Framework/Applications/knowing_app/Kconfig b/APP_Framework/Applications/knowing_app/Kconfig index 5fa6945be..1387fae5a 100755 --- a/APP_Framework/Applications/knowing_app/Kconfig +++ b/APP_Framework/Applications/knowing_app/Kconfig @@ -9,5 +9,6 @@ menu "knowing app" source "$APP_DIR/Applications/knowing_app/instrusion_detect/Kconfig" source "$APP_DIR/Applications/knowing_app/helmet_detect/Kconfig" source "$APP_DIR/Applications/knowing_app/iris_ml_demo/Kconfig" + source "$APP_DIR/Applications/knowing_app/k210_fft_test/Kconfig" endif endmenu diff --git a/APP_Framework/Applications/knowing_app/k210_fft_test/Kconfig b/APP_Framework/Applications/knowing_app/k210_fft_test/Kconfig new file mode 100644 index 000000000..07605f28d --- /dev/null +++ b/APP_Framework/Applications/knowing_app/k210_fft_test/Kconfig @@ -0,0 +1,3 @@ +config K210_FFT_TEST + bool "enable apps/k210 fft test" + default n diff --git a/APP_Framework/Applications/knowing_app/k210_fft_test/SConscript b/APP_Framework/Applications/knowing_app/k210_fft_test/SConscript new file mode 100644 index 000000000..3027f81e3 --- /dev/null +++ b/APP_Framework/Applications/knowing_app/k210_fft_test/SConscript @@ -0,0 +1,9 @@ +from building import * + +cwd = GetCurrentDir() +src = Glob('*.c') + Glob('*.cpp') +CPPPATH = [cwd] + +group = DefineGroup('Applications', src, depend = ['K210_FFT_TEST'], LOCAL_CPPPATH = CPPPATH) + +Return('group') diff --git a/APP_Framework/Applications/knowing_app/k210_fft_test/fft_soft.c b/APP_Framework/Applications/knowing_app/k210_fft_test/fft_soft.c new file mode 100644 index 000000000..0df966f1a --- /dev/null +++ b/APP_Framework/Applications/knowing_app/k210_fft_test/fft_soft.c @@ -0,0 +1,101 @@ +#include +#include +#include +#include "fft_soft.h" + +#define PI 3.14159265358979323846 +complex add(complex a, complex b) +{ + complex ret = {a.real + b.real, a.imag + b.imag}; + return ret; +} + +complex sub(complex a, complex b) +{ + complex ret = {a.real - b.real, a.imag - b.imag}; + return ret; +} + +complex mul(complex a, complex b) +{ + complex ret = {a.real * b.real - a.imag * b.imag, a.real * b.imag + a.imag * b.real}; + return ret; +} + +void bitrev(complex *data, int n) +{ + int j = 0; + int m = 0; + for (int i = 0; i < n; i++) + { + if (j > i) + SWAP(data[i], data[j]); + m = n / 2; + while (j >= m && m != 0) + { + j -= m; + m >>= 1; + } + j += m; + } +} + +void fft_soft(complex *data, int n) +{ + int M = 0; + for (int i = n; i > 1; i = i >> 1, M++); + + bitrev(data, n); + + for (int m = 0; m < M; m++) + { + int K = n >> (m + 1); + for (int k = 0; k < K; k++) + { + int J = 2 << m; + int base = k * J; + for (int j = 0; j < J / 2; j++) + { + int t = base + j; + complex w = {cos(-2 * PI * j * K / n), sin(-2 * PI * j * K / n)}; + complex wn = mul(data[t + J / 2], w); + complex temp = data[t]; + data[t] = add(data[t], wn); + data[t + J / 2] = sub(temp, wn); + } + } + } +} + +void ifft_soft(complex *data, int n) +{ + int M = 0; + for (int i = n; i > 1; i = i >> 1, M++); + + bitrev(data, n); + + for (int m = 0; m < M; m++) + { + int K = n >> (m + 1); + for (int k = 0; k < K; k++) + { + int J = 2 << m; + int base = k * J; + for (int j = 0; j < J / 2; j++) + { + int t = base + j; + complex w = {cos(2 * PI * j * K / n), sin(2 * PI * j * K / n)}; + complex wn = mul(data[t + J / 2], w); + complex temp = data[t]; + data[t] = add(data[t], wn); + data[t + J / 2] = sub(temp, wn); + } + } + } + + for (int i = 0; i < n; i++) + { + data[i].real /= n; + data[i].imag /= n; + } +} diff --git a/APP_Framework/Applications/knowing_app/k210_fft_test/fft_soft.h b/APP_Framework/Applications/knowing_app/k210_fft_test/fft_soft.h new file mode 100644 index 000000000..c98c980e0 --- /dev/null +++ b/APP_Framework/Applications/knowing_app/k210_fft_test/fft_soft.h @@ -0,0 +1,14 @@ +#ifndef _FFT_SOFT_H +#define _FFT_SOFT_H + +#include + +#define SWAP(a, b) do {complex t = (a); (a) = (b); (b) = t;} while(0) + +typedef struct{double real, imag;} complex; + +void fft_soft(complex *data, int n); +void ifft_soft(complex *data, int n); +void show(complex *data, int n); + +#endif /* _FFT_SOFT_H */ \ No newline at end of file diff --git a/APP_Framework/Applications/knowing_app/k210_fft_test/fft_test.c b/APP_Framework/Applications/knowing_app/k210_fft_test/fft_test.c new file mode 100644 index 000000000..2efe6d95d --- /dev/null +++ b/APP_Framework/Applications/knowing_app/k210_fft_test/fft_test.c @@ -0,0 +1,159 @@ +/* Copyright 2018 Canaan Inc. + * + * 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. + */ +#include +#include +#include "encoding.h" +#include "dmac.h" +#include "fft.h" +#include "encoding.h" +#include "sysctl.h" +#include "fft_soft.h" + +#define FFT_N 512U +#define FFT_FORWARD_SHIFT 0x0U +#define FFT_BACKWARD_SHIFT 0x1ffU +#define PI 3.14159265358979323846 + +typedef enum _complex_mode +{ + FFT_HARD = 0, + FFT_SOFT = 1, + FFT_COMPLEX_MAX, +} complex_mode_t; + +int16_t real[FFT_N]; +int16_t imag[FFT_N]; +float hard_power[FFT_N]; +float soft_power[FFT_N]; +float hard_angel[FFT_N]; +float soft_angel[FFT_N]; +uint64_t fft_out_data[FFT_N / 2]; +uint64_t buffer_input[FFT_N]; +uint64_t buffer_output[FFT_N]; +uint64_t cycle[FFT_COMPLEX_MAX][FFT_DIR_MAX]; + +uint16_t get_bit1_num(uint32_t data) +{ + uint16_t num; + for (num = 0; data; num++) + data &= data - 1; + return num; +} + +void k210_fft_test(void) +{ + int32_t i; + float tempf1[3]; + fft_data_t *output_data; + fft_data_t *input_data; + uint16_t bit1_num = get_bit1_num(FFT_FORWARD_SHIFT); + complex_hard_t data_hard[FFT_N] = {0}; + complex data_soft[FFT_N] = {0}; + for (i = 0; i < FFT_N; i++) + { + tempf1[0] = 0.3 * cosf(2 * PI * i / FFT_N + PI / 3) * 256; + tempf1[1] = 0.1 * cosf(16 * 2 * PI * i / FFT_N - PI / 9) * 256; + tempf1[2] = 0.5 * cosf((19 * 2 * PI * i / FFT_N) + PI / 6) * 256; + data_hard[i].real = (int16_t)(tempf1[0] + tempf1[1] + tempf1[2] + 10); + data_hard[i].imag = (int16_t)0; + data_soft[i].real = data_hard[i].real; + data_soft[i].imag = data_hard[i].imag; + } + for (int i = 0; i < FFT_N / 2; ++i) + { + input_data = (fft_data_t *)&buffer_input[i]; + input_data->R1 = data_hard[2 * i].real; + input_data->I1 = data_hard[2 * i].imag; + input_data->R2 = data_hard[2 * i + 1].real; + input_data->I2 = data_hard[2 * i + 1].imag; + } + cycle[FFT_HARD][FFT_DIR_FORWARD] = read_cycle(); + fft_complex_uint16_dma(DMAC_CHANNEL0, DMAC_CHANNEL1, FFT_FORWARD_SHIFT, FFT_DIR_FORWARD, buffer_input, FFT_N, buffer_output); + cycle[FFT_HARD][FFT_DIR_FORWARD] = read_cycle() - cycle[FFT_HARD][FFT_DIR_FORWARD]; + cycle[FFT_SOFT][FFT_DIR_FORWARD] = read_cycle(); + fft_soft(data_soft, FFT_N); + cycle[FFT_SOFT][FFT_DIR_FORWARD] = read_cycle() - cycle[FFT_SOFT][FFT_DIR_FORWARD]; + for (i = 0; i < FFT_N / 2; i++) + { + output_data = (fft_data_t*)&buffer_output[i]; + data_hard[2 * i].imag = output_data->I1 ; + data_hard[2 * i].real = output_data->R1 ; + data_hard[2 * i + 1].imag = output_data->I2 ; + data_hard[2 * i + 1].real = output_data->R2 ; + } + + for (i = 0; i < FFT_N; i++) + { + hard_power[i] = sqrt(data_hard[i].real * data_hard[i].real + data_hard[i].imag * data_hard[i].imag) * 2; + soft_power[i] = sqrt(data_soft[i].real * data_soft[i].real + data_soft[i].imag * data_soft[i].imag) * 2; + } + + printf("\n[hard fft real][soft fft real][hard fft imag][soft fft imag]\n"); + for (i = 0; i < FFT_N / 2; i++) + printf("%3d:%7d %7d %7d %7d\n", + i, data_hard[i].real, (int32_t)data_soft[i].real, data_hard[i].imag, (int32_t)data_soft[i].imag); + + printf("\nhard power soft power:\n"); + printf("%3d : %f %f\n", 0, hard_power[0] / 2 / FFT_N * (1 << bit1_num), soft_power[0] / 2 / FFT_N); + for (i = 1; i < FFT_N / 2; i++) + printf("%3d : %f %f\n", i, hard_power[i] / FFT_N * (1 << bit1_num), soft_power[i] / FFT_N); + + printf("\nhard phase soft phase:\n"); + for (i = 0; i < FFT_N / 2; i++) + { + hard_angel[i] = atan2(data_hard[i].imag, data_hard[i].real); + soft_angel[i] = atan2(data_soft[i].imag, data_soft[i].real); + printf("%3d : %f %f\n", i, hard_angel[i] * 180 / PI, soft_angel[i] * 180 / PI); + } + + for (int i = 0; i < FFT_N / 2; ++i) + { + input_data = (fft_data_t *)&buffer_input[i]; + input_data->R1 = data_hard[2 * i].real; + input_data->I1 = data_hard[2 * i].imag; + input_data->R2 = data_hard[2 * i + 1].real; + input_data->I2 = data_hard[2 * i + 1].imag; + } + cycle[FFT_HARD][FFT_DIR_BACKWARD] = read_cycle(); + fft_complex_uint16_dma(DMAC_CHANNEL0, DMAC_CHANNEL1, FFT_BACKWARD_SHIFT, FFT_DIR_BACKWARD, buffer_input, FFT_N, buffer_output); + cycle[FFT_HARD][FFT_DIR_BACKWARD] = read_cycle() - cycle[FFT_HARD][FFT_DIR_BACKWARD]; + cycle[FFT_SOFT][FFT_DIR_BACKWARD] = read_cycle(); + ifft_soft(data_soft, FFT_N); + cycle[FFT_SOFT][FFT_DIR_BACKWARD] = read_cycle() - cycle[FFT_SOFT][FFT_DIR_BACKWARD]; + for (i = 0; i < FFT_N / 2; i++) + { + output_data = (fft_data_t*)&buffer_output[i]; + data_hard[2 * i].imag = output_data->I1 ; + data_hard[2 * i].real = output_data->R1 ; + data_hard[2 * i + 1].imag = output_data->I2 ; + data_hard[2 * i + 1].real = output_data->R2 ; + } + printf("\n[hard ifft real][soft ifft real][hard ifft imag][soft ifft imag]\n"); + for (i = 0; i < FFT_N / 2; i++) + printf("%3d:%7d %7d %7d %7d\n", + i, data_hard[i].real, (int32_t)data_soft[i].real, data_hard[i].imag, (int32_t)data_soft[i].imag); + + printf("[hard fft test] [%d bytes] forward time = %ld us, backward time = %ld us\n", + FFT_N, + cycle[FFT_HARD][FFT_DIR_FORWARD]/(sysctl_clock_get_freq(SYSCTL_CLOCK_CPU)/1000000), + cycle[FFT_HARD][FFT_DIR_BACKWARD]/(sysctl_clock_get_freq(SYSCTL_CLOCK_CPU)/1000000)); + printf("[soft fft test] [%d bytes] forward time = %ld us, backward time = %ld us\n", + FFT_N, + cycle[FFT_SOFT][FFT_DIR_FORWARD]/(sysctl_clock_get_freq(SYSCTL_CLOCK_CPU)/1000000), + cycle[FFT_SOFT][FFT_DIR_BACKWARD]/(sysctl_clock_get_freq(SYSCTL_CLOCK_CPU)/1000000)); +} +#ifdef __RT_THREAD_H__ +MSH_CMD_EXPORT(k210_fft_test,k210 fft test ); +#endif \ No newline at end of file diff --git a/Ubiquitous/RT_Thread/bsp/k210/.config b/Ubiquitous/RT_Thread/bsp/k210/.config index c471c072d..e38931055 100644 --- a/Ubiquitous/RT_Thread/bsp/k210/.config +++ b/Ubiquitous/RT_Thread/bsp/k210/.config @@ -12,6 +12,7 @@ CONFIG_BOARD_K210_EVB=y # RT-Thread Kernel # CONFIG_RT_NAME_MAX=8 +# CONFIG_RT_USING_BIG_ENDIAN is not set # CONFIG_RT_USING_ARCH_DATA_TYPE is not set CONFIG_RT_USING_SMP=y CONFIG_RT_CPUS_NR=2 @@ -102,7 +103,8 @@ CONFIG_RT_MAIN_THREAD_PRIORITY=10 # # C++ features # -# CONFIG_RT_USING_CPLUSPLUS is not set +CONFIG_RT_USING_CPLUSPLUS=y +# CONFIG_RT_USING_CPLUSPLUS11 is not set # # Command shell @@ -185,7 +187,9 @@ CONFIG_RT_USING_PIN=y # CONFIG_RT_USING_MTD_NOR is not set # CONFIG_RT_USING_MTD_NAND is not set # CONFIG_RT_USING_PM is not set -# CONFIG_RT_USING_RTC is not set +CONFIG_RT_USING_RTC=y +# CONFIG_RT_USING_ALARM is not set +# CONFIG_RT_USING_SOFT_RTC is not set # CONFIG_RT_USING_SDIO is not set CONFIG_RT_USING_SPI=y # CONFIG_RT_USING_QSPI is not set @@ -268,8 +272,7 @@ CONFIG_RT_USING_SAL=y # protocol stack implement # CONFIG_SAL_USING_LWIP=y -# CONFIG_SAL_USING_POSIX is not set -CONFIG_SAL_SOCKETS_NUM=16 +CONFIG_SAL_USING_POSIX=y # # Network interface device @@ -472,6 +475,7 @@ CONFIG_MAIN_KTASK_STACK_SIZE=1024 # knowing app # CONFIG_APPLICATION_KNOWING=y +CONFIG_APP_MNIST=y CONFIG_FACE_DETECT=y # CONFIG_INSTRUSION_DETECT is not set # CONFIG_HELMET_DETECT is not set @@ -508,7 +512,10 @@ CONFIG_SENSOR_DEVICE_D124_DEV="/dev/uar2" # CONFIG_SENSOR_HUMIDITY is not set # CONFIG_SUPPORT_CONNECTION_FRAMEWORK is not set CONFIG_SUPPORT_KNOWING_FRAMEWORK=y -# CONFIG_USING_TENSORFLOWLITEMICRO is not set +CONFIG_USING_TENSORFLOWLITEMICRO=y +CONFIG_USING_TENSORFLOWLITEMICRO_NORMAL=y +# CONFIG_USING_TENSORFLOWLITEMICRO_CMSISNN is not set +# CONFIG_USING_TENSORFLOWLITEMICRO_DEMOAPP is not set CONFIG_USING_KPU_POSTPROCESSING=y CONFIG_USING_YOLOV2=y # CONFIG_USING_KNOWING_FILTER is not set diff --git a/Ubiquitous/RT_Thread/bsp/k210/rtconfig.h b/Ubiquitous/RT_Thread/bsp/k210/rtconfig.h index c0c6bb3cf..dd0ddb421 100644 --- a/Ubiquitous/RT_Thread/bsp/k210/rtconfig.h +++ b/Ubiquitous/RT_Thread/bsp/k210/rtconfig.h @@ -71,6 +71,7 @@ /* C++ features */ +#define RT_USING_CPLUSPLUS /* Command shell */ @@ -124,6 +125,7 @@ #define RT_SERIAL_USING_DMA #define RT_SERIAL_RB_BUFSZ 64 #define RT_USING_PIN +#define RT_USING_RTC #define RT_USING_SPI #define RT_USING_SPI_MSD #define RT_USING_SFUD @@ -178,7 +180,7 @@ /* protocol stack implement */ #define SAL_USING_LWIP -#define SAL_SOCKETS_NUM 16 +#define SAL_USING_POSIX /* Network interface device */ @@ -323,6 +325,7 @@ /* knowing app */ #define APPLICATION_KNOWING +#define APP_MNIST #define FACE_DETECT /* sensor app */ @@ -342,6 +345,8 @@ #define SENSOR_QUANTITY_D124_VOICE "voice_1" #define SENSOR_DEVICE_D124_DEV "/dev/uar2" #define SUPPORT_KNOWING_FRAMEWORK +#define USING_TENSORFLOWLITEMICRO +#define USING_TENSORFLOWLITEMICRO_NORMAL #define USING_KPU_POSTPROCESSING #define USING_YOLOV2 diff --git a/Ubiquitous/RT_Thread/rt-thread b/Ubiquitous/RT_Thread/rt-thread index 06fdc108b..0b6b8b008 160000 --- a/Ubiquitous/RT_Thread/rt-thread +++ b/Ubiquitous/RT_Thread/rt-thread @@ -1 +1 @@ -Subproject commit 06fdc108b420f34044a132a19c9adbebf86a7a90 +Subproject commit 0b6b8b0088dd6aa69d1533e7187e670c5820e0f8