├── Schematics ├── bpf.pdf ├── tayloe.pdf ├── esp32-sdr.pdf └── Tayloe_mixer_x3a.pdf ├── Src ├── src │ └── dsp_lib │ │ ├── xtensa_pid_reset_f32.c │ │ ├── xtensa_bitreversal2.c │ │ ├── xtensa_add_f32.c │ │ ├── xtensa_pid_init_f32.c │ │ ├── xtensa_negate_f32.c │ │ ├── xtensa_sub_f32.c │ │ ├── xtensa_mult_f32.c │ │ ├── xtensa_abs_f32.c │ │ ├── xtensa_offset_f32.c │ │ ├── xtensa_dot_prod_f32.c │ │ ├── xtensa_cmplx_conj_f32.c │ │ ├── xtensa_cmplx_mag_f32.c │ │ ├── xtensa_const_structs.h │ │ ├── xtensa_scale_f32.c │ │ ├── xtensa_cmplx_mag_squared_f32.c │ │ ├── xtensa_cmplx_mult_real_f32.c │ │ ├── xtensa_fir_lattice_init_f32.c │ │ ├── xtensa_cmplx_mult_cmplx_f32.c │ │ ├── arm_mat_init_f32.c │ │ ├── xtensa_biquad_cascade_df1_init_f32.c │ │ ├── xtensa_cmplx_dot_prod_f32.c │ │ ├── xtensa_iir_lattice_init_f32.c │ │ ├── xtensa_cos_f32.c │ │ ├── xtensa_mean_f32.c │ │ ├── xtensa_fir_init_f32.c │ │ ├── xtensa_sin_f32.c │ │ ├── xtensa_lms_init_f32.c │ │ ├── xtensa_power_f32.c │ │ ├── xtensa_rms_f32.c │ │ ├── xtensa_max_f32.c │ │ ├── xtensa_min_f32.c │ │ ├── xtensa_lms_norm_init_f32.c │ │ ├── xtensa_fir_sparse_init_f32.c │ │ ├── xtensa_biquad_cascade_df2T_init_f32.c │ │ ├── xtensa_biquad_cascade_stereo_df2T_init_f32.c │ │ ├── xtensa_const_structs.c │ │ ├── xtensa_bitreversal.c │ │ ├── xtensa_fir_decimate_init_f32.c │ │ ├── xtensa_var_f32.c │ │ ├── xtensa_fir_interpolate_init_f32.c │ │ ├── arm_mat_add_f32.c │ │ ├── xtensa_std_f32.c │ │ ├── arm_mat_sub_f32.c │ │ ├── arm_mat_trans_f32.c │ │ ├── arm_mat_scale_f32.c │ │ ├── xtensa_sin_cos_f32.c │ │ ├── xtensa_rfft_fast_init_f32.c │ │ ├── xtensa_conv_partial_f32.c │ │ ├── xtensa_common_tables.h │ │ ├── xtensa_cfft_radix4_init_f32.c │ │ ├── xtensa_conv_f32.c │ │ ├── arm_mat_mult_f32.c │ │ ├── xtensa_cfft_radix2_init_f32.c │ │ └── xtensa_cfft_radix2_f32.c ├── filters.h ├── wm8731.cpp ├── key.h ├── iir.S ├── tx.h ├── fft.h ├── fir.S ├── init.h ├── ESP32-SDR-TRX.ino ├── wm8731.h ├── rx.h └── lcd │ ├── LCD6BitI.h │ └── LCD6BitIS.h └── README.md /Schematics/bpf.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cvarc-Xtal/ESP32-SDR-TRX/HEAD/Schematics/bpf.pdf -------------------------------------------------------------------------------- /Schematics/tayloe.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cvarc-Xtal/ESP32-SDR-TRX/HEAD/Schematics/tayloe.pdf -------------------------------------------------------------------------------- /Schematics/esp32-sdr.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cvarc-Xtal/ESP32-SDR-TRX/HEAD/Schematics/esp32-sdr.pdf -------------------------------------------------------------------------------- /Schematics/Tayloe_mixer_x3a.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cvarc-Xtal/ESP32-SDR-TRX/HEAD/Schematics/Tayloe_mixer_x3a.pdf -------------------------------------------------------------------------------- /Src/src/dsp_lib/xtensa_pid_reset_f32.c: -------------------------------------------------------------------------------- 1 | 2 | 3 | #include "xtensa_math.h" 4 | 5 | /** 6 | * @addtogroup PID 7 | * @{ 8 | */ 9 | 10 | /** 11 | * @brief Reset function for the floating-point PID Control. 12 | * @param[in] *S Instance pointer of PID control data structure. 13 | * @return none. 14 | * \par Description: 15 | * The function resets the state buffer to zeros. 16 | */ 17 | void xtensa_pid_reset_f32( 18 | xtensa_pid_instance_f32 * S) 19 | { 20 | 21 | /* Clear the state buffer. The size will be always 3 samples */ 22 | memset(S->state, 0, 3U * sizeof(float32_t)); 23 | } 24 | 25 | /** 26 | * @} end of PID group 27 | */ 28 | -------------------------------------------------------------------------------- /Src/src/dsp_lib/xtensa_bitreversal2.c: -------------------------------------------------------------------------------- 1 | #include "xtensa_math.h" 2 | /* 3 | arm_bitreversal_32 PROC 4 | ADDS r3,r1,#1 5 | PUSH {r4-r6} 6 | ADDS r1,r2,#0 7 | LSRS r3,r3,#1 8 | arm_bitreversal_32_0 LABEL 9 | LDRH r2,[r1,#2] 10 | LDRH r6,[r1,#0] 11 | ADD r2,r0,r2 12 | ADD r6,r0,r6 13 | LDR r5,[r2,#0] 14 | LDR r4,[r6,#0] 15 | STR r5,[r6,#0] 16 | STR r4,[r2,#0] 17 | LDR r5,[r2,#4] 18 | LDR r4,[r6,#4] 19 | STR r5,[r6,#4] 20 | STR r4,[r2,#4] 21 | ADDS r1,r1,#4 22 | SUBS r3,r3,#1 23 | BNE arm_bitreversal_32_0 24 | POP {r4-r6} 25 | BX lr 26 | ENDP 27 | 28 | */ 29 | void xtensa_bitreversal_32(uint32_t *pSrc, const uint16_t bitRevLen, const uint16_t *pBitRevTab) 30 | { 31 | uint32_t r3 = (bitRevLen + 1) / 2; 32 | uint32_t *r2, *r6; 33 | uint32_t r4, r5; 34 | while(r3--) 35 | { 36 | r2 = (uint32_t *)((uint32_t)pSrc + pBitRevTab[0]); 37 | r6 = (uint32_t *)((uint32_t)pSrc + pBitRevTab[1]); 38 | 39 | r5 = r2[0]; 40 | r4 = r6[0]; 41 | r6[0] = r5; 42 | r2[0] = r4; 43 | 44 | r5 = r2[1]; 45 | r4 = r6[1]; 46 | r6[1] = r5; 47 | r2[1] = r4; 48 | 49 | pBitRevTab += 2; 50 | } 51 | } -------------------------------------------------------------------------------- /Src/filters.h: -------------------------------------------------------------------------------- 1 | #include "coefficients.h" 2 | 3 | FIR fir_rx; 4 | FIR fir_90; 5 | FIR fir_00; 6 | 7 | static float delay_state_rx[NTAPS_RX]; 8 | static float delay_state_tx_90[NTAPS_TX]; 9 | static float delay_state_tx_00[NTAPS_TX]; 10 | 11 | void fir_init(FIR* fir,float* coeffs, float* delay, int N){ 12 | fir->coeffs = coeffs; 13 | fir->delay = delay; 14 | fir->N = N; 15 | fir->pos = 0; 16 | for(int i=0;idelay[i] = 0; 18 | } 19 | } 20 | 21 | void init_filters (uint8_t num_filter){ 22 | uint8_t static old_filter = 100; 23 | if (num_filter == old_filter) return; 24 | for(int i=0;i<5;i++){acc_hpf[i]=acc_lpf[i]=0.0f;} 25 | switch (num_filter){ 26 | case 0:indent=0;bandwidth=3000; fir_init(&fir_rx,lpf3000, delay_state_rx, NTAPS_RX);break; 27 | case 1:indent=0;bandwidth=2200; fir_init(&fir_rx,lpf2400, delay_state_rx, NTAPS_RX);break; 28 | case 2:indent=bandwidth=500; fir_init(&fir_rx,bpf500, delay_state_rx, NTAPS_RX);break; 29 | case 3:indent=0;bandwidth=6000; fir_init(&fir_rx,lpf6000, delay_state_rx, NTAPS_RX);break; 30 | } 31 | fir_init(&fir_90, h90, delay_state_tx_90, NTAPS_TX); 32 | fir_init(&fir_00, h00, delay_state_tx_00, NTAPS_TX); 33 | old_filter = num_filter; 34 | Serial.print("Init new FIR."); 35 | } 36 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ПРОЕКТ ЗАКРЫТ. 2 | Эксперимент по определению возможностей применения ESP32 в SDR 3 | 4 | На данный момент проект в очень предварительной версии, но основной функционал реализован 5 | в том числе: 6 | 1.Прием и передача SSB 7 | 2.Отображение основной информации, включая спектр и "водопад" 8 | 3.Управление основными функциями: 9 | - изменение полос пропускания фильтра основной селекции 10 | - переключение LSB/USB 11 | - перестройка по диапазону или по отображаемой панораме 12 | 13 | Кратко об особенностях реализации. 14 | Для отображения информации выбран LCD с параллельным (tft24) интерфейсом как наименее 15 | затратный с точки зрения нагрузки процессора способ вывода изображения (подробнее в моем 16 | соседнем репозитарии). 17 | 18 | Фильтры FIR/IIR реализованы на ассемблере (позаимствовано из ESP-DSP). 19 | Для FFT-функций используется набор xtensa-math (переписанный cmsis-dsp для arm) 20 | В виду наличия в esp32 двух ядер , удалось гладко распараллелить задачи - 21 | операции ЦОС в основном выполняются на одном ядре, а управление и отображение - на другом. 22 | 23 | 24 | Добавлена возможность использовать VGA дисплей вместо LCD.Для этого закомментировать 25 | в файле global.h строку #define LCD_DE, раскомментировать #define VGA и персобрать проект. 26 | 27 | 28 | Код написан в среде Ардуино 1.8.13 29 | Никаких ограничений на использование этого проекта или его частей нет. 30 | -------------------------------------------------------------------------------- /Src/src/dsp_lib/xtensa_add_f32.c: -------------------------------------------------------------------------------- 1 | 2 | 3 | #include "xtensa_math.h" 4 | 5 | /** 6 | * @ingroup groupMath 7 | */ 8 | 9 | /** 10 | * @defgroup BasicAdd Vector Addition 11 | * 12 | * Element-by-element addition of two vectors. 13 | * 14 | *
15 |  *     pDst[n] = pSrcA[n] + pSrcB[n],   0 <= n < blockSize.
16 |  * 
17 | * 18 | * There are separate functions for floating-point, Q7, Q15, and Q31 data types. 19 | */ 20 | 21 | /** 22 | * @addtogroup BasicAdd 23 | * @{ 24 | */ 25 | 26 | /** 27 | * @brief Floating-point vector addition. 28 | * @param[in] *pSrcA points to the first input vector 29 | * @param[in] *pSrcB points to the second input vector 30 | * @param[out] *pDst points to the output vector 31 | * @param[in] blockSize number of samples in each vector 32 | * @return none. 33 | */ 34 | 35 | void xtensa_add_f32( 36 | float32_t * pSrcA, 37 | float32_t * pSrcB, 38 | float32_t * pDst, 39 | uint32_t blockSize) 40 | { 41 | uint32_t blkCnt; /* loop counter */ 42 | blkCnt = blockSize; 43 | 44 | 45 | while (blkCnt > 0U) 46 | { 47 | /* C = A + B */ 48 | /* Add and then store the results in the destination buffer. */ 49 | *pDst++ = (*pSrcA++) + (*pSrcB++); 50 | 51 | /* Decrement the loop counter */ 52 | blkCnt--; 53 | } 54 | } 55 | 56 | /** 57 | * @} end of BasicAdd group 58 | */ 59 | -------------------------------------------------------------------------------- /Src/src/dsp_lib/xtensa_pid_init_f32.c: -------------------------------------------------------------------------------- 1 | 2 | 3 | #include "xtensa_math.h" 4 | 5 | /** 6 | * @addtogroup PID 7 | * @{ 8 | */ 9 | 10 | /** 11 | * @brief Initialization function for the floating-point PID Control. 12 | * @param[in,out] *S points to an instance of the PID structure. 13 | * @param[in] resetStateFlag flag to reset the state. 0 = no change in state & 1 = reset the state. 14 | * @return none. 15 | * \par Description: 16 | * \par 17 | * The resetStateFlag specifies whether to set state to zero or not. \n 18 | * The function computes the structure fields: A0, A1 A2 19 | * using the proportional gain( \c Kp), integral gain( \c Ki) and derivative gain( \c Kd) 20 | * also sets the state variables to all zeros. 21 | */ 22 | 23 | void xtensa_pid_init_f32( 24 | xtensa_pid_instance_f32 * S, 25 | int32_t resetStateFlag) 26 | { 27 | 28 | /* Derived coefficient A0 */ 29 | S->A0 = S->Kp + S->Ki + S->Kd; 30 | 31 | /* Derived coefficient A1 */ 32 | S->A1 = (-S->Kp) - ((float32_t) 2.0 * S->Kd); 33 | 34 | /* Derived coefficient A2 */ 35 | S->A2 = S->Kd; 36 | 37 | /* Check whether state needs reset or not */ 38 | if (resetStateFlag) 39 | { 40 | /* Clear the state buffer. The size will be always 3 samples */ 41 | memset(S->state, 0, 3U * sizeof(float32_t)); 42 | } 43 | 44 | } 45 | 46 | /** 47 | * @} end of PID group 48 | */ 49 | -------------------------------------------------------------------------------- /Src/src/dsp_lib/xtensa_negate_f32.c: -------------------------------------------------------------------------------- 1 | 2 | 3 | #include "xtensa_math.h" 4 | 5 | /** 6 | * @ingroup groupMath 7 | */ 8 | 9 | /** 10 | * @defgroup negate Vector Negate 11 | * 12 | * Negates the elements of a vector. 13 | * 14 | *
15 |  *     pDst[n] = -pSrc[n],   0 <= n < blockSize.
16 |  * 
17 | * 18 | * The functions support in-place computation allowing the source and 19 | * destination pointers to reference the same memory buffer. 20 | * There are separate functions for floating-point, Q7, Q15, and Q31 data types. 21 | */ 22 | 23 | /** 24 | * @addtogroup negate 25 | * @{ 26 | */ 27 | 28 | /** 29 | * @brief Negates the elements of a floating-point vector. 30 | * @param[in] *pSrc points to the input vector 31 | * @param[out] *pDst points to the output vector 32 | * @param[in] blockSize number of samples in the vector 33 | * @return none. 34 | */ 35 | 36 | void xtensa_negate_f32( 37 | float32_t * pSrc, 38 | float32_t * pDst, 39 | uint32_t blockSize) 40 | { 41 | uint32_t blkCnt; /* loop counter */ 42 | 43 | 44 | 45 | 46 | /* Initialize blkCnt with number of samples */ 47 | blkCnt = blockSize; 48 | 49 | while (blkCnt > 0U) 50 | { 51 | /* C = -A */ 52 | /* Negate and then store the results in the destination buffer. */ 53 | *pDst++ = -*pSrc++; 54 | 55 | /* Decrement the loop counter */ 56 | blkCnt--; 57 | } 58 | } 59 | 60 | /** 61 | * @} end of negate group 62 | */ 63 | -------------------------------------------------------------------------------- /Src/src/dsp_lib/xtensa_sub_f32.c: -------------------------------------------------------------------------------- 1 | 2 | #include "xtensa_math.h" 3 | 4 | /** 5 | * @ingroup groupMath 6 | */ 7 | 8 | /** 9 | * @defgroup BasicSub Vector Subtraction 10 | * 11 | * Element-by-element subtraction of two vectors. 12 | * 13 | *
14 |  *     pDst[n] = pSrcA[n] - pSrcB[n],   0 <= n < blockSize.
15 |  * 
16 | * 17 | * There are separate functions for floating-point, Q7, Q15, and Q31 data types. 18 | */ 19 | 20 | /** 21 | * @addtogroup BasicSub 22 | * @{ 23 | */ 24 | 25 | 26 | /** 27 | * @brief Floating-point vector subtraction. 28 | * @param[in] *pSrcA points to the first input vector 29 | * @param[in] *pSrcB points to the second input vector 30 | * @param[out] *pDst points to the output vector 31 | * @param[in] blockSize number of samples in each vector 32 | * @return none. 33 | */ 34 | 35 | void xtensa_sub_f32( 36 | float32_t * pSrcA, 37 | float32_t * pSrcB, 38 | float32_t * pDst, 39 | uint32_t blockSize) 40 | { 41 | uint32_t blkCnt; /* loop counter */ 42 | 43 | 44 | 45 | /* Initialize blkCnt with number of samples */ 46 | blkCnt = blockSize; 47 | 48 | while (blkCnt > 0U) 49 | { 50 | /* C = A - B */ 51 | /* Subtract and then store the results in the destination buffer. */ 52 | *pDst++ = (*pSrcA++) - (*pSrcB++); 53 | 54 | /* Decrement the loop counter */ 55 | blkCnt--; 56 | } 57 | } 58 | 59 | /** 60 | * @} end of BasicSub group 61 | */ 62 | -------------------------------------------------------------------------------- /Src/src/dsp_lib/xtensa_mult_f32.c: -------------------------------------------------------------------------------- 1 | 2 | #include "xtensa_math.h" 3 | 4 | /** 5 | * @ingroup groupMath 6 | */ 7 | 8 | /** 9 | * @defgroup BasicMult Vector Multiplication 10 | * 11 | * Element-by-element multiplication of two vectors. 12 | * 13 | *
14 |  *     pDst[n] = pSrcA[n] * pSrcB[n],   0 <= n < blockSize.
15 |  * 
16 | * 17 | * There are separate functions for floating-point, Q7, Q15, and Q31 data types. 18 | */ 19 | 20 | /** 21 | * @addtogroup BasicMult 22 | * @{ 23 | */ 24 | 25 | /** 26 | * @brief Floating-point vector multiplication. 27 | * @param[in] *pSrcA points to the first input vector 28 | * @param[in] *pSrcB points to the second input vector 29 | * @param[out] *pDst points to the output vector 30 | * @param[in] blockSize number of samples in each vector 31 | * @return none. 32 | */ 33 | 34 | void xtensa_mult_f32( 35 | float32_t * pSrcA, 36 | float32_t * pSrcB, 37 | float32_t * pDst, 38 | uint32_t blockSize) 39 | { 40 | uint32_t blkCnt; /* loop counters */ 41 | 42 | /* Initialize blkCnt with number of samples */ 43 | blkCnt = blockSize; 44 | 45 | 46 | while (blkCnt > 0U) 47 | { 48 | /* C = A * B */ 49 | /* Multiply the inputs and store the results in output buffer */ 50 | *pDst++ = (*pSrcA++) * (*pSrcB++); 51 | 52 | /* Decrement the blockSize loop counter */ 53 | blkCnt--; 54 | } 55 | } 56 | 57 | /** 58 | * @} end of BasicMult group 59 | */ 60 | -------------------------------------------------------------------------------- /Src/src/dsp_lib/xtensa_abs_f32.c: -------------------------------------------------------------------------------- 1 | 2 | 3 | #include "xtensa_math.h" 4 | #include 5 | 6 | /** 7 | * @ingroup groupMath 8 | */ 9 | 10 | /** 11 | * @defgroup BasicAbs Vector Absolute Value 12 | * 13 | * Computes the absolute value of a vector on an element-by-element basis. 14 | * 15 | *
16 |  *     pDst[n] = abs(pSrc[n]),   0 <= n < blockSize.
17 |  * 
18 | * 19 | * The functions support in-place computation allowing the source and 20 | * destination pointers to reference the same memory buffer. 21 | * There are separate functions for floating-point, Q7, Q15, and Q31 data types. 22 | */ 23 | 24 | /** 25 | * @addtogroup BasicAbs 26 | * @{ 27 | */ 28 | 29 | /** 30 | * @brief Floating-point vector absolute value. 31 | * @param[in] *pSrc points to the input buffer 32 | * @param[out] *pDst points to the output buffer 33 | * @param[in] blockSize number of samples in each vector 34 | * @return none. 35 | */ 36 | 37 | void xtensa_abs_f32( 38 | float32_t * pSrc, 39 | float32_t * pDst, 40 | uint32_t blockSize) 41 | { 42 | uint32_t blkCnt; /* loop counter */ 43 | 44 | 45 | /* Initialize blkCnt with number of samples */ 46 | blkCnt = blockSize; 47 | 48 | while (blkCnt > 0U) 49 | { 50 | /* C = |A| */ 51 | /* Calculate absolute and then store the results in the destination buffer. */ 52 | *pDst++ = fabsf(*pSrc++); 53 | 54 | /* Decrement the loop counter */ 55 | blkCnt--; 56 | } 57 | } 58 | 59 | /** 60 | * @} end of BasicAbs group 61 | */ 62 | -------------------------------------------------------------------------------- /Src/src/dsp_lib/xtensa_offset_f32.c: -------------------------------------------------------------------------------- 1 | 2 | 3 | #include "xtensa_math.h" 4 | 5 | /** 6 | * @ingroup groupMath 7 | */ 8 | 9 | /** 10 | * @defgroup offset Vector Offset 11 | * 12 | * Adds a constant offset to each element of a vector. 13 | * 14 | *
15 |  *     pDst[n] = pSrc[n] + offset,   0 <= n < blockSize.
16 |  * 
17 | * 18 | * The functions support in-place computation allowing the source and 19 | * destination pointers to reference the same memory buffer. 20 | * There are separate functions for floating-point, Q7, Q15, and Q31 data types. 21 | */ 22 | 23 | /** 24 | * @addtogroup offset 25 | * @{ 26 | */ 27 | 28 | /** 29 | * @brief Adds a constant offset to a floating-point vector. 30 | * @param[in] *pSrc points to the input vector 31 | * @param[in] offset is the offset to be added 32 | * @param[out] *pDst points to the output vector 33 | * @param[in] blockSize number of samples in the vector 34 | * @return none. 35 | */ 36 | 37 | 38 | void xtensa_offset_f32( 39 | float32_t * pSrc, 40 | float32_t offset, 41 | float32_t * pDst, 42 | uint32_t blockSize) 43 | { 44 | uint32_t blkCnt; /* loop counter */ 45 | 46 | 47 | /* Initialize blkCnt with number of samples */ 48 | blkCnt = blockSize; 49 | 50 | while (blkCnt > 0U) 51 | { 52 | /* C = A + offset */ 53 | /* Add offset and then store the result in the destination buffer. */ 54 | *pDst++ = (*pSrc++) + offset; 55 | 56 | /* Decrement the loop counter */ 57 | blkCnt--; 58 | } 59 | } 60 | 61 | /** 62 | * @} end of offset group 63 | */ 64 | -------------------------------------------------------------------------------- /Src/src/dsp_lib/xtensa_dot_prod_f32.c: -------------------------------------------------------------------------------- 1 | 2 | 3 | #include "xtensa_math.h" 4 | 5 | /** 6 | * @ingroup groupMath 7 | */ 8 | 9 | /** 10 | * @defgroup dot_prod Vector Dot Product 11 | * 12 | * Computes the dot product of two vectors. 13 | * The vectors are multiplied element-by-element and then summed. 14 | * 15 | *
16 |  *     sum = pSrcA[0]*pSrcB[0] + pSrcA[1]*pSrcB[1] + ... + pSrcA[blockSize-1]*pSrcB[blockSize-1]
17 |  * 
18 | * 19 | * There are separate functions for floating-point, Q7, Q15, and Q31 data types. 20 | */ 21 | 22 | /** 23 | * @addtogroup dot_prod 24 | * @{ 25 | */ 26 | 27 | /** 28 | * @brief Dot product of floating-point vectors. 29 | * @param[in] *pSrcA points to the first input vector 30 | * @param[in] *pSrcB points to the second input vector 31 | * @param[in] blockSize number of samples in each vector 32 | * @param[out] *result output result returned here 33 | * @return none. 34 | */ 35 | 36 | 37 | void xtensa_dot_prod_f32( 38 | float32_t * pSrcA, 39 | float32_t * pSrcB, 40 | uint32_t blockSize, 41 | float32_t * result) 42 | { 43 | float32_t sum = 0.0f; /* Temporary result storage */ 44 | uint32_t blkCnt; /* loop counter */ 45 | 46 | 47 | 48 | 49 | /* Initialize blkCnt with number of samples */ 50 | blkCnt = blockSize; 51 | 52 | 53 | 54 | while (blkCnt > 0U) 55 | { 56 | /* C = A[0]* B[0] + A[1]* B[1] + A[2]* B[2] + .....+ A[blockSize-1]* B[blockSize-1] */ 57 | /* Calculate dot product and then store the result in a temporary buffer. */ 58 | sum += (*pSrcA++) * (*pSrcB++); 59 | 60 | /* Decrement the loop counter */ 61 | blkCnt--; 62 | } 63 | /* Store the result back in the destination buffer */ 64 | *result = sum; 65 | } 66 | 67 | /** 68 | * @} end of dot_prod group 69 | */ 70 | -------------------------------------------------------------------------------- /Src/wm8731.cpp: -------------------------------------------------------------------------------- 1 | #include "wm8731.h" 2 | 3 | 4 | void wm8731_init() { 5 | 6 | wm8731_write_reg(0b00011110, 0b00000000); //R15 Reset Chip 7 | wm8731_write_reg(0b00000100, 0b01111111); //R2 Left Headphone Out Mute 8 | wm8731_write_reg(0b00000110, 0b01111111); //R3 Right Headphone Out Mute 9 | wm8731_write_reg(0b00001110, 0b10111110); //R7 Digital Audio Interface Format, 10 | //Codec Slave, 32bits, I2S Format, 11 | //MSB-First left-1 justified 12 | wm8731_write_reg(0b00010000, 0b00000010); //R8 Sampling Control normal mode, 384fs, 13 | 14 | wm8731_write_reg(0b00000000, 0b00011111); //R0 Left Line Input volume 15 | wm8731_write_reg(0b00000010, 0b00011111); //R1 Right Line Input volume 16 | wm8731_write_reg(0b00001000, 0b00010010); //R4 Analogue Audio Path Control 17 | wm8731_write_reg(0b00001010, 0b00000110); //R5 Digital Audio Path Control 18 | wm8731_write_reg(0b00001100, 0b01100000); //R6 Power Down Control 19 | wm8731_write_reg(0b00010010, 0b00000001); //R9 reactivate digital audio interface 20 | 21 | } 22 | 23 | void wm8731_write_reg(uint8_t reg, uint8_t value) { 24 | uint8_t st = 2; 25 | uint8_t repeats = 0; 26 | Wire.beginTransmission(WM8731_WRITE_ADDRESS); 27 | Wire.write(reg);Wire.write(value); 28 | st = Wire.endTransmission(); 29 | } 30 | 31 | void wm8731_reset() { 32 | wm8731_write_reg(0b00011110, 0b00000000); //R15 Reset Chip 33 | } 34 | 35 | 36 | // set the line input volume to vol 37 | // vol: from 0 (=-34.5 dB) to 31 (=+12 dB) in 1.5 dB steps 38 | void wm8731_set_line_in_volume(uint8_t vol) { 39 | static uint8_t old_vol = 0; 40 | if(vol == old_vol)return; 41 | wm8731_write_reg(0b00000000, vol); //R0 Left Line In 42 | wm8731_write_reg(0b00000010, vol); //R1 Right Line In 43 | old_vol=vol; 44 | } 45 | -------------------------------------------------------------------------------- /Src/src/dsp_lib/xtensa_cmplx_conj_f32.c: -------------------------------------------------------------------------------- 1 | 2 | 3 | #include "xtensa_math.h" 4 | 5 | /** 6 | * @ingroup groupCmplxMath 7 | */ 8 | 9 | /** 10 | * @defgroup cmplx_conj Complex Conjugate 11 | * 12 | * Conjugates the elements of a complex data vector. 13 | * 14 | * The pSrc points to the source data and 15 | * pDst points to the where the result should be written. 16 | * numSamples specifies the number of complex samples 17 | * and the data in each array is stored in an interleaved fashion 18 | * (real, imag, real, imag, ...). 19 | * Each array has a total of 2*numSamples values. 20 | * The underlying algorithm is used: 21 | * 22 | *
23 |  * for(n=0; n
28 |  *
29 |  * There are separate functions for floating-point, Q15, and Q31 data types.
30 |  */
31 | 
32 | /**
33 |  * @addtogroup cmplx_conj
34 |  * @{
35 |  */
36 | 
37 | /**
38 |  * @brief  Floating-point complex conjugate.
39 |  * @param  *pSrc points to the input vector
40 |  * @param  *pDst points to the output vector
41 |  * @param  numSamples number of complex samples in each vector
42 |  * @return none.
43 |  */
44 | 
45 | void xtensa_cmplx_conj_f32(
46 |   float32_t * pSrc,
47 |   float32_t * pDst,
48 |   uint32_t numSamples)
49 | {
50 |   uint32_t blkCnt;                               /* loop counter */
51 | 
52 | 
53 |   blkCnt = numSamples;
54 | 
55 | 
56 |   while (blkCnt > 0U)
57 |   {
58 |     /* realOut + j (imagOut) = realIn + j (-1) imagIn */
59 |     /* Calculate Complex Conjugate and then store the results in the destination buffer. */
60 |     *pDst++ = *pSrc++;
61 |     *pDst++ = -*pSrc++;
62 | 
63 |     /* Decrement the loop counter */
64 |     blkCnt--;
65 |   }
66 | }
67 | 
68 | /**
69 |  * @} end of cmplx_conj group
70 |  */
71 | 


--------------------------------------------------------------------------------
/Src/src/dsp_lib/xtensa_cmplx_mag_f32.c:
--------------------------------------------------------------------------------
 1 | 
 2 | 
 3 | #include "xtensa_math.h"
 4 | 
 5 | /**
 6 |  * @ingroup groupCmplxMath
 7 |  */
 8 | 
 9 | /**
10 |  * @defgroup cmplx_mag Complex Magnitude
11 |  *
12 |  * Computes the magnitude of the elements of a complex data vector.
13 |  *
14 |  * The pSrc points to the source data and
15 |  * pDst points to the where the result should be written.
16 |  * numSamples specifies the number of complex samples
17 |  * in the input array and the data is stored in an interleaved fashion
18 |  * (real, imag, real, imag, ...).
19 |  * The input array has a total of 2*numSamples values;
20 |  * the output array has a total of numSamples values.
21 |  * The underlying algorithm is used:
22 |  *
23 |  * 
24 |  * for(n=0; n
28 |  *
29 |  * There are separate functions for floating-point, Q15, and Q31 data types.
30 |  */
31 | 
32 | /**
33 |  * @addtogroup cmplx_mag
34 |  * @{
35 |  */
36 | /**
37 |  * @brief Floating-point complex magnitude.
38 |  * @param[in]       *pSrc points to complex input buffer
39 |  * @param[out]      *pDst points to real output buffer
40 |  * @param[in]       numSamples number of complex samples in the input vector
41 |  * @return none.
42 |  *
43 |  */
44 | 
45 | 
46 | void xtensa_cmplx_mag_f32(
47 |   float32_t * pSrc,
48 |   float32_t * pDst,
49 |   uint32_t numSamples)
50 | {
51 |   float32_t realIn, imagIn;                      /* Temporary variables to hold input values */
52 | 
53 | 
54 | 
55 |   while (numSamples > 0U)
56 |   {
57 |     /* out = sqrt((real * real) + (imag * imag)) */
58 |     realIn = *pSrc++;
59 |     imagIn = *pSrc++;
60 |     /* store the result in the destination buffer. */
61 |     xtensa_sqrt_f32((realIn * realIn) + (imagIn * imagIn), pDst++);
62 | 
63 |     /* Decrement the loop counter */
64 |     numSamples--;
65 |   }
66 | 
67 | 
68 | }
69 | 
70 | /**
71 |  * @} end of cmplx_mag group
72 |  */
73 | 


--------------------------------------------------------------------------------
/Src/key.h:
--------------------------------------------------------------------------------
 1 | 
 2 | uint8_t lastkey_l(uint16_t value){
 3 |     uint8_t key = 0;
 4 |     if ((value > 500)){key=0;return key;}
 5 |     else if (abs(value - value_button[0]) < 5){key=1;return key;}
 6 |     else if (abs(value - value_button[1]) < 5){key=2;return key;}
 7 |     else if (abs(value - value_button[2]) < 5) {key=3;return key;}
 8 |     else if (abs(value - value_button[3]) < 5) {key=4;return key;}
 9 |     return key;
10 | }
11 | 
12 | uint8_t lastkey_r(uint16_t value){
13 |     uint8_t key = 0;
14 |     if ((value > 500)){key=0;return key;}
15 |     else if (abs(value - value_button[4]) < 5){key=1;return key;}
16 |     else if (abs(value - value_button[5]) < 5){key=2;return key;}
17 |     else if (abs(value - value_button[6]) < 5) {key=3;return key;}
18 |     else if (abs(value - value_button[7]) < 5) {key=4;return key;}
19 |     return key;
20 | }
21 | 
22 | //возвращает усредн.данные АЦП (0 - channel0, 1 - channel3)
23 | uint16_t v_knopka(int c){
24 |        uint16_t ll = 0;uint16_t mm = 0;
25 |        for (int i = 0;i < 5;i++){ //5 опросов для усреднения
26 |         if (c == 0){mm = adc1_get_raw(LEFT_ADC);}else{mm = adc1_get_raw(RIGHT_ADC);}
27 |         ll = ll + mm;
28 |        }
29 |        return (ll/5);
30 | }
31 | 
32 | //опрос левых кнопок
33 | void l_knopka(){
34 |        uint16_t value = v_knopka(0);
35 |        if ((value > 500) && l_press) {l_release = true;return;}//л.кнопка отпущена
36 |        in_left = v_knopka(0);//вторичный запрос данных АЦП для последующего сравнения и исключения ложных
37 |        if ((in_left  < 500) && (abs(in_left - value) < 5))
38 |        {l_release = false;l_press = true;lkey = lastkey_l(in_left);}else{l_press = false;}
39 | }
40 | 
41 | //опрос правых кнопок
42 | void r_knopka(){
43 |        uint16_t value = v_knopka(1);
44 |        if ((value > 500) && r_press) {r_release = true;return;}//пр.кнопка отпущена
45 |        in_right = v_knopka(1);//вторичный запрос данных АЦП для последующего сравнения  и исключения ложных
46 |        if ((in_right < 500)  && (abs(in_right - value) < 5))
47 |        {r_release = false;r_press = true;rkey = lastkey_r(in_right);}else{r_press = false;}
48 | }
49 | 


--------------------------------------------------------------------------------
/Src/src/dsp_lib/xtensa_const_structs.h:
--------------------------------------------------------------------------------
 1 | /* ----------------------------------------------------------------------
 2 |  * Project:      CMSIS DSP Library
 3 |  * Title:        xtensa_const_structs.h
 4 |  * Description:  Constant structs that are initialized for user convenience.
 5 |  *               For example, some can be given as arguments to the xtensa_cfft_f32() function.
 6 |  *
 7 |  * $Date:        27. January 2017
 8 |  * $Revision:    V.1.5.1
 9 |  *
10 |  * Target Processor: Cortex-M cores
11 |  * -------------------------------------------------------------------- */
12 | /*
13 |  * Copyright (C) 2010-2017 ARM Limited or its affiliates. All rights reserved.
14 |  *
15 |  * SPDX-License-Identifier: Apache-2.0
16 |  *
17 |  * Licensed under the Apache License, Version 2.0 (the License); you may
18 |  * not use this file except in compliance with the License.
19 |  * You may obtain a copy of the License at
20 |  *
21 |  * www.apache.org/licenses/LICENSE-2.0
22 |  *
23 |  * Unless required by applicable law or agreed to in writing, software
24 |  * distributed under the License is distributed on an AS IS BASIS, WITHOUT
25 |  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
26 |  * See the License for the specific language governing permissions and
27 |  * limitations under the License.
28 |  */
29 | 
30 | #ifndef _XTENSA_CONST_STRUCTS_H
31 | #define _XTENSA_CONST_STRUCTS_H
32 | 
33 | #include "xtensa_math.h"
34 | #include "xtensa_common_tables.h"
35 | 
36 |    extern const xtensa_cfft_instance_f32 xtensa_cfft_sR_f32_len16;
37 |    extern const xtensa_cfft_instance_f32 xtensa_cfft_sR_f32_len32;
38 |    extern const xtensa_cfft_instance_f32 xtensa_cfft_sR_f32_len64;
39 |    extern const xtensa_cfft_instance_f32 xtensa_cfft_sR_f32_len128;
40 |    extern const xtensa_cfft_instance_f32 xtensa_cfft_sR_f32_len256;
41 |    extern const xtensa_cfft_instance_f32 xtensa_cfft_sR_f32_len512;
42 |    extern const xtensa_cfft_instance_f32 xtensa_cfft_sR_f32_len1024;
43 |    extern const xtensa_cfft_instance_f32 xtensa_cfft_sR_f32_len2048;
44 |    extern const xtensa_cfft_instance_f32 xtensa_cfft_sR_f32_len4096;
45 | 
46 | #endif
47 | 


--------------------------------------------------------------------------------
/Src/iir.S:
--------------------------------------------------------------------------------
 1 | //(c)Espressif https://github.com/espressif/esp-dsp/blob/master/modules/iir/biquad/dsps_biquad_f32_ae32.S
 2 | 
 3 | // This is bi quad filter form II for ESP32 processor.
 4 |   .text
 5 |   .align  4
 6 |   .global iir_biquad_f32
 7 |   .type   iir_biquad_f32,@function
 8 | // The function implements the following C code:
 9 | //esp_err_t dsps_biquad_f32_ae32(const float* input, float* output, int len, float* coef, float* w)
10 | //  {
11 | //    for (int i=0 ; i< len ; i++)
12 | //    {
13 | //        float d0 = input[i] - coef[3]*w[0] - coef[4]*w[1]; (input[i] - a[1]*w[0] - a[2]*w[1];)
14 | //        output[i] = coef[0]*d0 +  coef[1]*w[0] + coef[2]*w[1];
15 | //        w[1] = w[0];
16 | //        w[0] = d0;
17 | //    }
18 | //    return ESP_OK;
19 | //  }
20 | 
21 | iir_biquad_f32: 
22 | // input    - a2
23 | // output   - a3
24 | // len  - a4
25 | // coeffs  - a5
26 | // w- a6
27 | 
28 | // f0 - b0
29 | // f1 - b1
30 | // f2 - b2
31 | // f3 - a1
32 | // f4 - a2
33 | 
34 | // f5 - w0
35 | // f6 - w1
36 | 
37 |   entry a1, 16
38 |   // Array increment for floating point data should be 4
39 |   lsi   f0, a5, 0
40 |   lsi   f1, a5, 4
41 |   lsi   f2, a5, 8
42 |   lsi   f3, a5, 12
43 |   lsi   f4, a5, 16
44 | 
45 |   
46 |   neg.s  f5, f3   // -a[1]
47 |   neg.s  f6, f4   // -a[2]
48 | 
49 |   lsi   f7, a6, 0 // w[0]
50 |   lsi   f8, a6, 4 // w[1]
51 |   
52 |   addi    a3, a3, -4       // i-- // preset a3
53 |   lsi     f9, a2, 0        // f9 = x[i]
54 |   loopnez a4, loop_bq_end_m_ae32
55 |     madd.s  f9, f7, f5   // f9 += -a1*w0
56 |     addi    a3, a3, 4    // out++;
57 |     mul.s   f10, f1, f7  // f10 = b1*w0
58 |     madd.s  f9, f8, f6   // f9 += -a2*w1
59 |     madd.s  f10, f9, f0  // f10 += b0*d0
60 |     addi    a2, a2, 4    // in++;
61 |     madd.s  f10, f2, f8  // f10+= b2*w1, f10 - result
62 |     mov.s   f8, f7       // w1 = w0
63 |     mov.s   f7, f9       // w0 = d0
64 |     lsi     f9, a2,  0   // f9 = x[i]
65 |     ssi     f10, a3, 0   // y[i] = result
66 | loop_bq_end_m_ae32:
67 |     // Store delay line
68 |     ssi     f7, a6, 0
69 |     ssi     f8, a6, 4
70 | 
71 |   movi.n  a2, 0 // return status ESP_OK
72 |   retw.n
73 | 


--------------------------------------------------------------------------------
/Src/src/dsp_lib/xtensa_scale_f32.c:
--------------------------------------------------------------------------------
 1 | 
 2 | 
 3 | #include "xtensa_math.h"
 4 | 
 5 | /**
 6 |  * @ingroup groupMath
 7 |  */
 8 | 
 9 | /**
10 |  * @defgroup scale Vector Scale
11 |  *
12 |  * Multiply a vector by a scalar value.  For floating-point data, the algorithm used is:
13 |  *
14 |  * 
15 |  *     pDst[n] = pSrc[n] * scale,   0 <= n < blockSize.
16 |  * 
17 | * 18 | * In the fixed-point Q7, Q15, and Q31 functions, scale is represented by 19 | * a fractional multiplication scaleFract and an arithmetic shift shift. 20 | * The shift allows the gain of the scaling operation to exceed 1.0. 21 | * The algorithm used with fixed-point data is: 22 | * 23 | *
24 |  *     pDst[n] = (pSrc[n] * scaleFract) << shift,   0 <= n < blockSize.
25 |  * 
26 | * 27 | * The overall scale factor applied to the fixed-point data is 28 | *
29 |  *     scale = scaleFract * 2^shift.
30 |  * 
31 | * 32 | * The functions support in-place computation allowing the source and destination 33 | * pointers to reference the same memory buffer. 34 | */ 35 | 36 | /** 37 | * @addtogroup scale 38 | * @{ 39 | */ 40 | 41 | /** 42 | * @brief Multiplies a floating-point vector by a scalar. 43 | * @param[in] *pSrc points to the input vector 44 | * @param[in] scale scale factor to be applied 45 | * @param[out] *pDst points to the output vector 46 | * @param[in] blockSize number of samples in the vector 47 | * @return none. 48 | */ 49 | 50 | 51 | void xtensa_scale_f32( 52 | float32_t * pSrc, 53 | float32_t scale, 54 | float32_t * pDst, 55 | uint32_t blockSize) 56 | { 57 | uint32_t blkCnt; /* loop counter */ 58 | 59 | 60 | 61 | /* Initialize blkCnt with number of samples */ 62 | blkCnt = blockSize; 63 | 64 | 65 | while (blkCnt > 0U) 66 | { 67 | /* C = A * scale */ 68 | /* Scale the input and then store the result in the destination buffer. */ 69 | *pDst++ = (*pSrc++) * scale; 70 | 71 | /* Decrement the loop counter */ 72 | blkCnt--; 73 | } 74 | } 75 | 76 | /** 77 | * @} end of scale group 78 | */ 79 | -------------------------------------------------------------------------------- /Src/src/dsp_lib/xtensa_cmplx_mag_squared_f32.c: -------------------------------------------------------------------------------- 1 | 2 | 3 | #include "xtensa_math.h" 4 | 5 | /** 6 | * @ingroup groupCmplxMath 7 | */ 8 | 9 | /** 10 | * @defgroup cmplx_mag_squared Complex Magnitude Squared 11 | * 12 | * Computes the magnitude squared of the elements of a complex data vector. 13 | * 14 | * The pSrc points to the source data and 15 | * pDst points to the where the result should be written. 16 | * numSamples specifies the number of complex samples 17 | * in the input array and the data is stored in an interleaved fashion 18 | * (real, imag, real, imag, ...). 19 | * The input array has a total of 2*numSamples values; 20 | * the output array has a total of numSamples values. 21 | * 22 | * The underlying algorithm is used: 23 | * 24 | *
25 |  * for(n=0; n
29 |  *
30 |  * There are separate functions for floating-point, Q15, and Q31 data types.
31 |  */
32 | 
33 | /**
34 |  * @addtogroup cmplx_mag_squared
35 |  * @{
36 |  */
37 | 
38 | 
39 | /**
40 |  * @brief  Floating-point complex magnitude squared
41 |  * @param[in]  *pSrc points to the complex input vector
42 |  * @param[out]  *pDst points to the real output vector
43 |  * @param[in]  numSamples number of complex samples in the input vector
44 |  * @return none.
45 |  */
46 | 
47 | void xtensa_cmplx_mag_squared_f32(
48 |   float32_t * pSrc,
49 |   float32_t * pDst,
50 |   uint32_t numSamples)
51 | {
52 |   float32_t real, imag;                          /* Temporary variables to store real and imaginary values */
53 |   uint32_t blkCnt;                               /* loop counter */
54 | 
55 |   blkCnt = numSamples;
56 |   while (blkCnt > 0U)
57 |   {
58 |     /* C[0] = (A[0] * A[0] + A[1] * A[1]) */
59 |     real = *pSrc++;
60 |     imag = *pSrc++;
61 | 
62 |     /* out = (real * real) + (imag * imag) */
63 |     /* store the result in the destination buffer. */
64 |     *pDst++ = (real * real) + (imag * imag);
65 | 
66 |     /* Decrement the loop counter */
67 |     blkCnt--;
68 |   }
69 | }
70 | 
71 | /**
72 |  * @} end of cmplx_mag_squared group
73 |  */
74 | 


--------------------------------------------------------------------------------
/Src/tx.h:
--------------------------------------------------------------------------------
 1 | 
 2 | xSemaphoreHandle xTXDSP;
 3 | xSemaphoreHandle xTXIN;
 4 | xSemaphoreHandle xTXOUT;
 5 | 
 6 | void IRAM_ATTR tx_in(void * pvParameters){
 7 |   size_t readsize = 0;
 8 |   while(true){
 9 |     xSemaphoreTake(xTXIN, portMAX_DELAY);//ждем сигнала об окончании dsp-обработки предыдущего буфера
10 |     if(current_mode==TX_MODE)i2s_read(I2S_NUM_0, &input_buffer, sizeof(input_buffer), &readsize, portMAX_DELAY);
11 |      for (int i=0; i>12);
13 |        workbuf_im[i] = (float)(input_buffer[i].im>>12);
14 |      }
15 |      if(current_mode==TX_MODE)xSemaphoreGive(xTXDSP);//разрешаем dsp-обработку рабочего буфера
16 |   }
17 | }
18 | 
19 | void IRAM_ATTR tx_out(void * pvParameters){
20 |   size_t readsize = 0;
21 |   while(true){
22 |     xSemaphoreTake(xTXOUT, portMAX_DELAY); //ждем сигнала об окончании dsp-обработки выходного буфера
23 |     for (int i=0; inumSamples represents the number of complex
16 |  * samples processed.  The complex arrays have a total of 2*numSamples
17 |  * real values while the real array has a total of numSamples
18 |  * real values.
19 |  *
20 |  * The underlying algorithm is used:
21 |  *
22 |  * 
23 |  * for(n=0; n
28 |  *
29 |  * There are separate functions for floating-point, Q15, and Q31 data types.
30 |  */
31 | 
32 | /**
33 |  * @addtogroup CmplxByRealMult
34 |  * @{
35 |  */
36 | 
37 | 
38 | /**
39 |  * @brief  Floating-point complex-by-real multiplication
40 |  * @param[in]  *pSrcCmplx points to the complex input vector
41 |  * @param[in]  *pSrcReal points to the real input vector
42 |  * @param[out]  *pCmplxDst points to the complex output vector
43 |  * @param[in]  numSamples number of samples in each vector
44 |  * @return none.
45 |  */
46 | 
47 | void xtensa_cmplx_mult_real_f32(
48 |   float32_t * pSrcCmplx,
49 |   float32_t * pSrcReal,
50 |   float32_t * pCmplxDst,
51 |   uint32_t numSamples)
52 | {
53 |   float32_t in;                                  /* Temporary variable to store input value */
54 |   uint32_t blkCnt;                               /* loop counters */
55 | 
56 | 
57 |   blkCnt = numSamples;
58 | 
59 | 
60 |   while (blkCnt > 0U)
61 |   {
62 |     /* C[2 * i] = A[2 * i] * B[i].            */
63 |     /* C[2 * i + 1] = A[2 * i + 1] * B[i].        */
64 |     in = *pSrcReal++;
65 |     /* store the result in the destination buffer. */
66 |     *pCmplxDst++ = (*pSrcCmplx++) * (in);
67 |     *pCmplxDst++ = (*pSrcCmplx++) * (in);
68 | 
69 |     /* Decrement the numSamples loop counter */
70 |     blkCnt--;
71 |   }
72 | }
73 | 
74 | /**
75 |  * @} end of CmplxByRealMult group
76 |  */
77 | 


--------------------------------------------------------------------------------
/Src/src/dsp_lib/xtensa_fir_lattice_init_f32.c:
--------------------------------------------------------------------------------
 1 | /* ----------------------------------------------------------------------
 2 |  * Project:      CMSIS DSP Library
 3 |  * Title:        xtensa_fir_lattice_init_f32.c
 4 |  * Description:  Floating-point FIR Lattice filter initialization function
 5 |  *
 6 |  * $Date:        27. January 2017
 7 |  * $Revision:    V.1.5.1
 8 |  *
 9 |  * Target Processor: Cortex-M cores
10 |  * -------------------------------------------------------------------- */
11 | /*
12 |  * Copyright (C) 2010-2017 ARM Limited or its affiliates. All rights reserved.
13 |  *
14 |  * SPDX-License-Identifier: Apache-2.0
15 |  *
16 |  * Licensed under the Apache License, Version 2.0 (the License); you may
17 |  * not use this file except in compliance with the License.
18 |  * You may obtain a copy of the License at
19 |  *
20 |  * www.apache.org/licenses/LICENSE-2.0
21 |  *
22 |  * Unless required by applicable law or agreed to in writing, software
23 |  * distributed under the License is distributed on an AS IS BASIS, WITHOUT
24 |  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
25 |  * See the License for the specific language governing permissions and
26 |  * limitations under the License.
27 |  */
28 | 
29 | #include "xtensa_math.h"
30 | 
31 | /**
32 |  * @ingroup groupFilters
33 |  */
34 | 
35 | /**
36 |  * @addtogroup FIR_Lattice
37 |  * @{
38 |  */
39 | 
40 | /**
41 |  * @brief Initialization function for the floating-point FIR lattice filter.
42 |  * @param[in] *S points to an instance of the floating-point FIR lattice structure.
43 |  * @param[in] numStages  number of filter stages.
44 |  * @param[in] *pCoeffs points to the coefficient buffer.  The array is of length numStages.
45 |  * @param[in] *pState points to the state buffer.  The array is of length numStages.
46 |  * @return none.
47 |  */
48 | 
49 | void xtensa_fir_lattice_init_f32(
50 |   xtensa_fir_lattice_instance_f32 * S,
51 |   uint16_t numStages,
52 |   float32_t * pCoeffs,
53 |   float32_t * pState)
54 | {
55 |   /* Assign filter taps */
56 |   S->numStages = numStages;
57 | 
58 |   /* Assign coefficient pointer */
59 |   S->pCoeffs = pCoeffs;
60 | 
61 |   /* Clear state buffer and size is always numStages */
62 |   memset(pState, 0, (numStages) * sizeof(float32_t));
63 | 
64 |   /* Assign state pointer */
65 |   S->pState = pState;
66 | 
67 | }
68 | 
69 | /**
70 |  * @} end of FIR_Lattice group
71 |  */
72 | 


--------------------------------------------------------------------------------
/Src/src/dsp_lib/xtensa_cmplx_mult_cmplx_f32.c:
--------------------------------------------------------------------------------
 1 | 
 2 | 
 3 | #include "xtensa_math.h"
 4 | 
 5 | /**
 6 |  * @ingroup groupCmplxMath
 7 |  */
 8 | 
 9 | /**
10 |  * @defgroup CmplxByCmplxMult Complex-by-Complex Multiplication
11 |  *
12 |  * Multiplies a complex vector by another complex vector and generates a complex result.
13 |  * The data in the complex arrays is stored in an interleaved fashion
14 |  * (real, imag, real, imag, ...).
15 |  * The parameter numSamples represents the number of complex
16 |  * samples processed.  The complex arrays have a total of 2*numSamples
17 |  * real values.
18 |  *
19 |  * The underlying algorithm is used:
20 |  *
21 |  * 
22 |  * for(n=0; n
27 |  *
28 |  * There are separate functions for floating-point, Q15, and Q31 data types.
29 |  */
30 | 
31 | /**
32 |  * @addtogroup CmplxByCmplxMult
33 |  * @{
34 |  */
35 | 
36 | 
37 | /**
38 |  * @brief  Floating-point complex-by-complex multiplication
39 |  * @param[in]  *pSrcA points to the first input vector
40 |  * @param[in]  *pSrcB points to the second input vector
41 |  * @param[out]  *pDst  points to the output vector
42 |  * @param[in]  numSamples number of complex samples in each vector
43 |  * @return none.
44 |  */
45 | 
46 | void xtensa_cmplx_mult_cmplx_f32(
47 |   float32_t * pSrcA,
48 |   float32_t * pSrcB,
49 |   float32_t * pDst,
50 |   uint32_t numSamples)
51 | {
52 |   float32_t a1, b1, c1, d1;                      /* Temporary variables to store real and imaginary values */
53 |   uint32_t blkCnt;                               /* loop counters */
54 | 
55 |   blkCnt = numSamples;
56 | 
57 | 
58 |   while (blkCnt > 0U)
59 |   {
60 |     /* C[2 * i] = A[2 * i] * B[2 * i] - A[2 * i + 1] * B[2 * i + 1].  */
61 |     /* C[2 * i + 1] = A[2 * i] * B[2 * i + 1] + A[2 * i + 1] * B[2 * i].  */
62 |     a1 = *pSrcA++;
63 |     b1 = *pSrcA++;
64 |     c1 = *pSrcB++;
65 |     d1 = *pSrcB++;
66 | 
67 |     /* store the result in the destination buffer. */
68 |     *pDst++ = (a1 * c1) - (b1 * d1);
69 |     *pDst++ = (a1 * d1) + (b1 * c1);
70 | 
71 |     /* Decrement the numSamples loop counter */
72 |     blkCnt--;
73 |   }
74 | }
75 | 
76 | /**
77 |  * @} end of CmplxByCmplxMult group
78 |  */
79 | 


--------------------------------------------------------------------------------
/Src/src/dsp_lib/arm_mat_init_f32.c:
--------------------------------------------------------------------------------
 1 | /* ----------------------------------------------------------------------
 2 |  * Project:      CMSIS DSP Library
 3 |  * Title:        xtensa_mat_init_f32.c
 4 |  * Description:  Floating-point matrix initialization
 5 |  *
 6 |  * $Date:        27. January 2017
 7 |  * $Revision:    V.1.5.1
 8 |  *
 9 |  * Target Processor: Cortex-M cores
10 |  * -------------------------------------------------------------------- */
11 | /*
12 |  * Copyright (C) 2010-2017 ARM Limited or its affiliates. All rights reserved.
13 |  *
14 |  * SPDX-License-Identifier: Apache-2.0
15 |  *
16 |  * Licensed under the Apache License, Version 2.0 (the License); you may
17 |  * not use this file except in compliance with the License.
18 |  * You may obtain a copy of the License at
19 |  *
20 |  * www.apache.org/licenses/LICENSE-2.0
21 |  *
22 |  * Unless required by applicable law or agreed to in writing, software
23 |  * distributed under the License is distributed on an AS IS BASIS, WITHOUT
24 |  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
25 |  * See the License for the specific language governing permissions and
26 |  * limitations under the License.
27 |  */
28 | 
29 | #include "xtensa_math.h"
30 | 
31 | /**
32 |  * @ingroup groupMatrix
33 |  */
34 | 
35 | /**
36 |  * @defgroup MatrixInit Matrix Initialization
37 |  *
38 |  * Initializes the underlying matrix data structure.
39 |  * The functions set the numRows,
40 |  * numCols, and pData fields
41 |  * of the matrix data structure.
42 |  */
43 | 
44 | /**
45 |  * @addtogroup MatrixInit
46 |  * @{
47 |  */
48 | 
49 | /**
50 |    * @brief  Floating-point matrix initialization.
51 |    * @param[in,out] *S             points to an instance of the floating-point matrix structure.
52 |    * @param[in]     nRows          number of rows in the matrix.
53 |    * @param[in]     nColumns       number of columns in the matrix.
54 |    * @param[in]     *pData	   points to the matrix data array.
55 |    * @return        none
56 |    */
57 | 
58 | void xtensa_mat_init_f32(
59 |   xtensa_matrix_instance_f32 * S,
60 |   uint16_t nRows,
61 |   uint16_t nColumns,
62 |   float32_t * pData)
63 | {
64 |   /* Assign Number of Rows */
65 |   S->numRows = nRows;
66 | 
67 |   /* Assign Number of Columns */
68 |   S->numCols = nColumns;
69 | 
70 |   /* Assign Data pointer */
71 |   S->pData = pData;
72 | }
73 | 
74 | /**
75 |  * @} end of MatrixInit group
76 |  */
77 | 


--------------------------------------------------------------------------------
/Src/src/dsp_lib/xtensa_biquad_cascade_df1_init_f32.c:
--------------------------------------------------------------------------------
 1 | 
 2 | 
 3 | #include "xtensa_math.h"
 4 | 
 5 | /**
 6 |  * @ingroup groupFilters
 7 |  */
 8 | 
 9 | /**
10 |  * @addtogroup BiquadCascadeDF1
11 |  * @{
12 |  */
13 | 
14 | /**
15 |  * @details
16 |  * @brief  Initialization function for the floating-point Biquad cascade filter.
17 |  * @param[in,out] *S           points to an instance of the floating-point Biquad cascade structure.
18 |  * @param[in]     numStages    number of 2nd order stages in the filter.
19 |  * @param[in]     *pCoeffs     points to the filter coefficients array.
20 |  * @param[in]     *pState      points to the state array.
21 |  * @return        none
22 |  *
23 |  *
24 |  * Coefficient and State Ordering:
25 |  *
26 |  * \par
27 |  * The coefficients are stored in the array pCoeffs in the following order:
28 |  * 
29 |  *     {b10, b11, b12, a11, a12, b20, b21, b22, a21, a22, ...}
30 |  * 
31 | * 32 | * \par 33 | * where b1x and a1x are the coefficients for the first stage, 34 | * b2x and a2x are the coefficients for the second stage, 35 | * and so on. The pCoeffs array contains a total of 5*numStages values. 36 | * 37 | * \par 38 | * The pState is a pointer to state array. 39 | * Each Biquad stage has 4 state variables x[n-1], x[n-2], y[n-1], and y[n-2]. 40 | * The state variables are arranged in the pState array as: 41 | *
42 |  *     {x[n-1], x[n-2], y[n-1], y[n-2]}
43 |  * 
44 | * The 4 state variables for stage 1 are first, then the 4 state variables for stage 2, and so on. 45 | * The state array has a total length of 4*numStages values. 46 | * The state variables are updated after each block of data is processed; the coefficients are untouched. 47 | * 48 | */ 49 | 50 | void xtensa_biquad_cascade_df1_init_f32( 51 | xtensa_biquad_casd_df1_inst_f32 * S, 52 | uint8_t numStages, 53 | float32_t * pCoeffs, 54 | float32_t * pState) 55 | { 56 | /* Assign filter stages */ 57 | S->numStages = numStages; 58 | 59 | /* Assign coefficient pointer */ 60 | S->pCoeffs = pCoeffs; 61 | 62 | /* Clear state buffer and size is always 4 * numStages */ 63 | memset(pState, 0, (4U * (uint32_t) numStages) * sizeof(float32_t)); 64 | 65 | /* Assign state pointer */ 66 | S->pState = pState; 67 | } 68 | 69 | /** 70 | * @} end of BiquadCascadeDF1 group 71 | */ 72 | -------------------------------------------------------------------------------- /Src/src/dsp_lib/xtensa_cmplx_dot_prod_f32.c: -------------------------------------------------------------------------------- 1 | 2 | 3 | #include "xtensa_math.h" 4 | 5 | /** 6 | * @ingroup groupCmplxMath 7 | */ 8 | 9 | /** 10 | * @defgroup cmplx_dot_prod Complex Dot Product 11 | * 12 | * Computes the dot product of two complex vectors. 13 | * The vectors are multiplied element-by-element and then summed. 14 | * 15 | * The pSrcA points to the first complex input vector and 16 | * pSrcB points to the second complex input vector. 17 | * numSamples specifies the number of complex samples 18 | * and the data in each array is stored in an interleaved fashion 19 | * (real, imag, real, imag, ...). 20 | * Each array has a total of 2*numSamples values. 21 | * 22 | * The underlying algorithm is used: 23 | *
24 |  * realResult=0;
25 |  * imagResult=0;
26 |  * for(n=0; n
31 |  *
32 |  * There are separate functions for floating-point, Q15, and Q31 data types.
33 |  */
34 | 
35 | /**
36 |  * @addtogroup cmplx_dot_prod
37 |  * @{
38 |  */
39 | 
40 | /**
41 |  * @brief  Floating-point complex dot product
42 |  * @param  *pSrcA points to the first input vector
43 |  * @param  *pSrcB points to the second input vector
44 |  * @param  numSamples number of complex samples in each vector
45 |  * @param  *realResult real part of the result returned here
46 |  * @param  *imagResult imaginary part of the result returned here
47 |  * @return none.
48 |  */
49 | 
50 | void xtensa_cmplx_dot_prod_f32(
51 |   float32_t * pSrcA,
52 |   float32_t * pSrcB,
53 |   uint32_t numSamples,
54 |   float32_t * realResult,
55 |   float32_t * imagResult)
56 | {
57 |   float32_t real_sum = 0.0f, imag_sum = 0.0f;    /* Temporary result storage */
58 |   float32_t a0,b0,c0,d0;
59 | 
60 | 
61 | 
62 | 
63 |   while (numSamples > 0U)
64 |   {
65 |       a0 = *pSrcA++;
66 |       b0 = *pSrcA++;
67 |       c0 = *pSrcB++;
68 |       d0 = *pSrcB++;
69 | 
70 |       real_sum += a0 * c0;
71 |       imag_sum += a0 * d0;
72 |       real_sum -= b0 * d0;
73 |       imag_sum += b0 * c0;
74 | 
75 |       /* Decrement the loop counter */
76 |       numSamples--;
77 |   }
78 | 
79 | 
80 |   /* Store the real and imaginary results in the destination buffers */
81 |   *realResult = real_sum;
82 |   *imagResult = imag_sum;
83 | }
84 | 
85 | /**
86 |  * @} end of cmplx_dot_prod group
87 |  */
88 | 


--------------------------------------------------------------------------------
/Src/fft.h:
--------------------------------------------------------------------------------
 1 | 
 2 | #include "src/dsp_lib/xtensa_const_structs.h"
 3 | 
 4 | xtensa_cfft_instance_f32 cfft;
 5 | xtensa_cfft_instance_f32 rfft;
 6 | 
 7 | float wind[NUM_SAMPLE_BUF];
 8 | 
 9 | void window_init(float *window, int len) 
10 | {
11 |     const float a0 = 0.42;
12 |     const float a1 = 0.5;
13 |     const float a2 = 0.08;
14 | 
15 |     float len_mult = 1/(float)(len-1);
16 |     for (int i = 0; i < len; i++) {
17 |         window[i] = a0 - a1 * cosf(i * 2 * M_PI * len_mult) + a2 * cosf(i * 4 * M_PI * len_mult);
18 |     }
19 | 
20 | }
21 | 
22 | 
23 | void fft_init(){
24 |       cfft = xtensa_cfft_sR_f32_len1024;
25 |       rfft = xtensa_cfft_sR_f32_len512;
26 |       window_init(wind,NUM_SAMPLE_BUF);//Blackman-window
27 |       for(int i=WP_LINE;i>0;i--){wp_num[i-1]=i-1;} //нумеруем массив номеров строк "водопада"
28 | }
29 | 
30 | int IRAM_ATTR sel_c(int val,int max,int mod){
31 | 
32 |   int md = max/mod;
33 |   int i=0;
34 |   if (val<=md)return i;
35 |   for (i=0;i val){return i;}
37 |   }
38 |   return i-1;
39 | }
40 | 
41 | 
42 | void IRAM_ATTR fft_for_display(float* input){
43 | 
44 |     for (int i = 0 ; i < NUM_SAMPLE_BUF; i++) {
45 |       input[i*2] = input[i*2] * wind[i];
46 |       input[i*2+1] = input[i*2+1] * wind[i];
47 |     }
48 |     xtensa_cfft_f32(&rfft,input,0,1);
49 |     for (int i=NUM_SAMPLE_BUF;i12){fft[i]*=0.01f;}else{fft[i]=0;}
59 |         if (max_fft < fft[i])max_fft=fft[i];
60 |         if (min_fft > fft[i])min_fft=fft[i];
61 |         if(fft[i]>=700)fft[i]=700;
62 |         //копирование магнитуд в отображаемый буфер,элементы которого постоянно уменьшаются
63 |         if(fft[i]<=fft_inter[k]) fft[i]=fft_inter[k];
64 |         if(fft[i]>fft_inter[k])fft_inter[k] = fft[i];
65 |         //заполняем верхнюю строку массива для отображения "водопада"
66 |         if(fill_fft)wp[wp_num[0]][k]=colors_w[sel_c((int)fft[i],FWW,CWW)];
67 |         sum_fft = sum_fft+fft[i];
68 |         k++;
69 |     }
70 |     avg_fft = (sum_fft-max_fft)/(NUM_SAMPLE_BUF/2);
71 |     if(max_fft>600  && !dec_Ifgain) dec_Ifgain = true;
72 |     if(avg_fft < 15 && !inc_Ifgain) inc_Ifgain = true;
73 |     if(avg_fft > 20 && !dec_Ifgain) dec_Ifgain = true;   
74 | }
75 | 


--------------------------------------------------------------------------------
/Src/fir.S:
--------------------------------------------------------------------------------
 1 | //(c)Espressif https://github.com/espressif/esp-dsp/blob/master/modules/fir/float/dsps_fir_f32_ae32.S
 2 | 
 3 | // This is FIR filter for ESP32 processor
 4 |   .text
 5 |   .align  4
 6 |   .global fir_f32
 7 |   .type   fir_f32,@function
 8 | // The function implements the following C code:
 9 | //esp_err_t dsps_fir_f32_ae32(fir_s* fir_t, float* input, float* output, int len);
10 | 
11 | fir_f32:
12 | // fir      - a2
13 | // input    - a3
14 | // output   - a4
15 | // len      - a5
16 | 
17 |   entry a1, 16
18 |   // Array increment for floating point data should be 4
19 |   l32i    a7,  a2, 12 // a7  - pos
20 |   movi    a10, 4
21 |   mull    a13, a7, a10// a13 - a7*4
22 |   l32i    a6,  a2, 8  // a6  - N
23 |   mull    a6, a6, a10// a6 = a6*4
24 |   l32i    a10, a2, 0  // a10 - coeffs
25 |   add     a10, a10, a6 // a10 = &coeffs[N];
26 |   addi    a10, a10, -4 // a10 = &coeffs[N-1];
27 |   l32i    a6,  a2, 8  // a6  - N
28 | 
29 |   movi.n a9, 0
30 |   movi.n a8, -4
31 |   movi.n a12, 4
32 | 
33 | //  a13 - delay index
34 | fir_loop_len:
35 |     // Store to delay line
36 |     l32i    a11, a2, 4      // a11 - delay line
37 |     lsi     f0, a3, 0       // f0 = x[i]
38 |     addi    a3, a3, 4       // x++
39 |     ssx     f0, a11, a13    // delay[a13] = f0;
40 |     addi    a13, a13, 4     // a13++
41 |     addi    a7, a7, 1       // a7++
42 |     // verify deley line
43 |     blt     a7, a6, do_not_reset_a13
44 |       movi    a13, 0
45 |       movi    a7,  0
46 |   do_not_reset_a13:
47 |     // Calc amount for delay line before end
48 |     mov     a15, a10        // a15 - coeffs
49 |     wfr     f2, a9 // f2 = 0;
50 |     sub   a14, a6, a7   // a14 = N-pos
51 | 
52 |     // a11 = &delay[pos]
53 |     add     a11, a11, a13
54 | 
55 |     loopnez  a14, first_fir_loop // pos...N-1
56 |       lsxp     f1, a15, a8     // f1 = *(coeffs--)
57 |       lsxp     f0, a11, a12    // load delay f0 = *(delay++)
58 |       madd.s  f2, f0, f1       // f2 += f0*f1
59 | first_fir_loop:
60 |     l32i    a11, a2, 4           // a11 - delay line
61 |     loopnez  a7, second_fir_loop // 0..pos
62 |       lsxp     f1, a15, a8     // f1 = *(coeffs--)
63 |       lsxp     f0, a11, a12    // load delay f0 = *(delay++)
64 |       madd.s  f2, f0, f1      // f2 += f0*f1
65 | second_fir_loop:
66 | 
67 |     // and after end
68 |     // Store result
69 |     ssi     f2, a4, 0
70 |     addi    a4, a4, 4 // y++ - increment output pointer
71 |     // Check loop 
72 |     addi   a5, a5, -1
73 |   bnez    a5, fir_loop_len
74 |   // store state
75 | 
76 |   s32i    a7,  a2, 12 // pos = a7
77 |   movi.n  a2, 0 // return status ESP_OK
78 |   retw.n
79 | 


--------------------------------------------------------------------------------
/Src/init.h:
--------------------------------------------------------------------------------
 1 | 
 2 | 
 3 | void i2sinit(){
 4 |    
 5 |    i2s_config_t i2s_config = {
 6 |     .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_RX | I2S_MODE_TX),
 7 |     .sample_rate = (int) I2S_SAMPLE_RATE,
 8 |     .bits_per_sample = I2S_BITS_PER_SAMPLE_32BIT,
 9 |     .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT,
10 |     .communication_format = I2S_COMM_FORMAT_STAND_I2S,
11 |     .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,
12 |     .dma_buf_count = 4,
13 |     .dma_buf_len = 256,
14 |     .use_apll = false,
15 |     .tx_desc_auto_clear = false,
16 |     .mclk_multiple = I2S_MCLK_MULTIPLE_384 //master-clock on GPIO0
17 |    };
18 |    i2s_pin_config_t pin_config = {
19 |      .mck_io_num =   I2S_MCLK,
20 |      .bck_io_num =   I2S_BCK,
21 |      .ws_io_num =    I2S_WS,
22 |      .data_out_num = I2S_DOUT,
23 |      .data_in_num =  I2S_DIN                                                       
24 |    };
25 |    i2s_driver_install(I2S_NUM_0, &i2s_config, 0, NULL);
26 |    i2s_set_clk(I2S_NUM_0,I2S_SAMPLE_RATE,I2S_BITS_PER_SAMPLE_32BIT,I2S_CHANNEL_STEREO);
27 |    i2s_set_pin(I2S_NUM_0, &pin_config);
28 | }
29 | 
30 | //АЦП для кнопок.Резистивные делители (5/6 резисторов по 1 кОм и 4/5 кнопок на канал)
31 | //номиналы не критичны - имеется программная калибровка в SETUP
32 | void adc_init(){ 
33 |  adc1_config_width(ADC_WIDTH_9Bit);
34 |  adc1_config_channel_atten(LEFT_ADC, ADC_ATTEN_11db);
35 |  adc1_config_channel_atten(RIGHT_ADC, ADC_ATTEN_11db);
36 | }
37 | 
38 | PCF8574 pcf(0x27);
39 | 
40 | void pcf_init(){
41 |  pcf.pinMode(0, OUTPUT);
42 |  pcf.pinMode(1, OUTPUT);
43 |  pcf.pinMode(2, OUTPUT);
44 |  pcf.pinMode(3, OUTPUT);
45 |  pcf.pinMode(4, OUTPUT);
46 |  pcf.digitalWrite(0,LOW);
47 |  pcf.digitalWrite(1,LOW);
48 |  pcf.digitalWrite(2,LOW);
49 |  pcf.digitalWrite(3,LOW);
50 |  pcf.digitalWrite(4,LOW);
51 | }
52 | 
53 | void buf_init(){
54 |   for(int i=0;inumStages = numStages;
61 | 
62 |   /* Assign reflection coefficient pointer */
63 |   S->pkCoeffs = pkCoeffs;
64 | 
65 |   /* Assign ladder coefficient pointer */
66 |   S->pvCoeffs = pvCoeffs;
67 | 
68 |   /* Clear state buffer and size is always blockSize + numStages */
69 |   memset(pState, 0, (numStages + blockSize) * sizeof(float32_t));
70 | 
71 |   /* Assign state pointer */
72 |   S->pState = pState;
73 | 
74 | 
75 | }
76 | 
77 |   /**
78 |    * @} end of IIR_Lattice group
79 |    */
80 | 


--------------------------------------------------------------------------------
/Src/src/dsp_lib/xtensa_cos_f32.c:
--------------------------------------------------------------------------------
 1 | 
 2 | 
 3 | #include "xtensa_math.h"
 4 | #include "xtensa_common_tables.h"
 5 | /**
 6 |  * @ingroup groupFastMath
 7 |  */
 8 | 
 9 | /**
10 |  * @defgroup cos Cosine
11 |  *
12 |  * Computes the trigonometric cosine function using a combination of table lookup
13 |  * and linear interpolation.  There are separate functions for
14 |  * Q15, Q31, and floating-point data types.
15 |  * The input to the floating-point version is in radians and in the range [0 2*pi) while the
16 |  * fixed-point Q15 and Q31 have a scaled input with the range
17 |  * [0 +0.9999] mapping to [0 2*pi).  The fixed-point range is chosen so that a
18 |  * value of 2*pi wraps around to 0.
19 |  *
20 |  * The implementation is based on table lookup using 256 values together with linear interpolation.
21 |  * The steps used are:
22 |  *  -# Calculation of the nearest integer table index
23 |  *  -# Compute the fractional portion (fract) of the table index.
24 |  *  -# The final result equals (1.0f-fract)*a + fract*b;
25 |  *
26 |  * where
27 |  * 
28 |  *    b=Table[index+0];
29 |  *    c=Table[index+1];
30 |  * 
31 | */ 32 | 33 | /** 34 | * @addtogroup cos 35 | * @{ 36 | */ 37 | 38 | /** 39 | * @brief Fast approximation to the trigonometric cosine function for floating-point data. 40 | * @param[in] x input value in radians. 41 | * @return cos(x). 42 | */ 43 | 44 | float32_t xtensa_cos_f32( 45 | float32_t x) 46 | { 47 | float32_t cosVal, fract, in; /* Temporary variables for input, output */ 48 | uint16_t index; /* Index variable */ 49 | float32_t a, b; /* Two nearest output values */ 50 | int32_t n; 51 | float32_t findex; 52 | 53 | /* input x is in radians */ 54 | /* Scale the input to [0 1] range from [0 2*PI] , divide input by 2*pi, add 0.25 (pi/2) to read sine table */ 55 | in = x * 0.159154943092f + 0.25f; 56 | 57 | /* Calculation of floor value of input */ 58 | n = (int32_t) in; 59 | 60 | /* Make negative values towards -infinity */ 61 | if (in < 0.0f) 62 | { 63 | n--; 64 | } 65 | 66 | /* Map input value to [0 1] */ 67 | in = in - (float32_t) n; 68 | 69 | /* Calculation of index of the table */ 70 | findex = (float32_t) FAST_MATH_TABLE_SIZE * in; 71 | index = ((uint16_t)findex) & 0x1ff; 72 | 73 | /* fractional value calculation */ 74 | fract = findex - (float32_t) index; 75 | 76 | /* Read two nearest values of input value from the cos table */ 77 | a = sinTable_f32[index]; 78 | b = sinTable_f32[index+1]; 79 | 80 | /* Linear interpolation process */ 81 | cosVal = (1.0f-fract)*a + fract*b; 82 | 83 | /* Return the output value */ 84 | return (cosVal); 85 | } 86 | 87 | /** 88 | * @} end of cos group 89 | */ 90 | -------------------------------------------------------------------------------- /Src/src/dsp_lib/xtensa_mean_f32.c: -------------------------------------------------------------------------------- 1 | /* ---------------------------------------------------------------------- 2 | * Project: CMSIS DSP Library 3 | * Title: xtensa_mean_f32.c 4 | * Description: Mean value of a floating-point vector 5 | * 6 | * $Date: 27. January 2017 7 | * $Revision: V.1.5.1 8 | * 9 | * Target Processor: Cortex-M cores 10 | * -------------------------------------------------------------------- */ 11 | /* 12 | * Copyright (C) 2010-2017 ARM Limited or its affiliates. All rights reserved. 13 | * 14 | * SPDX-License-Identifier: Apache-2.0 15 | * 16 | * Licensed under the Apache License, Version 2.0 (the License); you may 17 | * not use this file except in compliance with the License. 18 | * You may obtain a copy of the License at 19 | * 20 | * www.apache.org/licenses/LICENSE-2.0 21 | * 22 | * Unless required by applicable law or agreed to in writing, software 23 | * distributed under the License is distributed on an AS IS BASIS, WITHOUT 24 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 25 | * See the License for the specific language governing permissions and 26 | * limitations under the License. 27 | */ 28 | 29 | #include "xtensa_math.h" 30 | 31 | /** 32 | * @ingroup groupStats 33 | */ 34 | 35 | /** 36 | * @defgroup mean Mean 37 | * 38 | * Calculates the mean of the input vector. Mean is defined as the average of the elements in the vector. 39 | * The underlying algorithm is used: 40 | * 41 | *
42 |  * 	Result = (pSrc[0] + pSrc[1] + pSrc[2] + ... + pSrc[blockSize-1]) / blockSize;
43 |  * 
44 | * 45 | * There are separate functions for floating-point, Q31, Q15, and Q7 data types. 46 | */ 47 | 48 | /** 49 | * @addtogroup mean 50 | * @{ 51 | */ 52 | 53 | 54 | /** 55 | * @brief Mean value of a floating-point vector. 56 | * @param[in] *pSrc points to the input vector 57 | * @param[in] blockSize length of the input vector 58 | * @param[out] *pResult mean value returned here 59 | * @return none. 60 | */ 61 | 62 | void xtensa_mean_f32( 63 | float32_t * pSrc, 64 | uint32_t blockSize, 65 | float32_t * pResult) 66 | { 67 | float32_t sum = 0.0f; /* Temporary result storage */ 68 | uint32_t blkCnt; /* loop counter */ 69 | 70 | 71 | 72 | /* Loop over blockSize number of values */ 73 | blkCnt = blockSize; 74 | 75 | 76 | while (blkCnt > 0U) 77 | { 78 | /* C = (A[0] + A[1] + A[2] + ... + A[blockSize-1]) */ 79 | sum += *pSrc++; 80 | 81 | /* Decrement the loop counter */ 82 | blkCnt--; 83 | } 84 | 85 | /* C = (A[0] + A[1] + A[2] + ... + A[blockSize-1]) / blockSize */ 86 | /* Store the result to the destination */ 87 | *pResult = sum / (float32_t) blockSize; 88 | } 89 | 90 | /** 91 | * @} end of mean group 92 | */ 93 | -------------------------------------------------------------------------------- /Src/src/dsp_lib/xtensa_fir_init_f32.c: -------------------------------------------------------------------------------- 1 | /* ---------------------------------------------------------------------- 2 | * Project: CMSIS DSP Library 3 | * Title: xtensa_fir_init_f32.c 4 | * Description: Floating-point FIR filter initialization function 5 | * 6 | * $Date: 27. January 2017 7 | * $Revision: V.1.5.1 8 | * 9 | * Target Processor: Cortex-M cores 10 | * -------------------------------------------------------------------- */ 11 | /* 12 | * Copyright (C) 2010-2017 ARM Limited or its affiliates. All rights reserved. 13 | * 14 | * SPDX-License-Identifier: Apache-2.0 15 | * 16 | * Licensed under the Apache License, Version 2.0 (the License); you may 17 | * not use this file except in compliance with the License. 18 | * You may obtain a copy of the License at 19 | * 20 | * www.apache.org/licenses/LICENSE-2.0 21 | * 22 | * Unless required by applicable law or agreed to in writing, software 23 | * distributed under the License is distributed on an AS IS BASIS, WITHOUT 24 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 25 | * See the License for the specific language governing permissions and 26 | * limitations under the License. 27 | */ 28 | 29 | #include "xtensa_math.h" 30 | 31 | /** 32 | * @ingroup groupFilters 33 | */ 34 | 35 | /** 36 | * @addtogroup FIR 37 | * @{ 38 | */ 39 | 40 | /** 41 | * @details 42 | * 43 | * @param[in,out] *S points to an instance of the floating-point FIR filter structure. 44 | * @param[in] numTaps Number of filter coefficients in the filter. 45 | * @param[in] *pCoeffs points to the filter coefficients buffer. 46 | * @param[in] *pState points to the state buffer. 47 | * @param[in] blockSize number of samples that are processed per call. 48 | * @return none. 49 | * 50 | * Description: 51 | * \par 52 | * pCoeffs points to the array of filter coefficients stored in time reversed order: 53 | *
54 |  *    {b[numTaps-1], b[numTaps-2], b[N-2], ..., b[1], b[0]}
55 |  * 
56 | * \par 57 | * pState points to the array of state variables. 58 | * pState is of length numTaps+blockSize-1 samples, where blockSize is the number of input samples processed by each call to xtensa_fir_f32(). 59 | */ 60 | 61 | void xtensa_fir_init_f32( 62 | xtensa_fir_instance_f32 * S, 63 | uint16_t numTaps, 64 | float32_t * pCoeffs, 65 | float32_t * pState, 66 | uint32_t blockSize) 67 | { 68 | /* Assign filter taps */ 69 | S->numTaps = numTaps; 70 | 71 | /* Assign coefficient pointer */ 72 | S->pCoeffs = pCoeffs; 73 | 74 | /* Clear state buffer and the size of state buffer is (blockSize + numTaps - 1) */ 75 | memset(pState, 0, (numTaps + (blockSize - 1U)) * sizeof(float32_t)); 76 | 77 | /* Assign state pointer */ 78 | S->pState = pState; 79 | 80 | } 81 | 82 | /** 83 | * @} end of FIR group 84 | */ 85 | -------------------------------------------------------------------------------- /Src/src/dsp_lib/xtensa_sin_f32.c: -------------------------------------------------------------------------------- 1 | 2 | 3 | #include "xtensa_math.h" 4 | #include "xtensa_common_tables.h" 5 | #include 6 | 7 | /** 8 | * @ingroup groupFastMath 9 | */ 10 | 11 | /** 12 | * @defgroup sin Sine 13 | * 14 | * Computes the trigonometric sine function using a combination of table lookup 15 | * and linear interpolation. There are separate functions for 16 | * Q15, Q31, and floating-point data types. 17 | * The input to the floating-point version is in radians and in the range [0 2*pi) while the 18 | * fixed-point Q15 and Q31 have a scaled input with the range 19 | * [0 +0.9999] mapping to [0 2*pi). The fixed-point range is chosen so that a 20 | * value of 2*pi wraps around to 0. 21 | * 22 | * The implementation is based on table lookup using 256 values together with linear interpolation. 23 | * The steps used are: 24 | * -# Calculation of the nearest integer table index 25 | * -# Compute the fractional portion (fract) of the table index. 26 | * -# The final result equals (1.0f-fract)*a + fract*b; 27 | * 28 | * where 29 | *
30 |  *    b=Table[index+0];
31 |  *    c=Table[index+1];
32 |  * 
33 | */ 34 | 35 | /** 36 | * @addtogroup sin 37 | * @{ 38 | */ 39 | 40 | /** 41 | * @brief Fast approximation to the trigonometric sine function for floating-point data. 42 | * @param[in] x input value in radians. 43 | * @return sin(x). 44 | */ 45 | 46 | float32_t xtensa_sin_f32( 47 | float32_t x) 48 | { 49 | float32_t sinVal, fract, in; /* Temporary variables for input, output */ 50 | uint16_t index; /* Index variable */ 51 | float32_t a, b; /* Two nearest output values */ 52 | int32_t n; 53 | float32_t findex; 54 | 55 | /* Special case for small negative inputs */ 56 | if ((x < 0.0f) && (x >= -1.9e-7f)) { 57 | return x; 58 | } 59 | 60 | /* input x is in radians */ 61 | /* Scale the input to [0 1] range from [0 2*PI] , divide input by 2*pi */ 62 | in = x * 0.159154943092f; 63 | 64 | /* Calculation of floor value of input */ 65 | n = (int32_t) in; 66 | 67 | /* Make negative values towards -infinity */ 68 | if (x < 0.0f) 69 | { 70 | n--; 71 | } 72 | 73 | /* Map input value to [0 1] */ 74 | in = in - (float32_t) n; 75 | 76 | /* Calculation of index of the table */ 77 | findex = (float32_t) FAST_MATH_TABLE_SIZE * in; 78 | 79 | index = ((uint16_t)findex) & 0x1ff; 80 | 81 | /* fractional value calculation */ 82 | fract = findex - (float32_t) index; 83 | 84 | /* Read two nearest values of input value from the sin table */ 85 | a = sinTable_f32[index]; 86 | b = sinTable_f32[index+1]; 87 | 88 | /* Linear interpolation process */ 89 | sinVal = (1.0f-fract)*a + fract*b; 90 | 91 | /* Return the output value */ 92 | return (sinVal); 93 | } 94 | 95 | /** 96 | * @} end of sin group 97 | */ 98 | -------------------------------------------------------------------------------- /Src/src/dsp_lib/xtensa_lms_init_f32.c: -------------------------------------------------------------------------------- 1 | /* ---------------------------------------------------------------------- 2 | * Project: CMSIS DSP Library 3 | * Title: xtensa_lms_init_f32.c 4 | * Description: Floating-point LMS filter initialization function 5 | * 6 | * $Date: 27. January 2017 7 | * $Revision: V.1.5.1 8 | * 9 | * Target Processor: Cortex-M cores 10 | * -------------------------------------------------------------------- */ 11 | /* 12 | * Copyright (C) 2010-2017 ARM Limited or its affiliates. All rights reserved. 13 | * 14 | * SPDX-License-Identifier: Apache-2.0 15 | * 16 | * Licensed under the Apache License, Version 2.0 (the License); you may 17 | * not use this file except in compliance with the License. 18 | * You may obtain a copy of the License at 19 | * 20 | * www.apache.org/licenses/LICENSE-2.0 21 | * 22 | * Unless required by applicable law or agreed to in writing, software 23 | * distributed under the License is distributed on an AS IS BASIS, WITHOUT 24 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 25 | * See the License for the specific language governing permissions and 26 | * limitations under the License. 27 | */ 28 | 29 | #include "xtensa_math.h" 30 | 31 | /** 32 | * @addtogroup LMS 33 | * @{ 34 | */ 35 | 36 | /** 37 | * @brief Initialization function for floating-point LMS filter. 38 | * @param[in] *S points to an instance of the floating-point LMS filter structure. 39 | * @param[in] numTaps number of filter coefficients. 40 | * @param[in] *pCoeffs points to the coefficient buffer. 41 | * @param[in] *pState points to state buffer. 42 | * @param[in] mu step size that controls filter coefficient updates. 43 | * @param[in] blockSize number of samples to process. 44 | * @return none. 45 | */ 46 | 47 | /** 48 | * \par Description: 49 | * pCoeffs points to the array of filter coefficients stored in time reversed order: 50 | *
51 |  *    {b[numTaps-1], b[numTaps-2], b[N-2], ..., b[1], b[0]}
52 |  * 
53 | * The initial filter coefficients serve as a starting point for the adaptive filter. 54 | * pState points to an array of length numTaps+blockSize-1 samples, where blockSize is the number of input samples processed by each call to xtensa_lms_f32(). 55 | */ 56 | 57 | void xtensa_lms_init_f32( 58 | xtensa_lms_instance_f32 * S, 59 | uint16_t numTaps, 60 | float32_t * pCoeffs, 61 | float32_t * pState, 62 | float32_t mu, 63 | uint32_t blockSize) 64 | { 65 | /* Assign filter taps */ 66 | S->numTaps = numTaps; 67 | 68 | /* Assign coefficient pointer */ 69 | S->pCoeffs = pCoeffs; 70 | 71 | /* Clear state buffer and size is always blockSize + numTaps */ 72 | memset(pState, 0, (numTaps + (blockSize - 1)) * sizeof(float32_t)); 73 | 74 | /* Assign state pointer */ 75 | S->pState = pState; 76 | 77 | /* Assign Step size value */ 78 | S->mu = mu; 79 | } 80 | 81 | /** 82 | * @} end of LMS group 83 | */ 84 | -------------------------------------------------------------------------------- /Src/src/dsp_lib/xtensa_power_f32.c: -------------------------------------------------------------------------------- 1 | /* ---------------------------------------------------------------------- 2 | * Project: CMSIS DSP Library 3 | * Title: xtensa_power_f32.c 4 | * Description: Sum of the squares of the elements of a floating-point vector 5 | * 6 | * $Date: 27. January 2017 7 | * $Revision: V.1.5.1 8 | * 9 | * Target Processor: Cortex-M cores 10 | * -------------------------------------------------------------------- */ 11 | /* 12 | * Copyright (C) 2010-2017 ARM Limited or its affiliates. All rights reserved. 13 | * 14 | * SPDX-License-Identifier: Apache-2.0 15 | * 16 | * Licensed under the Apache License, Version 2.0 (the License); you may 17 | * not use this file except in compliance with the License. 18 | * You may obtain a copy of the License at 19 | * 20 | * www.apache.org/licenses/LICENSE-2.0 21 | * 22 | * Unless required by applicable law or agreed to in writing, software 23 | * distributed under the License is distributed on an AS IS BASIS, WITHOUT 24 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 25 | * See the License for the specific language governing permissions and 26 | * limitations under the License. 27 | */ 28 | 29 | #include "xtensa_math.h" 30 | 31 | /** 32 | * @ingroup groupStats 33 | */ 34 | 35 | /** 36 | * @defgroup power Power 37 | * 38 | * Calculates the sum of the squares of the elements in the input vector. 39 | * The underlying algorithm is used: 40 | * 41 | *
42 |  * 	Result = pSrc[0] * pSrc[0] + pSrc[1] * pSrc[1] + pSrc[2] * pSrc[2] + ... + pSrc[blockSize-1] * pSrc[blockSize-1];
43 |  * 
44 | * 45 | * There are separate functions for floating point, Q31, Q15, and Q7 data types. 46 | */ 47 | 48 | /** 49 | * @addtogroup power 50 | * @{ 51 | */ 52 | 53 | 54 | /** 55 | * @brief Sum of the squares of the elements of a floating-point vector. 56 | * @param[in] *pSrc points to the input vector 57 | * @param[in] blockSize length of the input vector 58 | * @param[out] *pResult sum of the squares value returned here 59 | * @return none. 60 | * 61 | */ 62 | 63 | 64 | void xtensa_power_f32( 65 | float32_t * pSrc, 66 | uint32_t blockSize, 67 | float32_t * pResult) 68 | { 69 | float32_t sum = 0.0f; /* accumulator */ 70 | float32_t in; /* Temporary variable to store input value */ 71 | uint32_t blkCnt; /* loop counter */ 72 | 73 | 74 | 75 | /* Loop over blockSize number of values */ 76 | blkCnt = blockSize; 77 | 78 | 79 | 80 | while (blkCnt > 0U) 81 | { 82 | /* C = A[0] * A[0] + A[1] * A[1] + A[2] * A[2] + ... + A[blockSize-1] * A[blockSize-1] */ 83 | /* compute power and then store the result in a temporary variable, sum. */ 84 | in = *pSrc++; 85 | sum += in * in; 86 | 87 | /* Decrement the loop counter */ 88 | blkCnt--; 89 | } 90 | 91 | /* Store the result to the destination */ 92 | *pResult = sum; 93 | } 94 | 95 | /** 96 | * @} end of power group 97 | */ 98 | -------------------------------------------------------------------------------- /Src/src/dsp_lib/xtensa_rms_f32.c: -------------------------------------------------------------------------------- 1 | /* ---------------------------------------------------------------------- 2 | * Project: CMSIS DSP Library 3 | * Title: xtensa_rms_f32.c 4 | * Description: Root mean square value of an array of F32 type 5 | * 6 | * $Date: 27. January 2017 7 | * $Revision: V.1.5.1 8 | * 9 | * Target Processor: Cortex-M cores 10 | * -------------------------------------------------------------------- */ 11 | /* 12 | * Copyright (C) 2010-2017 ARM Limited or its affiliates. All rights reserved. 13 | * 14 | * SPDX-License-Identifier: Apache-2.0 15 | * 16 | * Licensed under the Apache License, Version 2.0 (the License); you may 17 | * not use this file except in compliance with the License. 18 | * You may obtain a copy of the License at 19 | * 20 | * www.apache.org/licenses/LICENSE-2.0 21 | * 22 | * Unless required by applicable law or agreed to in writing, software 23 | * distributed under the License is distributed on an AS IS BASIS, WITHOUT 24 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 25 | * See the License for the specific language governing permissions and 26 | * limitations under the License. 27 | */ 28 | 29 | #include "xtensa_math.h" 30 | 31 | /** 32 | * @ingroup groupStats 33 | */ 34 | 35 | /** 36 | * @defgroup RMS Root mean square (RMS) 37 | * 38 | * 39 | * Calculates the Root Mean Sqaure of the elements in the input vector. 40 | * The underlying algorithm is used: 41 | * 42 | *
43 |  * 	Result = sqrt(((pSrc[0] * pSrc[0] + pSrc[1] * pSrc[1] + ... + pSrc[blockSize-1] * pSrc[blockSize-1]) / blockSize));
44 |  * 
45 | * 46 | * There are separate functions for floating point, Q31, and Q15 data types. 47 | */ 48 | 49 | /** 50 | * @addtogroup RMS 51 | * @{ 52 | */ 53 | 54 | 55 | /** 56 | * @brief Root Mean Square of the elements of a floating-point vector. 57 | * @param[in] *pSrc points to the input vector 58 | * @param[in] blockSize length of the input vector 59 | * @param[out] *pResult rms value returned here 60 | * @return none. 61 | * 62 | */ 63 | 64 | void xtensa_rms_f32( 65 | float32_t * pSrc, 66 | uint32_t blockSize, 67 | float32_t * pResult) 68 | { 69 | float32_t sum = 0.0f; /* Accumulator */ 70 | float32_t in; /* Tempoprary variable to store input value */ 71 | uint32_t blkCnt; /* loop counter */ 72 | 73 | 74 | 75 | /* Loop over blockSize number of values */ 76 | blkCnt = blockSize; 77 | 78 | 79 | while (blkCnt > 0U) 80 | { 81 | /* C = A[0] * A[0] + A[1] * A[1] + A[2] * A[2] + ... + A[blockSize-1] * A[blockSize-1] */ 82 | /* Compute sum of the squares and then store the results in a temporary variable, sum */ 83 | in = *pSrc++; 84 | sum += in * in; 85 | 86 | /* Decrement the loop counter */ 87 | blkCnt--; 88 | } 89 | 90 | /* Compute Rms and store the result in the destination */ 91 | xtensa_sqrt_f32(sum / (float32_t) blockSize, pResult); 92 | } 93 | 94 | /** 95 | * @} end of RMS group 96 | */ 97 | -------------------------------------------------------------------------------- /Src/ESP32-SDR-TRX.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include //https://github.com/etherkit/Si5351Arduino 6 | #include //https://github.com/xreef/PCF8574_library 7 | #undef DEBUG_PRINTLN 8 | #undef DEBUG_PRINT 9 | #include //https://github.com/igorantolic/ai-esp32-rotary-encoder 10 | #include //https://github.com/bitluni/ESP32Lib 11 | #include //должна быть установлена библиотека GFX-Adafruit https://github.com/adafruit/Adafruit-GFX-Library 12 | #include 13 | #include "src/dsp_lib/xtensa_math.h" //taken from https://github.com/whyengineer/esp32-lin/tree/master/components/dsp_lib 14 | #include "include/s7.h" //7-segments font 15 | #include "include/images.h" 16 | #include "wm8731.h" 17 | #include "global.h" 18 | #include "fft.h" 19 | #include "filters.h" 20 | #include "init.h" 21 | #include "key.h" 22 | #include "rx.h" 23 | #include "tx.h" 24 | #include "screens.h" 25 | #include "tools.h" 26 | 27 | 28 | 29 | 30 | void setup() { 31 | 32 | Serial.begin(115200,SERIAL_8N1,-1,TX_SERIAL);//только serial-TX 33 | pinMode(PTT,INPUT_PULLUP); 34 | EEPROM.begin(sizeof(uint32_t)*32); 35 | readConfig(); //восстанавливаем значения 36 | 37 | vSemaphoreCreateBinary(xRXDSP); 38 | vSemaphoreCreateBinary(xRXIN); 39 | vSemaphoreCreateBinary(xRXOUT); 40 | vSemaphoreCreateBinary(xTXDSP); 41 | vSemaphoreCreateBinary(xTXIN); 42 | vSemaphoreCreateBinary(xTXOUT); 43 | 44 | rotaryEncoder.begin(); 45 | pinMode(ROTARY_ENCODER_BUTTON_PIN,INPUT_PULLUP); 46 | rotaryEncoder.setup( 47 | [] { rotaryEncoder.readEncoder_ISR(); }, 48 | [] { NULL; }); 49 | rotaryEncoder.disableAcceleration(); 50 | Wire.begin(I2C_SDA,I2C_SCL); 51 | Wire.setClock(400000); 52 | si = si5351.init(SI5351_CRYSTAL_LOAD_8PF, 0, 0); 53 | if(si){si5351.set_freq(1228800000L,SI5351_CLK0);//to do clock wm8731 in master-mode 54 | si5351.output_enable(SI5351_CLK0, 1); 55 | Serial.println("SI5351 OK");} 56 | else{Serial.println("SI5351 not OK");} 57 | wm8731_init(); 58 | pcf_init(); 59 | adc_init(); 60 | fft_init(); 61 | buf_init(); 62 | i2sinit();//I2S0 63 | xTaskCreatePinnedToCore(rx_in, "rxin", 2048, NULL, 100, NULL, 1);// 64 | xTaskCreatePinnedToCore(rx_out, "rxout", 2048, NULL, 110, NULL, 1);// 65 | xTaskCreatePinnedToCore(rx_dsp, "rxdsp", 2048, NULL, 220, NULL, 0);// 66 | xTaskCreatePinnedToCore(tx_in, "txin", 2048, NULL, 221, NULL, 1);// 67 | xTaskCreatePinnedToCore(tx_out, "txout", 2048, NULL, 109, NULL, 1);// 68 | xTaskCreatePinnedToCore(tx_dsp, "txdsp", 2048, NULL, 219, NULL, 0);// 69 | 70 | #ifdef VGA 71 | tft.init(myMode,RED0,RED1,GREEN0,GREEN1,BLUE0,BLUE1,HSYNCPIN,DEPIN); 72 | #else 73 | tft.init(tft.MODE480x272,RED0,RED1,GREEN0,GREEN1,BLUE0,BLUE1,HSYNCPIN,DEPIN,CLOCKPIN); 74 | #endif 75 | start_ok(); 76 | //нажатие энкодера во время заставки вызывает экран настройки кнопок 77 | //нажатие энкодера во время приема сохраняет основные настройки для их восстановления при последующем включении 78 | } 79 | 80 | void loop() { 81 | control(); 82 | screens(current_mode); 83 | } 84 | -------------------------------------------------------------------------------- /Src/src/dsp_lib/xtensa_max_f32.c: -------------------------------------------------------------------------------- 1 | /* ---------------------------------------------------------------------- 2 | * Project: CMSIS DSP Library 3 | * Title: xtensa_max_f32.c 4 | * Description: Maximum value of a floating-point vector 5 | * 6 | * $Date: 27. January 2017 7 | * $Revision: V.1.5.1 8 | * 9 | * Target Processor: Cortex-M cores 10 | * -------------------------------------------------------------------- */ 11 | /* 12 | * Copyright (C) 2010-2017 ARM Limited or its affiliates. All rights reserved. 13 | * 14 | * SPDX-License-Identifier: Apache-2.0 15 | * 16 | * Licensed under the Apache License, Version 2.0 (the License); you may 17 | * not use this file except in compliance with the License. 18 | * You may obtain a copy of the License at 19 | * 20 | * www.apache.org/licenses/LICENSE-2.0 21 | * 22 | * Unless required by applicable law or agreed to in writing, software 23 | * distributed under the License is distributed on an AS IS BASIS, WITHOUT 24 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 25 | * See the License for the specific language governing permissions and 26 | * limitations under the License. 27 | */ 28 | 29 | #include "xtensa_math.h" 30 | 31 | /** 32 | * @ingroup groupStats 33 | */ 34 | 35 | /** 36 | * @defgroup Max Maximum 37 | * 38 | * Computes the maximum value of an array of data. 39 | * The function returns both the maximum value and its position within the array. 40 | * There are separate functions for floating-point, Q31, Q15, and Q7 data types. 41 | */ 42 | 43 | /** 44 | * @addtogroup Max 45 | * @{ 46 | */ 47 | 48 | 49 | /** 50 | * @brief Maximum value of a floating-point vector. 51 | * @param[in] *pSrc points to the input vector 52 | * @param[in] blockSize length of the input vector 53 | * @param[out] *pResult maximum value returned here 54 | * @param[out] *pIndex index of maximum value returned here 55 | * @return none. 56 | */ 57 | 58 | void xtensa_max_f32( 59 | float32_t * pSrc, 60 | uint32_t blockSize, 61 | float32_t * pResult, 62 | uint32_t * pIndex) 63 | { 64 | 65 | 66 | float32_t maxVal1, out; /* Temporary variables to store the output value. */ 67 | uint32_t blkCnt, outIndex; /* loop counter */ 68 | 69 | /* Initialise the index value to zero. */ 70 | outIndex = 0U; 71 | /* Load first input value that act as reference value for comparision */ 72 | out = *pSrc++; 73 | 74 | blkCnt = (blockSize - 1U); 75 | 76 | 77 | while (blkCnt > 0U) 78 | { 79 | /* Initialize maxVal to the next consecutive values one by one */ 80 | maxVal1 = *pSrc++; 81 | 82 | /* compare for the maximum value */ 83 | if (out < maxVal1) 84 | { 85 | /* Update the maximum value and it's index */ 86 | out = maxVal1; 87 | outIndex = blockSize - blkCnt; 88 | } 89 | 90 | /* Decrement the loop counter */ 91 | blkCnt--; 92 | } 93 | 94 | /* Store the maximum value and it's index into destination pointers */ 95 | *pResult = out; 96 | *pIndex = outIndex; 97 | } 98 | 99 | /** 100 | * @} end of Max group 101 | */ 102 | -------------------------------------------------------------------------------- /Src/src/dsp_lib/xtensa_min_f32.c: -------------------------------------------------------------------------------- 1 | /* ---------------------------------------------------------------------- 2 | * Project: CMSIS DSP Library 3 | * Title: xtensa_min_f32.c 4 | * Description: Minimum value of a floating-point vector 5 | * 6 | * $Date: 27. January 2017 7 | * $Revision: V.1.5.1 8 | * 9 | * Target Processor: Cortex-M cores 10 | * -------------------------------------------------------------------- */ 11 | /* 12 | * Copyright (C) 2010-2017 ARM Limited or its affiliates. All rights reserved. 13 | * 14 | * SPDX-License-Identifier: Apache-2.0 15 | * 16 | * Licensed under the Apache License, Version 2.0 (the License); you may 17 | * not use this file except in compliance with the License. 18 | * You may obtain a copy of the License at 19 | * 20 | * www.apache.org/licenses/LICENSE-2.0 21 | * 22 | * Unless required by applicable law or agreed to in writing, software 23 | * distributed under the License is distributed on an AS IS BASIS, WITHOUT 24 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 25 | * See the License for the specific language governing permissions and 26 | * limitations under the License. 27 | */ 28 | 29 | #include "xtensa_math.h" 30 | 31 | /** 32 | * @ingroup groupStats 33 | */ 34 | 35 | /** 36 | * @defgroup Min Minimum 37 | * 38 | * Computes the minimum value of an array of data. 39 | * The function returns both the minimum value and its position within the array. 40 | * There are separate functions for floating-point, Q31, Q15, and Q7 data types. 41 | */ 42 | 43 | /** 44 | * @addtogroup Min 45 | * @{ 46 | */ 47 | 48 | 49 | /** 50 | * @brief Minimum value of a floating-point vector. 51 | * @param[in] *pSrc points to the input vector 52 | * @param[in] blockSize length of the input vector 53 | * @param[out] *pResult minimum value returned here 54 | * @param[out] *pIndex index of minimum value returned here 55 | * @return none. 56 | */ 57 | 58 | void xtensa_min_f32( 59 | float32_t * pSrc, 60 | uint32_t blockSize, 61 | float32_t * pResult, 62 | uint32_t * pIndex) 63 | { 64 | 65 | 66 | float32_t minVal1, out; /* Temporary variables to store the output value. */ 67 | uint32_t blkCnt, outIndex; /* loop counter */ 68 | 69 | /* Initialise the index value to zero. */ 70 | outIndex = 0U; 71 | /* Load first input value that act as reference value for comparision */ 72 | out = *pSrc++; 73 | 74 | blkCnt = (blockSize - 1U); 75 | 76 | 77 | while (blkCnt > 0U) 78 | { 79 | /* Initialize minVal to the next consecutive values one by one */ 80 | minVal1 = *pSrc++; 81 | 82 | /* compare for the minimum value */ 83 | if (out > minVal1) 84 | { 85 | /* Update the minimum value and it's index */ 86 | out = minVal1; 87 | outIndex = blockSize - blkCnt; 88 | } 89 | 90 | /* Decrement the loop counter */ 91 | blkCnt--; 92 | } 93 | 94 | /* Store the minimum value and it's index into destination pointers */ 95 | *pResult = out; 96 | *pIndex = outIndex; 97 | } 98 | 99 | /** 100 | * @} end of Min group 101 | */ 102 | -------------------------------------------------------------------------------- /Src/src/dsp_lib/xtensa_lms_norm_init_f32.c: -------------------------------------------------------------------------------- 1 | /* ---------------------------------------------------------------------- 2 | * Project: CMSIS DSP Library 3 | * Title: xtensa_lms_norm_init_f32.c 4 | * Description: Floating-point NLMS filter initialization function 5 | * 6 | * $Date: 27. January 2017 7 | * $Revision: V.1.5.1 8 | * 9 | * Target Processor: Cortex-M cores 10 | * -------------------------------------------------------------------- */ 11 | /* 12 | * Copyright (C) 2010-2017 ARM Limited or its affiliates. All rights reserved. 13 | * 14 | * SPDX-License-Identifier: Apache-2.0 15 | * 16 | * Licensed under the Apache License, Version 2.0 (the License); you may 17 | * not use this file except in compliance with the License. 18 | * You may obtain a copy of the License at 19 | * 20 | * www.apache.org/licenses/LICENSE-2.0 21 | * 22 | * Unless required by applicable law or agreed to in writing, software 23 | * distributed under the License is distributed on an AS IS BASIS, WITHOUT 24 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 25 | * See the License for the specific language governing permissions and 26 | * limitations under the License. 27 | */ 28 | 29 | #include "xtensa_math.h" 30 | 31 | /** 32 | * @ingroup groupFilters 33 | */ 34 | 35 | /** 36 | * @addtogroup LMS_NORM 37 | * @{ 38 | */ 39 | 40 | /** 41 | * @brief Initialization function for floating-point normalized LMS filter. 42 | * @param[in] *S points to an instance of the floating-point LMS filter structure. 43 | * @param[in] numTaps number of filter coefficients. 44 | * @param[in] *pCoeffs points to coefficient buffer. 45 | * @param[in] *pState points to state buffer. 46 | * @param[in] mu step size that controls filter coefficient updates. 47 | * @param[in] blockSize number of samples to process. 48 | * @return none. 49 | * 50 | * \par Description: 51 | * pCoeffs points to the array of filter coefficients stored in time reversed order: 52 | *
53 |  *    {b[numTaps-1], b[numTaps-2], b[N-2], ..., b[1], b[0]}
54 |  * 
55 | * The initial filter coefficients serve as a starting point for the adaptive filter. 56 | * pState points to an array of length numTaps+blockSize-1 samples, 57 | * where blockSize is the number of input samples processed by each call to xtensa_lms_norm_f32(). 58 | */ 59 | 60 | void xtensa_lms_norm_init_f32( 61 | xtensa_lms_norm_instance_f32 * S, 62 | uint16_t numTaps, 63 | float32_t * pCoeffs, 64 | float32_t * pState, 65 | float32_t mu, 66 | uint32_t blockSize) 67 | { 68 | /* Assign filter taps */ 69 | S->numTaps = numTaps; 70 | 71 | /* Assign coefficient pointer */ 72 | S->pCoeffs = pCoeffs; 73 | 74 | /* Clear state buffer and size is always blockSize + numTaps - 1 */ 75 | memset(pState, 0, (numTaps + (blockSize - 1U)) * sizeof(float32_t)); 76 | 77 | /* Assign state pointer */ 78 | S->pState = pState; 79 | 80 | /* Assign Step size value */ 81 | S->mu = mu; 82 | 83 | /* Initialise Energy to zero */ 84 | S->energy = 0.0f; 85 | 86 | /* Initialise x0 to zero */ 87 | S->x0 = 0.0f; 88 | 89 | } 90 | 91 | /** 92 | * @} end of LMS_NORM group 93 | */ 94 | -------------------------------------------------------------------------------- /Src/src/dsp_lib/xtensa_fir_sparse_init_f32.c: -------------------------------------------------------------------------------- 1 | /* ---------------------------------------------------------------------- 2 | * Project: CMSIS DSP Library 3 | * Title: xtensa_fir_sparse_init_f32.c 4 | * Description: Floating-point sparse FIR filter initialization function 5 | * 6 | * $Date: 27. January 2017 7 | * $Revision: V.1.5.1 8 | * 9 | * Target Processor: Cortex-M cores 10 | * -------------------------------------------------------------------- */ 11 | /* 12 | * Copyright (C) 2010-2017 ARM Limited or its affiliates. All rights reserved. 13 | * 14 | * SPDX-License-Identifier: Apache-2.0 15 | * 16 | * Licensed under the Apache License, Version 2.0 (the License); you may 17 | * not use this file except in compliance with the License. 18 | * You may obtain a copy of the License at 19 | * 20 | * www.apache.org/licenses/LICENSE-2.0 21 | * 22 | * Unless required by applicable law or agreed to in writing, software 23 | * distributed under the License is distributed on an AS IS BASIS, WITHOUT 24 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 25 | * See the License for the specific language governing permissions and 26 | * limitations under the License. 27 | */ 28 | 29 | #include "xtensa_math.h" 30 | 31 | /** 32 | * @ingroup groupFilters 33 | */ 34 | 35 | /** 36 | * @addtogroup FIR_Sparse 37 | * @{ 38 | */ 39 | 40 | /** 41 | * @brief Initialization function for the floating-point sparse FIR filter. 42 | * @param[in,out] *S points to an instance of the floating-point sparse FIR structure. 43 | * @param[in] numTaps number of nonzero coefficients in the filter. 44 | * @param[in] *pCoeffs points to the array of filter coefficients. 45 | * @param[in] *pState points to the state buffer. 46 | * @param[in] *pTapDelay points to the array of offset times. 47 | * @param[in] maxDelay maximum offset time supported. 48 | * @param[in] blockSize number of samples that will be processed per block. 49 | * @return none 50 | * 51 | * Description: 52 | * \par 53 | * pCoeffs holds the filter coefficients and has length numTaps. 54 | * pState holds the filter's state variables and must be of length 55 | * maxDelay + blockSize, where maxDelay 56 | * is the maximum number of delay line values. 57 | * blockSize is the 58 | * number of samples processed by the xtensa_fir_sparse_f32() function. 59 | */ 60 | 61 | void xtensa_fir_sparse_init_f32( 62 | xtensa_fir_sparse_instance_f32 * S, 63 | uint16_t numTaps, 64 | float32_t * pCoeffs, 65 | float32_t * pState, 66 | int32_t * pTapDelay, 67 | uint16_t maxDelay, 68 | uint32_t blockSize) 69 | { 70 | /* Assign filter taps */ 71 | S->numTaps = numTaps; 72 | 73 | /* Assign coefficient pointer */ 74 | S->pCoeffs = pCoeffs; 75 | 76 | /* Assign TapDelay pointer */ 77 | S->pTapDelay = pTapDelay; 78 | 79 | /* Assign MaxDelay */ 80 | S->maxDelay = maxDelay; 81 | 82 | /* reset the stateIndex to 0 */ 83 | S->stateIndex = 0U; 84 | 85 | /* Clear state buffer and size is always maxDelay + blockSize */ 86 | memset(pState, 0, (maxDelay + blockSize) * sizeof(float32_t)); 87 | 88 | /* Assign state pointer */ 89 | S->pState = pState; 90 | 91 | } 92 | 93 | /** 94 | * @} end of FIR_Sparse group 95 | */ 96 | -------------------------------------------------------------------------------- /Src/src/dsp_lib/xtensa_biquad_cascade_df2T_init_f32.c: -------------------------------------------------------------------------------- 1 | /* ---------------------------------------------------------------------- 2 | * Project: CMSIS DSP Library 3 | * Title: xtensa_biquad_cascade_df2T_init_f32.c 4 | * Description: Initialization function for floating-point transposed direct form II Biquad cascade filter 5 | * 6 | * $Date: 27. January 2017 7 | * $Revision: V.1.5.1 8 | * 9 | * Target Processor: Cortex-M cores 10 | * -------------------------------------------------------------------- */ 11 | /* 12 | * Copyright (C) 2010-2017 ARM Limited or its affiliates. All rights reserved. 13 | * 14 | * SPDX-License-Identifier: Apache-2.0 15 | * 16 | * Licensed under the Apache License, Version 2.0 (the License); you may 17 | * not use this file except in compliance with the License. 18 | * You may obtain a copy of the License at 19 | * 20 | * www.apache.org/licenses/LICENSE-2.0 21 | * 22 | * Unless required by applicable law or agreed to in writing, software 23 | * distributed under the License is distributed on an AS IS BASIS, WITHOUT 24 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 25 | * See the License for the specific language governing permissions and 26 | * limitations under the License. 27 | */ 28 | 29 | #include "xtensa_math.h" 30 | 31 | /** 32 | * @ingroup groupFilters 33 | */ 34 | 35 | /** 36 | * @addtogroup BiquadCascadeDF2T 37 | * @{ 38 | */ 39 | 40 | /** 41 | * @brief Initialization function for the floating-point transposed direct form II Biquad cascade filter. 42 | * @param[in,out] *S points to an instance of the filter data structure. 43 | * @param[in] numStages number of 2nd order stages in the filter. 44 | * @param[in] *pCoeffs points to the filter coefficients. 45 | * @param[in] *pState points to the state buffer. 46 | * @return none 47 | * 48 | * Coefficient and State Ordering: 49 | * \par 50 | * The coefficients are stored in the array pCoeffs in the following order: 51 | *
52 |  *     {b10, b11, b12, a11, a12, b20, b21, b22, a21, a22, ...}
53 |  * 
54 | * 55 | * \par 56 | * where b1x and a1x are the coefficients for the first stage, 57 | * b2x and a2x are the coefficients for the second stage, 58 | * and so on. The pCoeffs array contains a total of 5*numStages values. 59 | * 60 | * \par 61 | * The pState is a pointer to state array. 62 | * Each Biquad stage has 2 state variables d1, and d2. 63 | * The 2 state variables for stage 1 are first, then the 2 state variables for stage 2, and so on. 64 | * The state array has a total length of 2*numStages values. 65 | * The state variables are updated after each block of data is processed; the coefficients are untouched. 66 | */ 67 | 68 | void xtensa_biquad_cascade_df2T_init_f32( 69 | xtensa_biquad_cascade_df2T_instance_f32 * S, 70 | uint8_t numStages, 71 | float32_t * pCoeffs, 72 | float32_t * pState) 73 | { 74 | /* Assign filter stages */ 75 | S->numStages = numStages; 76 | 77 | /* Assign coefficient pointer */ 78 | S->pCoeffs = pCoeffs; 79 | 80 | /* Clear state buffer and size is always 2 * numStages */ 81 | memset(pState, 0, (2U * (uint32_t) numStages) * sizeof(float32_t)); 82 | 83 | /* Assign state pointer */ 84 | S->pState = pState; 85 | } 86 | 87 | /** 88 | * @} end of BiquadCascadeDF2T group 89 | */ 90 | -------------------------------------------------------------------------------- /Src/src/dsp_lib/xtensa_biquad_cascade_stereo_df2T_init_f32.c: -------------------------------------------------------------------------------- 1 | /* ---------------------------------------------------------------------- 2 | * Project: CMSIS DSP Library 3 | * Title: xtensa_biquad_cascade_stereo_df2T_init_f32.c 4 | * Description: Initialization function for floating-point transposed direct form II Biquad cascade filter 5 | * 6 | * $Date: 27. January 2017 7 | * $Revision: V.1.5.1 8 | * 9 | * Target Processor: Cortex-M cores 10 | * -------------------------------------------------------------------- */ 11 | /* 12 | * Copyright (C) 2010-2017 ARM Limited or its affiliates. All rights reserved. 13 | * 14 | * SPDX-License-Identifier: Apache-2.0 15 | * 16 | * Licensed under the Apache License, Version 2.0 (the License); you may 17 | * not use this file except in compliance with the License. 18 | * You may obtain a copy of the License at 19 | * 20 | * www.apache.org/licenses/LICENSE-2.0 21 | * 22 | * Unless required by applicable law or agreed to in writing, software 23 | * distributed under the License is distributed on an AS IS BASIS, WITHOUT 24 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 25 | * See the License for the specific language governing permissions and 26 | * limitations under the License. 27 | */ 28 | 29 | #include "xtensa_math.h" 30 | 31 | /** 32 | * @ingroup groupFilters 33 | */ 34 | 35 | /** 36 | * @addtogroup BiquadCascadeDF2T 37 | * @{ 38 | */ 39 | 40 | /** 41 | * @brief Initialization function for the floating-point transposed direct form II Biquad cascade filter. 42 | * @param[in,out] *S points to an instance of the filter data structure. 43 | * @param[in] numStages number of 2nd order stages in the filter. 44 | * @param[in] *pCoeffs points to the filter coefficients. 45 | * @param[in] *pState points to the state buffer. 46 | * @return none 47 | * 48 | * Coefficient and State Ordering: 49 | * \par 50 | * The coefficients are stored in the array pCoeffs in the following order: 51 | *
52 |  *     {b10, b11, b12, a11, a12, b20, b21, b22, a21, a22, ...}
53 |  * 
54 | * 55 | * \par 56 | * where b1x and a1x are the coefficients for the first stage, 57 | * b2x and a2x are the coefficients for the second stage, 58 | * and so on. The pCoeffs array contains a total of 5*numStages values. 59 | * 60 | * \par 61 | * The pState is a pointer to state array. 62 | * Each Biquad stage has 2 state variables d1, and d2 for each channel. 63 | * The 2 state variables for stage 1 are first, then the 2 state variables for stage 2, and so on. 64 | * The state array has a total length of 2*numStages values. 65 | * The state variables are updated after each block of data is processed; the coefficients are untouched. 66 | */ 67 | 68 | void xtensa_biquad_cascade_stereo_df2T_init_f32( 69 | xtensa_biquad_cascade_stereo_df2T_instance_f32 * S, 70 | uint8_t numStages, 71 | float32_t * pCoeffs, 72 | float32_t * pState) 73 | { 74 | /* Assign filter stages */ 75 | S->numStages = numStages; 76 | 77 | /* Assign coefficient pointer */ 78 | S->pCoeffs = pCoeffs; 79 | 80 | /* Clear state buffer and size is always 4 * numStages */ 81 | memset(pState, 0, (4U * (uint32_t) numStages) * sizeof(float32_t)); 82 | 83 | /* Assign state pointer */ 84 | S->pState = pState; 85 | } 86 | 87 | /** 88 | * @} end of BiquadCascadeDF2T group 89 | */ 90 | -------------------------------------------------------------------------------- /Src/src/dsp_lib/xtensa_const_structs.c: -------------------------------------------------------------------------------- 1 | 2 | #include "xtensa_const_structs.h" 3 | 4 | /* Floating-point structs */ 5 | const xtensa_cfft_instance_f32 xtensa_cfft_sR_f32_len16 = { 6 | 16, twiddleCoef_16, xtensaBitRevIndexTable16, XTENSABITREVINDEXTABLE_16_TABLE_LENGTH 7 | }; 8 | 9 | const xtensa_cfft_instance_f32 xtensa_cfft_sR_f32_len32 = { 10 | 32, twiddleCoef_32, xtensaBitRevIndexTable32, XTENSABITREVINDEXTABLE_32_TABLE_LENGTH 11 | }; 12 | 13 | const xtensa_cfft_instance_f32 xtensa_cfft_sR_f32_len64 = { 14 | 64, twiddleCoef_64, xtensaBitRevIndexTable64, XTENSABITREVINDEXTABLE_64_TABLE_LENGTH 15 | }; 16 | 17 | const xtensa_cfft_instance_f32 xtensa_cfft_sR_f32_len128 = { 18 | 128, twiddleCoef_128, xtensaBitRevIndexTable128, XTENSABITREVINDEXTABLE_128_TABLE_LENGTH 19 | }; 20 | 21 | const xtensa_cfft_instance_f32 xtensa_cfft_sR_f32_len256 = { 22 | 256, twiddleCoef_256, xtensaBitRevIndexTable256, XTENSABITREVINDEXTABLE_256_TABLE_LENGTH 23 | }; 24 | 25 | const xtensa_cfft_instance_f32 xtensa_cfft_sR_f32_len512 = { 26 | 512, twiddleCoef_512, xtensaBitRevIndexTable512, XTENSABITREVINDEXTABLE_512_TABLE_LENGTH 27 | }; 28 | 29 | const xtensa_cfft_instance_f32 xtensa_cfft_sR_f32_len1024 = { 30 | 1024, twiddleCoef_1024, xtensaBitRevIndexTable1024, XTENSABITREVINDEXTABLE_1024_TABLE_LENGTH 31 | }; 32 | 33 | const xtensa_cfft_instance_f32 xtensa_cfft_sR_f32_len2048 = { 34 | 2048, twiddleCoef_2048, xtensaBitRevIndexTable2048, XTENSABITREVINDEXTABLE_2048_TABLE_LENGTH 35 | }; 36 | 37 | const xtensa_cfft_instance_f32 xtensa_cfft_sR_f32_len4096 = { 38 | 4096, twiddleCoef_4096, xtensaBitRevIndexTable4096, XTENSABITREVINDEXTABLE_4096_TABLE_LENGTH 39 | }; 40 | 41 | 42 | 43 | /* Structure for real-value inputs */ 44 | /* Floating-point structs */ 45 | const xtensa_rfft_fast_instance_f32 xtensa_rfft_fast_sR_f32_len32 = { 46 | { 16, twiddleCoef_32, xtensaBitRevIndexTable32, XTENSABITREVINDEXTABLE_16_TABLE_LENGTH }, 47 | 32U, 48 | (float32_t *)twiddleCoef_rfft_32 49 | }; 50 | 51 | const xtensa_rfft_fast_instance_f32 xtensa_rfft_fast_sR_f32_len64 = { 52 | { 32, twiddleCoef_32, xtensaBitRevIndexTable32, XTENSABITREVINDEXTABLE_32_TABLE_LENGTH }, 53 | 64U, 54 | (float32_t *)twiddleCoef_rfft_64 55 | }; 56 | 57 | const xtensa_rfft_fast_instance_f32 xtensa_rfft_fast_sR_f32_len128 = { 58 | { 64, twiddleCoef_64, xtensaBitRevIndexTable64, XTENSABITREVINDEXTABLE_64_TABLE_LENGTH }, 59 | 128U, 60 | (float32_t *)twiddleCoef_rfft_128 61 | }; 62 | 63 | const xtensa_rfft_fast_instance_f32 xtensa_rfft_fast_sR_f32_len256 = { 64 | { 128, twiddleCoef_128, xtensaBitRevIndexTable128, XTENSABITREVINDEXTABLE_128_TABLE_LENGTH }, 65 | 256U, 66 | (float32_t *)twiddleCoef_rfft_256 67 | }; 68 | 69 | const xtensa_rfft_fast_instance_f32 xtensa_rfft_fast_sR_f32_len512 = { 70 | { 256, twiddleCoef_256, xtensaBitRevIndexTable256, XTENSABITREVINDEXTABLE_256_TABLE_LENGTH }, 71 | 512U, 72 | (float32_t *)twiddleCoef_rfft_512 73 | }; 74 | 75 | const xtensa_rfft_fast_instance_f32 xtensa_rfft_fast_sR_f32_len1024 = { 76 | { 512, twiddleCoef_512, xtensaBitRevIndexTable512, XTENSABITREVINDEXTABLE_512_TABLE_LENGTH }, 77 | 1024U, 78 | (float32_t *)twiddleCoef_rfft_1024 79 | }; 80 | 81 | const xtensa_rfft_fast_instance_f32 xtensa_rfft_fast_sR_f32_len2048 = { 82 | { 1024, twiddleCoef_1024, xtensaBitRevIndexTable1024, XTENSABITREVINDEXTABLE_1024_TABLE_LENGTH }, 83 | 2048U, 84 | (float32_t *)twiddleCoef_rfft_2048 85 | }; 86 | 87 | const xtensa_rfft_fast_instance_f32 xtensa_rfft_fast_sR_f32_len4096 = { 88 | { 2048, twiddleCoef_2048, xtensaBitRevIndexTable2048, XTENSABITREVINDEXTABLE_2048_TABLE_LENGTH }, 89 | 4096U, 90 | (float32_t *)twiddleCoef_rfft_4096 91 | }; 92 | -------------------------------------------------------------------------------- /Src/src/dsp_lib/xtensa_bitreversal.c: -------------------------------------------------------------------------------- 1 | /* ---------------------------------------------------------------------- 2 | * Project: CMSIS DSP Library 3 | * Title: xtensa_bitreversal.c 4 | * Description: Bitreversal functions 5 | * 6 | * $Date: 27. January 2017 7 | * $Revision: V.1.5.1 8 | * 9 | * Target Processor: Cortex-M cores 10 | * -------------------------------------------------------------------- */ 11 | /* 12 | * Copyright (C) 2010-2017 ARM Limited or its affiliates. All rights reserved. 13 | * 14 | * SPDX-License-Identifier: Apache-2.0 15 | * 16 | * Licensed under the Apache License, Version 2.0 (the License); you may 17 | * not use this file except in compliance with the License. 18 | * You may obtain a copy of the License at 19 | * 20 | * www.apache.org/licenses/LICENSE-2.0 21 | * 22 | * Unless required by applicable law or agreed to in writing, software 23 | * distributed under the License is distributed on an AS IS BASIS, WITHOUT 24 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 25 | * See the License for the specific language governing permissions and 26 | * limitations under the License. 27 | */ 28 | 29 | #include "xtensa_math.h" 30 | #include "xtensa_common_tables.h" 31 | 32 | /* 33 | * @brief In-place bit reversal function. 34 | * @param[in, out] *pSrc points to the in-place buffer of floating-point data type. 35 | * @param[in] fftSize length of the FFT. 36 | * @param[in] bitRevFactor bit reversal modifier that supports different size FFTs with the same bit reversal table. 37 | * @param[in] *pBitRevTab points to the bit reversal table. 38 | * @return none. 39 | */ 40 | 41 | void xtensa_bitreversal_f32( 42 | float32_t * pSrc, 43 | uint16_t fftSize, 44 | uint16_t bitRevFactor, 45 | uint16_t * pBitRevTab) 46 | { 47 | uint16_t fftLenBy2, fftLenBy2p1; 48 | uint16_t i, j; 49 | float32_t in; 50 | 51 | /* Initializations */ 52 | j = 0U; 53 | fftLenBy2 = fftSize >> 1U; 54 | fftLenBy2p1 = (fftSize >> 1U) + 1U; 55 | 56 | /* Bit Reversal Implementation */ 57 | for (i = 0U; i <= (fftLenBy2 - 2U); i += 2U) 58 | { 59 | if (i < j) 60 | { 61 | /* pSrc[i] <-> pSrc[j]; */ 62 | in = pSrc[2U * i]; 63 | pSrc[2U * i] = pSrc[2U * j]; 64 | pSrc[2U * j] = in; 65 | 66 | /* pSrc[i+1U] <-> pSrc[j+1U] */ 67 | in = pSrc[(2U * i) + 1U]; 68 | pSrc[(2U * i) + 1U] = pSrc[(2U * j) + 1U]; 69 | pSrc[(2U * j) + 1U] = in; 70 | 71 | /* pSrc[i+fftLenBy2p1] <-> pSrc[j+fftLenBy2p1] */ 72 | in = pSrc[2U * (i + fftLenBy2p1)]; 73 | pSrc[2U * (i + fftLenBy2p1)] = pSrc[2U * (j + fftLenBy2p1)]; 74 | pSrc[2U * (j + fftLenBy2p1)] = in; 75 | 76 | /* pSrc[i+fftLenBy2p1+1U] <-> pSrc[j+fftLenBy2p1+1U] */ 77 | in = pSrc[(2U * (i + fftLenBy2p1)) + 1U]; 78 | pSrc[(2U * (i + fftLenBy2p1)) + 1U] = 79 | pSrc[(2U * (j + fftLenBy2p1)) + 1U]; 80 | pSrc[(2U * (j + fftLenBy2p1)) + 1U] = in; 81 | 82 | } 83 | 84 | /* pSrc[i+1U] <-> pSrc[j+1U] */ 85 | in = pSrc[2U * (i + 1U)]; 86 | pSrc[2U * (i + 1U)] = pSrc[2U * (j + fftLenBy2)]; 87 | pSrc[2U * (j + fftLenBy2)] = in; 88 | 89 | /* pSrc[i+2U] <-> pSrc[j+2U] */ 90 | in = pSrc[(2U * (i + 1U)) + 1U]; 91 | pSrc[(2U * (i + 1U)) + 1U] = pSrc[(2U * (j + fftLenBy2)) + 1U]; 92 | pSrc[(2U * (j + fftLenBy2)) + 1U] = in; 93 | 94 | /* Reading the index for the bit reversal */ 95 | j = *pBitRevTab; 96 | 97 | /* Updating the bit reversal index depending on the fft length */ 98 | pBitRevTab += bitRevFactor; 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /Src/src/dsp_lib/xtensa_fir_decimate_init_f32.c: -------------------------------------------------------------------------------- 1 | /* ---------------------------------------------------------------------- 2 | * Project: CMSIS DSP Library 3 | * Title: xtensa_fir_decimate_init_f32.c 4 | * Description: Floating-point FIR Decimator initialization function 5 | * 6 | * $Date: 27. January 2017 7 | * $Revision: V.1.5.1 8 | * 9 | * Target Processor: Cortex-M cores 10 | * -------------------------------------------------------------------- */ 11 | /* 12 | * Copyright (C) 2010-2017 ARM Limited or its affiliates. All rights reserved. 13 | * 14 | * SPDX-License-Identifier: Apache-2.0 15 | * 16 | * Licensed under the Apache License, Version 2.0 (the License); you may 17 | * not use this file except in compliance with the License. 18 | * You may obtain a copy of the License at 19 | * 20 | * www.apache.org/licenses/LICENSE-2.0 21 | * 22 | * Unless required by applicable law or agreed to in writing, software 23 | * distributed under the License is distributed on an AS IS BASIS, WITHOUT 24 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 25 | * See the License for the specific language governing permissions and 26 | * limitations under the License. 27 | */ 28 | 29 | #include "xtensa_math.h" 30 | 31 | /** 32 | * @ingroup groupFilters 33 | */ 34 | 35 | /** 36 | * @addtogroup FIR_decimate 37 | * @{ 38 | */ 39 | 40 | /** 41 | * @brief Initialization function for the floating-point FIR decimator. 42 | * @param[in,out] *S points to an instance of the floating-point FIR decimator structure. 43 | * @param[in] numTaps number of coefficients in the filter. 44 | * @param[in] M decimation factor. 45 | * @param[in] *pCoeffs points to the filter coefficients. 46 | * @param[in] *pState points to the state buffer. 47 | * @param[in] blockSize number of input samples to process per call. 48 | * @return The function returns ARM_MATH_SUCCESS if initialization was successful or ARM_MATH_LENGTH_ERROR if 49 | * blockSize is not a multiple of M. 50 | * 51 | * Description: 52 | * \par 53 | * pCoeffs points to the array of filter coefficients stored in time reversed order: 54 | *
 55 |  *    {b[numTaps-1], b[numTaps-2], b[N-2], ..., b[1], b[0]}
 56 |  * 
57 | * \par 58 | * pState points to the array of state variables. 59 | * pState is of length numTaps+blockSize-1 words where blockSize is the number of input samples passed to xtensa_fir_decimate_f32(). 60 | * M is the decimation factor. 61 | */ 62 | 63 | xtensa_status xtensa_fir_decimate_init_f32( 64 | xtensa_fir_decimate_instance_f32 * S, 65 | uint16_t numTaps, 66 | uint8_t M, 67 | float32_t * pCoeffs, 68 | float32_t * pState, 69 | uint32_t blockSize) 70 | { 71 | xtensa_status status; 72 | 73 | /* The size of the input block must be a multiple of the decimation factor */ 74 | if ((blockSize % M) != 0U) 75 | { 76 | /* Set status as ARM_MATH_LENGTH_ERROR */ 77 | status = XTENSA_MATH_LENGTH_ERROR; 78 | } 79 | else 80 | { 81 | /* Assign filter taps */ 82 | S->numTaps = numTaps; 83 | 84 | /* Assign coefficient pointer */ 85 | S->pCoeffs = pCoeffs; 86 | 87 | /* Clear state buffer and size is always (blockSize + numTaps - 1) */ 88 | memset(pState, 0, (numTaps + (blockSize - 1U)) * sizeof(float32_t)); 89 | 90 | /* Assign state pointer */ 91 | S->pState = pState; 92 | 93 | /* Assign Decimation Factor */ 94 | S->M = M; 95 | 96 | status = XTENSA_MATH_SUCCESS; 97 | } 98 | 99 | return (status); 100 | 101 | } 102 | 103 | /** 104 | * @} end of FIR_decimate group 105 | */ 106 | -------------------------------------------------------------------------------- /Src/src/dsp_lib/xtensa_var_f32.c: -------------------------------------------------------------------------------- 1 | /* ---------------------------------------------------------------------- 2 | * Project: CMSIS DSP Library 3 | * Title: xtensa_var_f32.c 4 | * Description: Variance of the elements of a floating-point vector 5 | * 6 | * $Date: 27. January 2017 7 | * $Revision: V.1.5.1 8 | * 9 | * Target Processor: Cortex-M cores 10 | * -------------------------------------------------------------------- */ 11 | /* 12 | * Copyright (C) 2010-2017 ARM Limited or its affiliates. All rights reserved. 13 | * 14 | * SPDX-License-Identifier: Apache-2.0 15 | * 16 | * Licensed under the Apache License, Version 2.0 (the License); you may 17 | * not use this file except in compliance with the License. 18 | * You may obtain a copy of the License at 19 | * 20 | * www.apache.org/licenses/LICENSE-2.0 21 | * 22 | * Unless required by applicable law or agreed to in writing, software 23 | * distributed under the License is distributed on an AS IS BASIS, WITHOUT 24 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 25 | * See the License for the specific language governing permissions and 26 | * limitations under the License. 27 | */ 28 | 29 | #include "xtensa_math.h" 30 | 31 | /** 32 | * @ingroup groupStats 33 | */ 34 | 35 | /** 36 | * @defgroup variance Variance 37 | * 38 | * Calculates the variance of the elements in the input vector. 39 | * The underlying algorithm used is the direct method sometimes referred to as the two-pass method: 40 | * 41 | *
 42 |  *   Result = sum(element - meanOfElements)^2) / numElement - 1
 43 |  *
 44 |  *     where, meanOfElements = ( pSrc[0] * pSrc[0] + pSrc[1] * pSrc[1] + ... + pSrc[blockSize-1] ) / blockSize
 45 |  *
 46 |  * 
47 | * 48 | * There are separate functions for floating point, Q31, and Q15 data types. 49 | */ 50 | 51 | /** 52 | * @addtogroup variance 53 | * @{ 54 | */ 55 | 56 | 57 | /** 58 | * @brief Variance of the elements of a floating-point vector. 59 | * @param[in] *pSrc points to the input vector 60 | * @param[in] blockSize length of the input vector 61 | * @param[out] *pResult variance value returned here 62 | * @return none. 63 | */ 64 | 65 | void xtensa_var_f32( 66 | float32_t * pSrc, 67 | uint32_t blockSize, 68 | float32_t * pResult) 69 | { 70 | float32_t fMean, fValue; 71 | uint32_t blkCnt; /* loop counter */ 72 | float32_t * pInput = pSrc; 73 | float32_t sum = 0.0f; 74 | float32_t fSum = 0.0f; 75 | #if defined(ARM_MATH_DSP) 76 | float32_t in1, in2, in3, in4; 77 | #endif 78 | 79 | if (blockSize <= 1U) 80 | { 81 | *pResult = 0; 82 | return; 83 | } 84 | 85 | 86 | 87 | /* Loop over blockSize number of values */ 88 | blkCnt = blockSize; 89 | 90 | 91 | 92 | while (blkCnt > 0U) 93 | { 94 | /* C = (A[0] + A[1] + A[2] + ... + A[blockSize-1]) */ 95 | sum += *pInput++; 96 | 97 | /* Decrement the loop counter */ 98 | blkCnt--; 99 | } 100 | 101 | /* C = (A[0] + A[1] + A[2] + ... + A[blockSize-1]) / blockSize */ 102 | fMean = sum / (float32_t) blockSize; 103 | 104 | pInput = pSrc; 105 | 106 | 107 | 108 | /* Loop over blockSize number of values */ 109 | blkCnt = blockSize; 110 | 111 | 112 | while (blkCnt > 0U) 113 | { 114 | fValue = *pInput++ - fMean; 115 | fSum += fValue * fValue; 116 | 117 | /* Decrement the loop counter */ 118 | blkCnt--; 119 | } 120 | 121 | /* Variance */ 122 | *pResult = fSum / (float32_t)(blockSize - 1.0f); 123 | } 124 | 125 | /** 126 | * @} end of variance group 127 | */ 128 | -------------------------------------------------------------------------------- /Src/src/dsp_lib/xtensa_fir_interpolate_init_f32.c: -------------------------------------------------------------------------------- 1 | /* ---------------------------------------------------------------------- 2 | * Project: CMSIS DSP Library 3 | * Title: xtensa_fir_interpolate_init_f32.c 4 | * Description: Floating-point FIR interpolator initialization function 5 | * 6 | * $Date: 27. January 2017 7 | * $Revision: V.1.5.1 8 | * 9 | * Target Processor: Cortex-M cores 10 | * -------------------------------------------------------------------- */ 11 | /* 12 | * Copyright (C) 2010-2017 XTENSA Limited or its affiliates. All rights reserved. 13 | * 14 | * SPDX-License-Identifier: Apache-2.0 15 | * 16 | * Licensed under the Apache License, Version 2.0 (the License); you may 17 | * not use this file except in compliance with the License. 18 | * You may obtain a copy of the License at 19 | * 20 | * www.apache.org/licenses/LICENSE-2.0 21 | * 22 | * Unless required by applicable law or agreed to in writing, software 23 | * distributed under the License is distributed on an AS IS BASIS, WITHOUT 24 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 25 | * See the License for the specific language governing permissions and 26 | * limitations under the License. 27 | */ 28 | 29 | #include "xtensa_math.h" 30 | 31 | /** 32 | * @ingroup groupFilters 33 | */ 34 | 35 | /** 36 | * @addtogroup FIR_Interpolate 37 | * @{ 38 | */ 39 | 40 | /** 41 | * @brief Initialization function for the floating-point FIR interpolator. 42 | * @param[in,out] *S points to an instance of the floating-point FIR interpolator structure. 43 | * @param[in] L upsample factor. 44 | * @param[in] numTaps number of filter coefficients in the filter. 45 | * @param[in] *pCoeffs points to the filter coefficient buffer. 46 | * @param[in] *pState points to the state buffer. 47 | * @param[in] blockSize number of input samples to process per call. 48 | * @return The function returns XTENSA_MATH_SUCCESS if initialization was successful or XTENSA_MATH_LENGTH_ERROR if 49 | * the filter length numTaps is not a multiple of the interpolation factor L. 50 | * 51 | * Description: 52 | * \par 53 | * pCoeffs points to the array of filter coefficients stored in time reversed order: 54 | *
 55 |  *    {b[numTaps-1], b[numTaps-2], b[numTaps-2], ..., b[1], b[0]}
 56 |  * 
57 | * The length of the filter numTaps must be a multiple of the interpolation factor L. 58 | * \par 59 | * pState points to the array of state variables. 60 | * pState is of length (numTaps/L)+blockSize-1 words 61 | * where blockSize is the number of input samples processed by each call to xtensa_fir_interpolate_f32(). 62 | */ 63 | 64 | xtensa_status xtensa_fir_interpolate_init_f32( 65 | xtensa_fir_interpolate_instance_f32 * S, 66 | uint8_t L, 67 | uint16_t numTaps, 68 | float32_t * pCoeffs, 69 | float32_t * pState, 70 | uint32_t blockSize) 71 | { 72 | xtensa_status status; 73 | 74 | /* The filter length must be a multiple of the interpolation factor */ 75 | if ((numTaps % L) != 0U) 76 | { 77 | /* Set status as XTENSA_MATH_LENGTH_ERROR */ 78 | status = XTENSA_MATH_LENGTH_ERROR; 79 | } 80 | else 81 | { 82 | 83 | /* Assign coefficient pointer */ 84 | S->pCoeffs = pCoeffs; 85 | 86 | /* Assign Interpolation factor */ 87 | S->L = L; 88 | 89 | /* Assign polyPhaseLength */ 90 | S->phaseLength = numTaps / L; 91 | 92 | /* Clear state buffer and size of state array is always phaseLength + blockSize - 1 */ 93 | memset(pState, 0, 94 | (blockSize + 95 | ((uint32_t) S->phaseLength - 1U)) * sizeof(float32_t)); 96 | 97 | /* Assign state pointer */ 98 | S->pState = pState; 99 | 100 | status = XTENSA_MATH_SUCCESS; 101 | } 102 | 103 | return (status); 104 | 105 | } 106 | 107 | /** 108 | * @} end of FIR_Interpolate group 109 | */ 110 | -------------------------------------------------------------------------------- /Src/src/dsp_lib/arm_mat_add_f32.c: -------------------------------------------------------------------------------- 1 | /* ---------------------------------------------------------------------- 2 | * Project: CMSIS DSP Library 3 | * Title: xtensa_mat_add_f32.c 4 | * Description: Floating-point matrix addition 5 | * 6 | * $Date: 27. January 2017 7 | * $Revision: V.1.5.1 8 | * 9 | * Target Processor: Cortex-M cores 10 | * -------------------------------------------------------------------- */ 11 | /* 12 | * Copyright (C) 2010-2017 XTENSA Limited or its affiliates. All rights reserved. 13 | * 14 | * SPDX-License-Identifier: Apache-2.0 15 | * 16 | * Licensed under the Apache License, Version 2.0 (the License); you may 17 | * not use this file except in compliance with the License. 18 | * You may obtain a copy of the License at 19 | * 20 | * www.apache.org/licenses/LICENSE-2.0 21 | * 22 | * Unless required by applicable law or agreed to in writing, software 23 | * distributed under the License is distributed on an AS IS BASIS, WITHOUT 24 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 25 | * See the License for the specific language governing permissions and 26 | * limitations under the License. 27 | */ 28 | 29 | #include "xtensa_math.h" 30 | 31 | /** 32 | * @ingroup groupMatrix 33 | */ 34 | 35 | /** 36 | * @defgroup MatrixAdd Matrix Addition 37 | * 38 | * Adds two matrices. 39 | * \image html MatrixAddition.gif "Addition of two 3 x 3 matrices" 40 | * 41 | * The functions check to make sure that 42 | * pSrcA, pSrcB, and pDst have the same 43 | * number of rows and columns. 44 | */ 45 | 46 | /** 47 | * @addtogroup MatrixAdd 48 | * @{ 49 | */ 50 | 51 | 52 | /** 53 | * @brief Floating-point matrix addition. 54 | * @param[in] *pSrcA points to the first input matrix structure 55 | * @param[in] *pSrcB points to the second input matrix structure 56 | * @param[out] *pDst points to output matrix structure 57 | * @return The function returns either 58 | * XTENSA_MATH_SIZE_MISMATCH or XTENSA_MATH_SUCCESS based on the outcome of size checking. 59 | */ 60 | 61 | xtensa_status xtensa_mat_add_f32( 62 | const xtensa_matrix_instance_f32 * pSrcA, 63 | const xtensa_matrix_instance_f32 * pSrcB, 64 | xtensa_matrix_instance_f32 * pDst) 65 | { 66 | float32_t *pIn1 = pSrcA->pData; /* input data matrix pointer A */ 67 | float32_t *pIn2 = pSrcB->pData; /* input data matrix pointer B */ 68 | float32_t *pOut = pDst->pData; /* output data matrix pointer */ 69 | 70 | 71 | 72 | uint32_t numSamples; /* total number of elements in the matrix */ 73 | uint32_t blkCnt; /* loop counters */ 74 | xtensa_status status; /* status of matrix addition */ 75 | 76 | #ifdef XTENSA_MATH_MATRIX_CHECK 77 | /* Check for matrix mismatch condition */ 78 | if ((pSrcA->numRows != pSrcB->numRows) || 79 | (pSrcA->numCols != pSrcB->numCols) || 80 | (pSrcA->numRows != pDst->numRows) || (pSrcA->numCols != pDst->numCols)) 81 | { 82 | /* Set status as XTENSA_MATH_SIZE_MISMATCH */ 83 | status = XTENSA_MATH_SIZE_MISMATCH; 84 | } 85 | else 86 | #endif 87 | { 88 | 89 | /* Total number of samples in the input matrix */ 90 | numSamples = (uint32_t) pSrcA->numRows * pSrcA->numCols; 91 | 92 | 93 | 94 | /* Initialize blkCnt with number of samples */ 95 | blkCnt = numSamples; 96 | 97 | 98 | while (blkCnt > 0U) 99 | { 100 | /* C(m,n) = A(m,n) + B(m,n) */ 101 | /* Add and then store the results in the destination buffer. */ 102 | *pOut++ = (*pIn1++) + (*pIn2++); 103 | 104 | /* Decrement the loop counter */ 105 | blkCnt--; 106 | } 107 | 108 | /* set status as XTENSA_MATH_SUCCESS */ 109 | status = XTENSA_MATH_SUCCESS; 110 | 111 | } 112 | 113 | /* Return to application */ 114 | return (status); 115 | } 116 | 117 | /** 118 | * @} end of MatrixAdd group 119 | */ 120 | -------------------------------------------------------------------------------- /Src/src/dsp_lib/xtensa_std_f32.c: -------------------------------------------------------------------------------- 1 | /* ---------------------------------------------------------------------- 2 | * Project: CMSIS DSP Library 3 | * Title: xtensa_std_f32.c 4 | * Description: Standard deviation of the elements of a floating-point vector 5 | * 6 | * $Date: 27. January 2017 7 | * $Revision: V.1.5.1 8 | * 9 | * Target Processor: Cortex-M cores 10 | * -------------------------------------------------------------------- */ 11 | /* 12 | * Copyright (C) 2010-2017 ARM Limited or its affiliates. All rights reserved. 13 | * 14 | * SPDX-License-Identifier: Apache-2.0 15 | * 16 | * Licensed under the Apache License, Version 2.0 (the License); you may 17 | * not use this file except in compliance with the License. 18 | * You may obtain a copy of the License at 19 | * 20 | * www.apache.org/licenses/LICENSE-2.0 21 | * 22 | * Unless required by applicable law or agreed to in writing, software 23 | * distributed under the License is distributed on an AS IS BASIS, WITHOUT 24 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 25 | * See the License for the specific language governing permissions and 26 | * limitations under the License. 27 | */ 28 | 29 | #include "xtensa_math.h" 30 | 31 | /** 32 | * @ingroup groupStats 33 | */ 34 | 35 | /** 36 | * @defgroup STD Standard deviation 37 | * 38 | * Calculates the standard deviation of the elements in the input vector. 39 | * The underlying algorithm is used: 40 | * 41 | *
 42 |  *   Result = sqrt((sumOfSquares - sum2 / blockSize) / (blockSize - 1))
 43 |  *
 44 |  *     where, sumOfSquares = pSrc[0] * pSrc[0] + pSrc[1] * pSrc[1] + ... + pSrc[blockSize-1] * pSrc[blockSize-1]
 45 |  *
 46 |  *                     sum = pSrc[0] + pSrc[1] + pSrc[2] + ... + pSrc[blockSize-1]
 47 |  * 
48 | * 49 | * There are separate functions for floating point, Q31, and Q15 data types. 50 | */ 51 | 52 | /** 53 | * @addtogroup STD 54 | * @{ 55 | */ 56 | 57 | 58 | /** 59 | * @brief Standard deviation of the elements of a floating-point vector. 60 | * @param[in] *pSrc points to the input vector 61 | * @param[in] blockSize length of the input vector 62 | * @param[out] *pResult standard deviation value returned here 63 | * @return none. 64 | */ 65 | 66 | void xtensa_std_f32( 67 | float32_t * pSrc, 68 | uint32_t blockSize, 69 | float32_t * pResult) 70 | { 71 | float32_t sum = 0.0f; /* Temporary result storage */ 72 | float32_t sumOfSquares = 0.0f; /* Sum of squares */ 73 | float32_t in; /* input value */ 74 | uint32_t blkCnt; /* loop counter */ 75 | 76 | float32_t squareOfSum; /* Square of Sum */ 77 | float32_t var; /* Temporary varaince storage */ 78 | 79 | 80 | if (blockSize == 1U) 81 | { 82 | *pResult = 0; 83 | return; 84 | } 85 | 86 | 87 | 88 | /* Loop over blockSize number of values */ 89 | blkCnt = blockSize; 90 | 91 | while (blkCnt > 0U) 92 | { 93 | /* C = (A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1]) */ 94 | /* Compute Sum of squares of the input samples 95 | * and then store the result in a temporary variable, sumOfSquares. */ 96 | in = *pSrc++; 97 | sumOfSquares += in * in; 98 | 99 | /* C = (A[0] + A[1] + ... + A[blockSize-1]) */ 100 | /* Compute Sum of the input samples 101 | * and then store the result in a temporary variable, sum. */ 102 | sum += in; 103 | 104 | /* Decrement the loop counter */ 105 | blkCnt--; 106 | } 107 | 108 | /* Compute the square of sum */ 109 | squareOfSum = ((sum * sum) / (float32_t) blockSize); 110 | 111 | /* Compute the variance */ 112 | var = ((sumOfSquares - squareOfSum) / (float32_t) (blockSize - 1.0f)); 113 | 114 | /* Compute standard deviation and then store the result to the destination */ 115 | xtensa_sqrt_f32(var, pResult); 116 | 117 | } 118 | 119 | /** 120 | * @} end of STD group 121 | */ 122 | -------------------------------------------------------------------------------- /Src/wm8731.h: -------------------------------------------------------------------------------- 1 | #ifndef WM8731_H 2 | #define WM8731_H 3 | 4 | #include 5 | #include "Arduino.h" 6 | #include 7 | 8 | #define I2C_SCL 12 9 | #define I2C_SDA 14 10 | 11 | #define WM8731_WRITE_ADDRESS 0x1A 12 | #define WM8731_READ_ADDRESS 0x1B 13 | 14 | // WM8731 register map 15 | #define WM8731_LEFT_LINE_IN 0x00 16 | #define WM8731_LRINBOTH 0x100 17 | #define WM8731_LINMUTE 0x080 18 | #define WM8731_LINVOL 0x01F 19 | 20 | #define WM8731_RIGHT_LINE_IN 0x01 21 | #define WM8731_RLINBOTH 0x100 22 | #define WM8731_RINMUTE 0x080 23 | #define WM8731_RINVOL 0x01F 24 | 25 | #define WM8731_LEFT_HP_OUT 0x02 26 | #define WM8731_LRHPBOTH 0x100 27 | #define WM8731_LZCEN 0x080 28 | #define WM8731_LHPVOL 0x07F 29 | 30 | #define WM8731_RIGHT_HP_OUT 0x03 31 | #define WM8731_RLHPBOTH 0x100 32 | #define WM8731_RZCEN 0x080 33 | #define WM8731_RHPVOL 0x07F 34 | 35 | #define WM8731_ANALOG_AUDIO_PATH_CONTROL 0x04 36 | #define WM8731_SIDEATT_1 0x080 37 | #define WM8731_SIDEATT_0 0x040 38 | #define WM8731_SIDETONE 0x020 39 | #define WM8731_DACSEL 0x010 40 | #define WM8731_BYPASS 0x008 41 | #define WM8731_INSEL 0x004 42 | #define WM8731_MUTEMIC 0x002 43 | #define WM8731_MICBOOST 0x001 44 | 45 | #define WM8731_SIDEATT_Pos 6 46 | 47 | #define WM8731_DIGITAL_AUDIO_PATH_CONTROL 0x005 48 | #define WM8731_HPOR 0x010 49 | #define WM8731_DACMU 0x008 50 | #define WM8731_DEEMPH_1 0x004 51 | #define WM8731_DEEMPH_0 0x002 52 | #define WM8731_ADCHPD 0x001 53 | 54 | #define WM8731_DEEMPH_Pos 1 55 | 56 | #define WM8731_POWER_DOWN_CONTROL 0x06 57 | #define WM8731_POWEROFF 0x080 58 | #define WM8731_CLKOUTPD 0x040 59 | #define WM8731_OSCPD 0x020 60 | #define WM8731_OUTPD 0x010 61 | #define WM8731_DACPD 0x008 62 | #define WM8731_ADCPD 0x004 63 | #define WM8731_MICPD 0x002 64 | #define WM8731_LINEINPD 0x001 65 | 66 | #define WM8731_DIGITAL_AUDIO_INTERFACE_FORMAT 0x07 67 | #define WM8731_BCLKINV 0x080 68 | #define WM8731_MS 0x040 69 | #define WM8731_LRSWAP 0x020 70 | #define WM8731_LRP 0x010 71 | #define WM8731_IWL_1 0x008 72 | #define WM8731_IWL_0 0x004 73 | #define WM8731_FORMAT_1 0x002 74 | #define WM8731_FORMAT_0 0x001 75 | 76 | #define WM8731_IWL_Pos 2 77 | #define WM8731_FORMAT_Pos 0 78 | 79 | #define WM8731_SAMPLING_CONTROL 0x08 80 | #define WM8731_CLKODIV2 0x080 81 | #define WM8731_CLKIDIV2 0x040 82 | #define WM8731_SR_3 0x020 83 | #define WM8731_SR_2 0x010 84 | #define WM8731_SR_1 0x008 85 | #define WM8731_SR_0 0x004 86 | #define WM8731_BOSR 0x002 87 | #define WM8731_USB_NORMAL 0x001 88 | 89 | #define WM8731_ACTIVE_CONTROL 0x09 90 | #define WM8731_ACTIVE 0x001 91 | 92 | #define WM8731_RESET 0x0F 93 | 94 | typedef enum { 95 | LEFT, 96 | RIGHT, 97 | BOTH 98 | } WM8731_Channel; 99 | 100 | void wm8731_init(); 101 | void wm8731_write_reg(uint8_t reg, uint8_t value); 102 | void wm8731_set_line_in_volume(uint8_t vol); 103 | 104 | #endif 105 | -------------------------------------------------------------------------------- /Src/src/dsp_lib/arm_mat_sub_f32.c: -------------------------------------------------------------------------------- 1 | /* ---------------------------------------------------------------------- 2 | * Project: CMSIS DSP Library 3 | * Title: xtensa_mat_sub_f32.c 4 | * Description: Floating-point matrix subtraction 5 | * 6 | * $Date: 27. January 2017 7 | * $Revision: V.1.5.1 8 | * 9 | * Target Processor: Cortex-M cores 10 | * -------------------------------------------------------------------- */ 11 | /* 12 | * Copyright (C) 2010-2017 XTENSA Limited or its affiliates. All rights reserved. 13 | * 14 | * SPDX-License-Identifier: Apache-2.0 15 | * 16 | * Licensed under the Apache License, Version 2.0 (the License); you may 17 | * not use this file except in compliance with the License. 18 | * You may obtain a copy of the License at 19 | * 20 | * www.apache.org/licenses/LICENSE-2.0 21 | * 22 | * Unless required by applicable law or agreed to in writing, software 23 | * distributed under the License is distributed on an AS IS BASIS, WITHOUT 24 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 25 | * See the License for the specific language governing permissions and 26 | * limitations under the License. 27 | */ 28 | 29 | #include "xtensa_math.h" 30 | 31 | /** 32 | * @ingroup groupMatrix 33 | */ 34 | 35 | /** 36 | * @defgroup MatrixSub Matrix Subtraction 37 | * 38 | * Subtract two matrices. 39 | * \image html MatrixSubtraction.gif "Subraction of two 3 x 3 matrices" 40 | * 41 | * The functions check to make sure that 42 | * pSrcA, pSrcB, and pDst have the same 43 | * number of rows and columns. 44 | */ 45 | 46 | /** 47 | * @addtogroup MatrixSub 48 | * @{ 49 | */ 50 | 51 | /** 52 | * @brief Floating-point matrix subtraction 53 | * @param[in] *pSrcA points to the first input matrix structure 54 | * @param[in] *pSrcB points to the second input matrix structure 55 | * @param[out] *pDst points to output matrix structure 56 | * @return The function returns either 57 | * XTENSA_MATH_SIZE_MISMATCH or XTENSA_MATH_SUCCESS based on the outcome of size checking. 58 | */ 59 | 60 | xtensa_status xtensa_mat_sub_f32( 61 | const xtensa_matrix_instance_f32 * pSrcA, 62 | const xtensa_matrix_instance_f32 * pSrcB, 63 | xtensa_matrix_instance_f32 * pDst) 64 | { 65 | float32_t *pIn1 = pSrcA->pData; /* input data matrix pointer A */ 66 | float32_t *pIn2 = pSrcB->pData; /* input data matrix pointer B */ 67 | float32_t *pOut = pDst->pData; /* output data matrix pointer */ 68 | 69 | 70 | uint32_t numSamples; /* total number of elements in the matrix */ 71 | uint32_t blkCnt; /* loop counters */ 72 | xtensa_status status; /* status of matrix subtraction */ 73 | 74 | #ifdef XTENSA_MATH_MATRIX_CHECK 75 | /* Check for matrix mismatch condition */ 76 | if ((pSrcA->numRows != pSrcB->numRows) || 77 | (pSrcA->numCols != pSrcB->numCols) || 78 | (pSrcA->numRows != pDst->numRows) || (pSrcA->numCols != pDst->numCols)) 79 | { 80 | /* Set status as XTENSA_MATH_SIZE_MISMATCH */ 81 | status = XTENSA_MATH_SIZE_MISMATCH; 82 | } 83 | else 84 | #endif /* #ifdef XTENSA_MATH_MATRIX_CHECK */ 85 | { 86 | /* Total number of samples in the input matrix */ 87 | numSamples = (uint32_t) pSrcA->numRows * pSrcA->numCols; 88 | 89 | 90 | 91 | /* Initialize blkCnt with number of samples */ 92 | blkCnt = numSamples; 93 | 94 | 95 | while (blkCnt > 0U) 96 | { 97 | /* C(m,n) = A(m,n) - B(m,n) */ 98 | /* Subtract and then store the results in the destination buffer. */ 99 | *pOut++ = (*pIn1++) - (*pIn2++); 100 | 101 | /* Decrement the loop counter */ 102 | blkCnt--; 103 | } 104 | 105 | /* Set status as XTENSA_MATH_SUCCESS */ 106 | status = XTENSA_MATH_SUCCESS; 107 | } 108 | 109 | /* Return to application */ 110 | return (status); 111 | } 112 | 113 | /** 114 | * @} end of MatrixSub group 115 | */ 116 | -------------------------------------------------------------------------------- /Src/src/dsp_lib/arm_mat_trans_f32.c: -------------------------------------------------------------------------------- 1 | /* ---------------------------------------------------------------------- 2 | * Project: CMSIS DSP Library 3 | * Title: xtensa_mat_trans_f32.c 4 | * Description: Floating-point matrix transpose 5 | * 6 | * $Date: 27. January 2017 7 | * $Revision: V.1.5.1 8 | * 9 | * Target Processor: Cortex-M cores 10 | * -------------------------------------------------------------------- */ 11 | /* 12 | * Copyright (C) 2010-2017 XTENSA Limited or its affiliates. All rights reserved. 13 | * 14 | * SPDX-License-Identifier: Apache-2.0 15 | * 16 | * Licensed under the Apache License, Version 2.0 (the License); you may 17 | * not use this file except in compliance with the License. 18 | * You may obtain a copy of the License at 19 | * 20 | * www.apache.org/licenses/LICENSE-2.0 21 | * 22 | * Unless required by applicable law or agreed to in writing, software 23 | * distributed under the License is distributed on an AS IS BASIS, WITHOUT 24 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 25 | * See the License for the specific language governing permissions and 26 | * limitations under the License. 27 | */ 28 | 29 | /** 30 | * @defgroup MatrixTrans Matrix Transpose 31 | * 32 | * Tranposes a matrix. 33 | * Transposing an M x N matrix flips it around the center diagonal and results in an N x M matrix. 34 | * \image html MatrixTranspose.gif "Transpose of a 3 x 3 matrix" 35 | */ 36 | 37 | #include "xtensa_math.h" 38 | 39 | /** 40 | * @ingroup groupMatrix 41 | */ 42 | 43 | /** 44 | * @addtogroup MatrixTrans 45 | * @{ 46 | */ 47 | 48 | /** 49 | * @brief Floating-point matrix transpose. 50 | * @param[in] *pSrc points to the input matrix 51 | * @param[out] *pDst points to the output matrix 52 | * @return The function returns either XTENSA_MATH_SIZE_MISMATCH 53 | * or XTENSA_MATH_SUCCESS based on the outcome of size checking. 54 | */ 55 | 56 | 57 | xtensa_status xtensa_mat_trans_f32( 58 | const xtensa_matrix_instance_f32 * pSrc, 59 | xtensa_matrix_instance_f32 * pDst) 60 | { 61 | float32_t *pIn = pSrc->pData; /* input data matrix pointer */ 62 | float32_t *pOut = pDst->pData; /* output data matrix pointer */ 63 | float32_t *px; /* Temporary output data matrix pointer */ 64 | uint16_t nRows = pSrc->numRows; /* number of rows */ 65 | uint16_t nColumns = pSrc->numCols; /* number of columns */ 66 | 67 | 68 | 69 | uint16_t col, i = 0U, row = nRows; /* loop counters */ 70 | xtensa_status status; /* status of matrix transpose */ 71 | 72 | 73 | #ifdef XTENSA_MATH_MATRIX_CHECK 74 | 75 | /* Check for matrix mismatch condition */ 76 | if ((pSrc->numRows != pDst->numCols) || (pSrc->numCols != pDst->numRows)) 77 | { 78 | /* Set status as XTENSA_MATH_SIZE_MISMATCH */ 79 | status = XTENSA_MATH_SIZE_MISMATCH; 80 | } 81 | else 82 | #endif /* #ifdef XTENSA_MATH_MATRIX_CHECK */ 83 | 84 | { 85 | /* Matrix transpose by exchanging the rows with columns */ 86 | /* row loop */ 87 | do 88 | { 89 | /* The pointer px is set to starting address of the column being processed */ 90 | px = pOut + i; 91 | 92 | /* Initialize column loop counter */ 93 | col = nColumns; 94 | 95 | while (col > 0U) 96 | { 97 | /* Read and store the input element in the destination */ 98 | *px = *pIn++; 99 | 100 | /* Update the pointer px to point to the next row of the transposed matrix */ 101 | px += nRows; 102 | 103 | /* Decrement the column loop counter */ 104 | col--; 105 | } 106 | 107 | 108 | i++; 109 | 110 | /* Decrement the row loop counter */ 111 | row--; 112 | 113 | } while (row > 0U); /* row loop end */ 114 | 115 | /* Set status as XTENSA_MATH_SUCCESS */ 116 | status = XTENSA_MATH_SUCCESS; 117 | } 118 | 119 | /* Return to application */ 120 | return (status); 121 | } 122 | 123 | /** 124 | * @} end of MatrixTrans group 125 | */ 126 | -------------------------------------------------------------------------------- /Src/src/dsp_lib/arm_mat_scale_f32.c: -------------------------------------------------------------------------------- 1 | /* ---------------------------------------------------------------------- 2 | * Project: CMSIS DSP Library 3 | * Title: xtensa_mat_scale_f32.c 4 | * Description: Multiplies a floating-point matrix by a scalar 5 | * 6 | * $Date: 27. January 2017 7 | * $Revision: V.1.5.1 8 | * 9 | * Target Processor: Cortex-M cores 10 | * -------------------------------------------------------------------- */ 11 | /* 12 | * Copyright (C) 2010-2017 XTENSA Limited or its affiliates. All rights reserved. 13 | * 14 | * SPDX-License-Identifier: Apache-2.0 15 | * 16 | * Licensed under the Apache License, Version 2.0 (the License); you may 17 | * not use this file except in compliance with the License. 18 | * You may obtain a copy of the License at 19 | * 20 | * www.apache.org/licenses/LICENSE-2.0 21 | * 22 | * Unless required by applicable law or agreed to in writing, software 23 | * distributed under the License is distributed on an AS IS BASIS, WITHOUT 24 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 25 | * See the License for the specific language governing permissions and 26 | * limitations under the License. 27 | */ 28 | 29 | #include "xtensa_math.h" 30 | 31 | /** 32 | * @ingroup groupMatrix 33 | */ 34 | 35 | /** 36 | * @defgroup MatrixScale Matrix Scale 37 | * 38 | * Multiplies a matrix by a scalar. This is accomplished by multiplying each element in the 39 | * matrix by the scalar. For example: 40 | * \image html MatrixScale.gif "Matrix Scaling of a 3 x 3 matrix" 41 | * 42 | * The function checks to make sure that the input and output matrices are of the same size. 43 | * 44 | * In the fixed-point Q15 and Q31 functions, scale is represented by 45 | * a fractional multiplication scaleFract and an arithmetic shift shift. 46 | * The shift allows the gain of the scaling operation to exceed 1.0. 47 | * The overall scale factor applied to the fixed-point data is 48 | *
 49 |  *     scale = scaleFract * 2^shift.
 50 |  * 
51 | */ 52 | 53 | /** 54 | * @addtogroup MatrixScale 55 | * @{ 56 | */ 57 | 58 | /** 59 | * @brief Floating-point matrix scaling. 60 | * @param[in] *pSrc points to input matrix structure 61 | * @param[in] scale scale factor to be applied 62 | * @param[out] *pDst points to output matrix structure 63 | * @return The function returns either XTENSA_MATH_SIZE_MISMATCH 64 | * or XTENSA_MATH_SUCCESS based on the outcome of size checking. 65 | * 66 | */ 67 | 68 | xtensa_status xtensa_mat_scale_f32( 69 | const xtensa_matrix_instance_f32 * pSrc, 70 | float32_t scale, 71 | xtensa_matrix_instance_f32 * pDst) 72 | { 73 | float32_t *pIn = pSrc->pData; /* input data matrix pointer */ 74 | float32_t *pOut = pDst->pData; /* output data matrix pointer */ 75 | uint32_t numSamples; /* total number of elements in the matrix */ 76 | uint32_t blkCnt; /* loop counters */ 77 | xtensa_status status; /* status of matrix scaling */ 78 | 79 | 80 | 81 | #ifdef XTENSA_MATH_MATRIX_CHECK 82 | /* Check for matrix mismatch condition */ 83 | if ((pSrc->numRows != pDst->numRows) || (pSrc->numCols != pDst->numCols)) 84 | { 85 | /* Set status as XTENSA_MATH_SIZE_MISMATCH */ 86 | status = XTENSA_MATH_SIZE_MISMATCH; 87 | } 88 | else 89 | #endif /* #ifdef XTENSA_MATH_MATRIX_CHECK */ 90 | { 91 | /* Total number of samples in the input matrix */ 92 | numSamples = (uint32_t) pSrc->numRows * pSrc->numCols; 93 | 94 | 95 | /* Initialize blkCnt with number of samples */ 96 | blkCnt = numSamples; 97 | 98 | 99 | while (blkCnt > 0U) 100 | { 101 | /* C(m,n) = A(m,n) * scale */ 102 | /* The results are stored in the destination buffer. */ 103 | *pOut++ = (*pIn++) * scale; 104 | 105 | /* Decrement the loop counter */ 106 | blkCnt--; 107 | } 108 | 109 | /* Set status as XTENSA_MATH_SUCCESS */ 110 | status = XTENSA_MATH_SUCCESS; 111 | } 112 | 113 | /* Return to application */ 114 | return (status); 115 | } 116 | 117 | /** 118 | * @} end of MatrixScale group 119 | */ 120 | -------------------------------------------------------------------------------- /Src/src/dsp_lib/xtensa_sin_cos_f32.c: -------------------------------------------------------------------------------- 1 | 2 | 3 | #include "xtensa_math.h" 4 | #include "xtensa_common_tables.h" 5 | 6 | /** 7 | * @ingroup groupController 8 | */ 9 | 10 | /** 11 | * @defgroup SinCos Sine Cosine 12 | * 13 | * Computes the trigonometric sine and cosine values using a combination of table lookup 14 | * and linear interpolation. 15 | * There are separate functions for Q31 and floating-point data types. 16 | * The input to the floating-point version is in degrees while the 17 | * fixed-point Q31 have a scaled input with the range 18 | * [-1 0.9999] mapping to [-180 +180] degrees. 19 | * 20 | * The floating point function also allows values that are out of the usual range. When this happens, the function will 21 | * take extra time to adjust the input value to the range of [-180 180]. 22 | * 23 | * The result is accurate to 5 digits after the decimal point. 24 | * 25 | * The implementation is based on table lookup using 360 values together with linear interpolation. 26 | * The steps used are: 27 | * -# Calculation of the nearest integer table index. 28 | * -# Compute the fractional portion (fract) of the input. 29 | * -# Fetch the value corresponding to \c index from sine table to \c y0 and also value from \c index+1 to \c y1. 30 | * -# Sine value is computed as *psinVal = y0 + (fract * (y1 - y0)). 31 | * -# Fetch the value corresponding to \c index from cosine table to \c y0 and also value from \c index+1 to \c y1. 32 | * -# Cosine value is computed as *pcosVal = y0 + (fract * (y1 - y0)). 33 | */ 34 | 35 | /** 36 | * @addtogroup SinCos 37 | * @{ 38 | */ 39 | 40 | /** 41 | * @brief Floating-point sin_cos function. 42 | * @param[in] theta input value in degrees 43 | * @param[out] *pSinVal points to the processed sine output. 44 | * @param[out] *pCosVal points to the processed cos output. 45 | * @return none. 46 | */ 47 | 48 | void xtensa_sin_cos_f32( 49 | float32_t theta, 50 | float32_t * pSinVal, 51 | float32_t * pCosVal) 52 | { 53 | float32_t fract, in; /* Temporary variables for input, output */ 54 | uint16_t indexS, indexC; /* Index variable */ 55 | float32_t f1, f2, d1, d2; /* Two nearest output values */ 56 | float32_t findex, Dn, Df, temp; 57 | 58 | /* input x is in degrees */ 59 | /* Scale the input, divide input by 360, for cosine add 0.25 (pi/2) to read sine table */ 60 | in = theta * 0.00277777777778f; 61 | 62 | if (in < 0.0f) 63 | { 64 | in = -in; 65 | } 66 | 67 | in = in - (int32_t)in; 68 | 69 | /* Calculation of index of the table */ 70 | findex = (float32_t) FAST_MATH_TABLE_SIZE * in; 71 | indexS = ((uint16_t)findex) & 0x1ff; 72 | indexC = (indexS + (FAST_MATH_TABLE_SIZE / 4)) & 0x1ff; 73 | 74 | /* fractional value calculation */ 75 | fract = findex - (float32_t) indexS; 76 | 77 | /* Read two nearest values of input value from the cos & sin tables */ 78 | f1 = sinTable_f32[indexC+0]; 79 | f2 = sinTable_f32[indexC+1]; 80 | d1 = -sinTable_f32[indexS+0]; 81 | d2 = -sinTable_f32[indexS+1]; 82 | 83 | temp = (1.0f - fract) * f1 + fract * f2; 84 | 85 | Dn = 0.0122718463030f; // delta between the two points (fixed), in this case 2*pi/FAST_MATH_TABLE_SIZE 86 | Df = f2 - f1; // delta between the values of the functions 87 | 88 | temp = Dn *(d1 + d2) - 2 * Df; 89 | temp = fract * temp + (3 * Df - (d2 + 2 * d1) * Dn); 90 | temp = fract * temp + d1 * Dn; 91 | 92 | /* Calculation of cosine value */ 93 | *pCosVal = fract * temp + f1; 94 | 95 | /* Read two nearest values of input value from the cos & sin tables */ 96 | f1 = sinTable_f32[indexS+0]; 97 | f2 = sinTable_f32[indexS+1]; 98 | d1 = sinTable_f32[indexC+0]; 99 | d2 = sinTable_f32[indexC+1]; 100 | 101 | temp = (1.0f - fract) * f1 + fract * f2; 102 | 103 | Df = f2 - f1; // delta between the values of the functions 104 | temp = Dn*(d1 + d2) - 2*Df; 105 | temp = fract*temp + (3*Df - (d2 + 2*d1)*Dn); 106 | temp = fract*temp + d1*Dn; 107 | 108 | /* Calculation of sine value */ 109 | *pSinVal = fract*temp + f1; 110 | 111 | if (theta < 0.0f) 112 | { 113 | *pSinVal = -*pSinVal; 114 | } 115 | } 116 | /** 117 | * @} end of SinCos group 118 | */ 119 | -------------------------------------------------------------------------------- /Src/src/dsp_lib/xtensa_rfft_fast_init_f32.c: -------------------------------------------------------------------------------- 1 | /* ---------------------------------------------------------------------- 2 | * Project: CMSIS DSP Library 3 | * Title: xtensa_cfft_init_f32.c 4 | * Description: Split Radix Decimation in Frequency CFFT Floating point processing function 5 | * 6 | * $Date: 27. January 2017 7 | * $Revision: V.1.5.1 8 | * 9 | * Target Processor: Cortex-M cores 10 | * -------------------------------------------------------------------- */ 11 | /* 12 | * Copyright (C) 2010-2017 XTENSA Limited or its affiliates. All rights reserved. 13 | * 14 | * SPDX-License-Identifier: Apache-2.0 15 | * 16 | * Licensed under the Apache License, Version 2.0 (the License); you may 17 | * not use this file except in compliance with the License. 18 | * You may obtain a copy of the License at 19 | * 20 | * www.apache.org/licenses/LICENSE-2.0 21 | * 22 | * Unless required by applicable law or agreed to in writing, software 23 | * distributed under the License is distributed on an AS IS BASIS, WITHOUT 24 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 25 | * See the License for the specific language governing permissions and 26 | * limitations under the License. 27 | */ 28 | 29 | #include "xtensa_math.h" 30 | #include "xtensa_common_tables.h" 31 | 32 | /** 33 | * @ingroup groupTransforms 34 | */ 35 | 36 | /** 37 | * @addtogroup RealFFT 38 | * @{ 39 | */ 40 | 41 | /** 42 | * @brief Initialization function for the floating-point real FFT. 43 | * @param[in,out] *S points to an xtensa_rfft_fast_instance_f32 structure. 44 | * @param[in] fftLen length of the Real Sequence. 45 | * @return The function returns XTENSA_MATH_SUCCESS if initialization is successful or XTENSA_MATH_ARGUMENT_ERROR if fftLen is not a supported value. 46 | * 47 | * \par Description: 48 | * \par 49 | * The parameter fftLen Specifies length of RFFT/CIFFT process. Supported FFT Lengths are 32, 64, 128, 256, 512, 1024, 2048, 4096. 50 | * \par 51 | * This Function also initializes Twiddle factor table pointer and Bit reversal table pointer. 52 | */ 53 | xtensa_status xtensa_rfft_fast_init_f32( 54 | xtensa_rfft_fast_instance_f32 * S, 55 | uint16_t fftLen) 56 | { 57 | xtensa_cfft_instance_f32 * Sint; 58 | /* Initialise the default xtensa status */ 59 | xtensa_status status = XTENSA_MATH_SUCCESS; 60 | /* Initialise the FFT length */ 61 | Sint = &(S->Sint); 62 | Sint->fftLen = fftLen/2; 63 | S->fftLenRFFT = fftLen; 64 | 65 | /* Initializations of structure parameters depending on the FFT length */ 66 | switch (Sint->fftLen) 67 | { 68 | case 2048U: 69 | /* Initializations of structure parameters for 2048 point FFT */ 70 | /* Initialise the bit reversal table length */ 71 | Sint->bitRevLength = XTENSABITREVINDEXTABLE_2048_TABLE_LENGTH; 72 | /* Initialise the bit reversal table pointer */ 73 | Sint->pBitRevTable = (uint16_t *)xtensaBitRevIndexTable2048; 74 | /* Initialise the Twiddle coefficient pointers */ 75 | Sint->pTwiddle = (float32_t *) twiddleCoef_2048; 76 | S->pTwiddleRFFT = (float32_t *) twiddleCoef_rfft_4096; 77 | break; 78 | case 1024U: 79 | Sint->bitRevLength = XTENSABITREVINDEXTABLE_1024_TABLE_LENGTH; 80 | Sint->pBitRevTable = (uint16_t *)xtensaBitRevIndexTable1024; 81 | Sint->pTwiddle = (float32_t *) twiddleCoef_1024; 82 | S->pTwiddleRFFT = (float32_t *) twiddleCoef_rfft_2048; 83 | break; 84 | case 512U: 85 | Sint->bitRevLength = XTENSABITREVINDEXTABLE_512_TABLE_LENGTH; 86 | Sint->pBitRevTable = (uint16_t *)xtensaBitRevIndexTable512; 87 | Sint->pTwiddle = (float32_t *) twiddleCoef_512; 88 | S->pTwiddleRFFT = (float32_t *) twiddleCoef_rfft_1024; 89 | break; 90 | case 256U: 91 | Sint->bitRevLength = XTENSABITREVINDEXTABLE_256_TABLE_LENGTH; 92 | Sint->pBitRevTable = (uint16_t *)xtensaBitRevIndexTable256; 93 | Sint->pTwiddle = (float32_t *) twiddleCoef_256; 94 | S->pTwiddleRFFT = (float32_t *) twiddleCoef_rfft_512; 95 | break; 96 | case 128U: 97 | Sint->bitRevLength = XTENSABITREVINDEXTABLE_128_TABLE_LENGTH; 98 | Sint->pBitRevTable = (uint16_t *)xtensaBitRevIndexTable128; 99 | Sint->pTwiddle = (float32_t *) twiddleCoef_128; 100 | S->pTwiddleRFFT = (float32_t *) twiddleCoef_rfft_256; 101 | break; 102 | case 64U: 103 | Sint->bitRevLength = XTENSABITREVINDEXTABLE_64_TABLE_LENGTH; 104 | Sint->pBitRevTable = (uint16_t *)xtensaBitRevIndexTable64; 105 | Sint->pTwiddle = (float32_t *) twiddleCoef_64; 106 | S->pTwiddleRFFT = (float32_t *) twiddleCoef_rfft_128; 107 | break; 108 | case 32U: 109 | Sint->bitRevLength = XTENSABITREVINDEXTABLE_32_TABLE_LENGTH; 110 | Sint->pBitRevTable = (uint16_t *)xtensaBitRevIndexTable32; 111 | Sint->pTwiddle = (float32_t *) twiddleCoef_32; 112 | S->pTwiddleRFFT = (float32_t *) twiddleCoef_rfft_64; 113 | break; 114 | case 16U: 115 | Sint->bitRevLength = XTENSABITREVINDEXTABLE_16_TABLE_LENGTH; 116 | Sint->pBitRevTable = (uint16_t *)xtensaBitRevIndexTable16; 117 | Sint->pTwiddle = (float32_t *) twiddleCoef_16; 118 | S->pTwiddleRFFT = (float32_t *) twiddleCoef_rfft_32; 119 | break; 120 | default: 121 | /* Reporting argument error if fftSize is not valid value */ 122 | status = XTENSA_MATH_ARGUMENT_ERROR; 123 | break; 124 | } 125 | 126 | return (status); 127 | } 128 | 129 | /** 130 | * @} end of RealFFT group 131 | */ 132 | -------------------------------------------------------------------------------- /Src/src/dsp_lib/xtensa_conv_partial_f32.c: -------------------------------------------------------------------------------- 1 | /* ---------------------------------------------------------------------- 2 | * Project: CMSIS DSP Library 3 | * Title: xtensa_conv_partial_f32.c 4 | * Description: Partial convolution of floating-point sequences 5 | * 6 | * $Date: 27. January 2017 7 | * $Revision: V.1.5.1 8 | * 9 | * Target Processor: Cortex-M cores 10 | * -------------------------------------------------------------------- */ 11 | /* 12 | * Copyright (C) 2010-2017 XTENSA Limited or its affiliates. All rights reserved. 13 | * 14 | * SPDX-License-Identifier: Apache-2.0 15 | * 16 | * Licensed under the Apache License, Version 2.0 (the License); you may 17 | * not use this file except in compliance with the License. 18 | * You may obtain a copy of the License at 19 | * 20 | * www.apache.org/licenses/LICENSE-2.0 21 | * 22 | * Unless required by applicable law or agreed to in writing, software 23 | * distributed under the License is distributed on an AS IS BASIS, WITHOUT 24 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 25 | * See the License for the specific language governing permissions and 26 | * limitations under the License. 27 | */ 28 | 29 | #include "xtensa_math.h" 30 | 31 | /** 32 | * @ingroup groupFilters 33 | */ 34 | 35 | /** 36 | * @defgroup PartialConv Partial Convolution 37 | * 38 | * Partial Convolution is equivalent to Convolution except that a subset of the output samples is generated. 39 | * Each function has two additional arguments. 40 | * firstIndex specifies the starting index of the subset of output samples. 41 | * numPoints is the number of output samples to compute. 42 | * The function computes the output in the range 43 | * [firstIndex, ..., firstIndex+numPoints-1]. 44 | * The output array pDst contains numPoints values. 45 | * 46 | * The allowable range of output indices is [0 srcALen+srcBLen-2]. 47 | * If the requested subset does not fall in this range then the functions return XTENSA_MATH_ARGUMENT_ERROR. 48 | * Otherwise the functions return XTENSA_MATH_SUCCESS. 49 | * \note Refer xtensa_conv_f32() for details on fixed point behavior. 50 | * 51 | * 52 | * Fast Versions 53 | * 54 | * \par 55 | * Fast versions are supported for Q31 and Q15 of partial convolution. Cycles for Fast versions are less compared to Q31 and Q15 of partial conv and the design requires 56 | * the input signals should be scaled down to avoid intermediate overflows. 57 | * 58 | * 59 | * Opt Versions 60 | * 61 | * \par 62 | * Opt versions are supported for Q15 and Q7. Design uses internal scratch buffer for getting good optimisation. 63 | * These versions are optimised in cycles and consumes more memory(Scratch memory) compared to Q15 and Q7 versions of partial convolution 64 | */ 65 | 66 | /** 67 | * @addtogroup PartialConv 68 | * @{ 69 | */ 70 | 71 | /** 72 | * @brief Partial convolution of floating-point sequences. 73 | * @param[in] *pSrcA points to the first input sequence. 74 | * @param[in] srcALen length of the first input sequence. 75 | * @param[in] *pSrcB points to the second input sequence. 76 | * @param[in] srcBLen length of the second input sequence. 77 | * @param[out] *pDst points to the location where the output result is written. 78 | * @param[in] firstIndex is the first output sample to start with. 79 | * @param[in] numPoints is the number of output points to be computed. 80 | * @return Returns either XTENSA_MATH_SUCCESS if the function completed correctly or XTENSA_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. 81 | */ 82 | 83 | xtensa_status xtensa_conv_partial_f32( 84 | float32_t * pSrcA, 85 | uint32_t srcALen, 86 | float32_t * pSrcB, 87 | uint32_t srcBLen, 88 | float32_t * pDst, 89 | uint32_t firstIndex, 90 | uint32_t numPoints) 91 | { 92 | 93 | 94 | 95 | 96 | float32_t *pIn1 = pSrcA; /* inputA pointer */ 97 | float32_t *pIn2 = pSrcB; /* inputB pointer */ 98 | float32_t sum; /* Accumulator */ 99 | uint32_t i, j; /* loop counters */ 100 | xtensa_status status; /* status of Partial convolution */ 101 | 102 | /* Check for range of output samples to be calculated */ 103 | if ((firstIndex + numPoints) > ((srcALen + (srcBLen - 1U)))) 104 | { 105 | /* Set status as XTENSA_ARGUMENT_ERROR */ 106 | status = XTENSA_MATH_ARGUMENT_ERROR; 107 | } 108 | else 109 | { 110 | /* Loop to calculate convolution for output length number of values */ 111 | for (i = firstIndex; i <= (firstIndex + numPoints - 1); i++) 112 | { 113 | /* Initialize sum with zero to carry on MAC operations */ 114 | sum = 0.0f; 115 | 116 | /* Loop to perform MAC operations according to convolution equation */ 117 | for (j = 0U; j <= i; j++) 118 | { 119 | /* Check the array limitations for inputs */ 120 | if ((((i - j) < srcBLen) && (j < srcALen))) 121 | { 122 | /* z[i] += x[i-j] * y[j] */ 123 | sum += pIn1[j] * pIn2[i - j]; 124 | } 125 | } 126 | /* Store the output in the destination buffer */ 127 | pDst[i] = sum; 128 | } 129 | /* set status as XTENSA_SUCCESS as there are no argument errors */ 130 | status = XTENSA_MATH_SUCCESS; 131 | } 132 | return (status); 133 | 134 | } 135 | 136 | /** 137 | * @} end of PartialConv group 138 | */ 139 | -------------------------------------------------------------------------------- /Src/src/dsp_lib/xtensa_common_tables.h: -------------------------------------------------------------------------------- 1 | /* ---------------------------------------------------------------------- 2 | * Project: CMSIS DSP Library 3 | * Title: xtensa_common_tables.h 4 | * Description: Extern declaration for common tables 5 | * 6 | * $Date: 27. January 2017 7 | * $Revision: V.1.5.1 8 | * 9 | * Target Processor: Cortex-M cores 10 | * -------------------------------------------------------------------- */ 11 | /* 12 | * Copyright (C) 2010-2017 XTENSA Limited or its affiliates. All rights reserved. 13 | * 14 | * SPDX-License-Identifier: Apache-2.0 15 | * 16 | * Licensed under the Apache License, Version 2.0 (the License); you may 17 | * not use this file except in compliance with the License. 18 | * You may obtain a copy of the License at 19 | * 20 | * www.apache.org/licenses/LICENSE-2.0 21 | * 22 | * Unless required by applicable law or agreed to in writing, software 23 | * distributed under the License is distributed on an AS IS BASIS, WITHOUT 24 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 25 | * See the License for the specific language governing permissions and 26 | * limitations under the License. 27 | */ 28 | 29 | #ifndef _XTENSA_COMMON_TABLES_H 30 | #define _XTENSA_COMMON_TABLES_H 31 | 32 | #include "xtensa_math.h" 33 | 34 | extern const uint16_t xtensaBitRevTable[1024]; 35 | extern const float32_t twiddleCoef_16[32]; 36 | extern const float32_t twiddleCoef_32[64]; 37 | extern const float32_t twiddleCoef_64[128]; 38 | extern const float32_t twiddleCoef_128[256]; 39 | extern const float32_t twiddleCoef_256[512]; 40 | extern const float32_t twiddleCoef_512[1024]; 41 | extern const float32_t twiddleCoef_1024[2048]; 42 | extern const float32_t twiddleCoef_2048[4096]; 43 | extern const float32_t twiddleCoef_4096[8192]; 44 | #define twiddleCoef twiddleCoef_4096 45 | extern const float32_t twiddleCoef_rfft_32[32]; 46 | extern const float32_t twiddleCoef_rfft_64[64]; 47 | extern const float32_t twiddleCoef_rfft_128[128]; 48 | extern const float32_t twiddleCoef_rfft_256[256]; 49 | extern const float32_t twiddleCoef_rfft_512[512]; 50 | extern const float32_t twiddleCoef_rfft_1024[1024]; 51 | extern const float32_t twiddleCoef_rfft_2048[2048]; 52 | extern const float32_t twiddleCoef_rfft_4096[4096]; 53 | 54 | /* floating-point bit reversal tables */ 55 | #define XTENSABITREVINDEXTABLE_16_TABLE_LENGTH ((uint16_t)20) 56 | #define XTENSABITREVINDEXTABLE_32_TABLE_LENGTH ((uint16_t)48) 57 | #define XTENSABITREVINDEXTABLE_64_TABLE_LENGTH ((uint16_t)56) 58 | #define XTENSABITREVINDEXTABLE_128_TABLE_LENGTH ((uint16_t)208) 59 | #define XTENSABITREVINDEXTABLE_256_TABLE_LENGTH ((uint16_t)440) 60 | #define XTENSABITREVINDEXTABLE_512_TABLE_LENGTH ((uint16_t)448) 61 | #define XTENSABITREVINDEXTABLE_1024_TABLE_LENGTH ((uint16_t)1800) 62 | #define XTENSABITREVINDEXTABLE_2048_TABLE_LENGTH ((uint16_t)3808) 63 | #define XTENSABITREVINDEXTABLE_4096_TABLE_LENGTH ((uint16_t)4032) 64 | 65 | extern const uint16_t xtensaBitRevIndexTable16[XTENSABITREVINDEXTABLE_16_TABLE_LENGTH]; 66 | extern const uint16_t xtensaBitRevIndexTable32[XTENSABITREVINDEXTABLE_32_TABLE_LENGTH]; 67 | extern const uint16_t xtensaBitRevIndexTable64[XTENSABITREVINDEXTABLE_64_TABLE_LENGTH]; 68 | extern const uint16_t xtensaBitRevIndexTable128[XTENSABITREVINDEXTABLE_128_TABLE_LENGTH]; 69 | extern const uint16_t xtensaBitRevIndexTable256[XTENSABITREVINDEXTABLE_256_TABLE_LENGTH]; 70 | extern const uint16_t xtensaBitRevIndexTable512[XTENSABITREVINDEXTABLE_512_TABLE_LENGTH]; 71 | extern const uint16_t xtensaBitRevIndexTable1024[XTENSABITREVINDEXTABLE_1024_TABLE_LENGTH]; 72 | extern const uint16_t xtensaBitRevIndexTable2048[XTENSABITREVINDEXTABLE_2048_TABLE_LENGTH]; 73 | extern const uint16_t xtensaBitRevIndexTable4096[XTENSABITREVINDEXTABLE_4096_TABLE_LENGTH]; 74 | 75 | /* fixed-point bit reversal tables */ 76 | #define XTENSABITREVINDEXTABLE_FIXED_16_TABLE_LENGTH ((uint16_t)12) 77 | #define XTENSABITREVINDEXTABLE_FIXED_32_TABLE_LENGTH ((uint16_t)24) 78 | #define XTENSABITREVINDEXTABLE_FIXED_64_TABLE_LENGTH ((uint16_t)56) 79 | #define XTENSABITREVINDEXTABLE_FIXED_128_TABLE_LENGTH ((uint16_t)112) 80 | #define XTENSABITREVINDEXTABLE_FIXED_256_TABLE_LENGTH ((uint16_t)240) 81 | #define XTENSABITREVINDEXTABLE_FIXED_512_TABLE_LENGTH ((uint16_t)480) 82 | #define XTENSABITREVINDEXTABLE_FIXED_1024_TABLE_LENGTH ((uint16_t)992) 83 | #define XTENSABITREVINDEXTABLE_FIXED_2048_TABLE_LENGTH ((uint16_t)1984) 84 | #define XTENSABITREVINDEXTABLE_FIXED_4096_TABLE_LENGTH ((uint16_t)4032) 85 | 86 | extern const uint16_t xtensaBitRevIndexTable_fixed_16[XTENSABITREVINDEXTABLE_FIXED_16_TABLE_LENGTH]; 87 | extern const uint16_t xtensaBitRevIndexTable_fixed_32[XTENSABITREVINDEXTABLE_FIXED_32_TABLE_LENGTH]; 88 | extern const uint16_t xtensaBitRevIndexTable_fixed_64[XTENSABITREVINDEXTABLE_FIXED_64_TABLE_LENGTH]; 89 | extern const uint16_t xtensaBitRevIndexTable_fixed_128[XTENSABITREVINDEXTABLE_FIXED_128_TABLE_LENGTH]; 90 | extern const uint16_t xtensaBitRevIndexTable_fixed_256[XTENSABITREVINDEXTABLE_FIXED_256_TABLE_LENGTH]; 91 | extern const uint16_t xtensaBitRevIndexTable_fixed_512[XTENSABITREVINDEXTABLE_FIXED_512_TABLE_LENGTH]; 92 | extern const uint16_t xtensaBitRevIndexTable_fixed_1024[XTENSABITREVINDEXTABLE_FIXED_1024_TABLE_LENGTH]; 93 | extern const uint16_t xtensaBitRevIndexTable_fixed_2048[XTENSABITREVINDEXTABLE_FIXED_2048_TABLE_LENGTH]; 94 | extern const uint16_t xtensaBitRevIndexTable_fixed_4096[XTENSABITREVINDEXTABLE_FIXED_4096_TABLE_LENGTH]; 95 | 96 | /* Tables for Fast Math Sine and Cosine */ 97 | extern const float32_t sinTable_f32[FAST_MATH_TABLE_SIZE + 1]; 98 | 99 | #endif /* XTENSA_COMMON_TABLES_H */ 100 | -------------------------------------------------------------------------------- /Src/src/dsp_lib/xtensa_cfft_radix4_init_f32.c: -------------------------------------------------------------------------------- 1 | /* ---------------------------------------------------------------------- 2 | * Project: CMSIS DSP Library 3 | * Title: xtensa_cfft_radix4_init_f32.c 4 | * Description: Radix-4 Decimation in Frequency Floating-point CFFT & CIFFT Initialization function 5 | * 6 | * $Date: 27. January 2017 7 | * $Revision: V.1.5.1 8 | * 9 | * Target Processor: Cortex-M cores 10 | * -------------------------------------------------------------------- */ 11 | /* 12 | * Copyright (C) 2010-2017 XTENSA Limited or its affiliates. All rights reserved. 13 | * 14 | * SPDX-License-Identifier: Apache-2.0 15 | * 16 | * Licensed under the Apache License, Version 2.0 (the License); you may 17 | * not use this file except in compliance with the License. 18 | * You may obtain a copy of the License at 19 | * 20 | * www.apache.org/licenses/LICENSE-2.0 21 | * 22 | * Unless required by applicable law or agreed to in writing, software 23 | * distributed under the License is distributed on an AS IS BASIS, WITHOUT 24 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 25 | * See the License for the specific language governing permissions and 26 | * limitations under the License. 27 | */ 28 | 29 | #include "xtensa_math.h" 30 | #include "xtensa_common_tables.h" 31 | 32 | /** 33 | * @ingroup groupTransforms 34 | */ 35 | 36 | /** 37 | * @addtogroup ComplexFFT 38 | * @{ 39 | */ 40 | 41 | /** 42 | * @brief Initialization function for the floating-point CFFT/CIFFT. 43 | * @deprecated Do not use this function. It has been superceded by \ref xtensa_cfft_f32 and will be removed 44 | * in the future. 45 | * @param[in,out] *S points to an instance of the floating-point CFFT/CIFFT structure. 46 | * @param[in] fftLen length of the FFT. 47 | * @param[in] ifftFlag flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. 48 | * @param[in] bitReverseFlag flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. 49 | * @return The function returns XTENSA_MATH_SUCCESS if initialization is successful or XTENSA_MATH_ARGUMENT_ERROR if fftLen is not a supported value. 50 | * 51 | * \par Description: 52 | * \par 53 | * The parameter ifftFlag controls whether a forward or inverse transform is computed. 54 | * Set(=1) ifftFlag for calculation of CIFFT otherwise CFFT is calculated 55 | * \par 56 | * The parameter bitReverseFlag controls whether output is in normal order or bit reversed order. 57 | * Set(=1) bitReverseFlag for output to be in normal order otherwise output is in bit reversed order. 58 | * \par 59 | * The parameter fftLen Specifies length of CFFT/CIFFT process. Supported FFT Lengths are 16, 64, 256, 1024. 60 | * \par 61 | * This Function also initializes Twiddle factor table pointer and Bit reversal table pointer. 62 | */ 63 | 64 | xtensa_status xtensa_cfft_radix4_init_f32( 65 | xtensa_cfft_radix4_instance_f32 * S, 66 | uint16_t fftLen, 67 | uint8_t ifftFlag, 68 | uint8_t bitReverseFlag) 69 | { 70 | /* Initialise the default xtensa status */ 71 | xtensa_status status = XTENSA_MATH_SUCCESS; 72 | 73 | /* Initialise the FFT length */ 74 | S->fftLen = fftLen; 75 | 76 | /* Initialise the Twiddle coefficient pointer */ 77 | S->pTwiddle = (float32_t *) twiddleCoef; 78 | 79 | /* Initialise the Flag for selection of CFFT or CIFFT */ 80 | S->ifftFlag = ifftFlag; 81 | 82 | /* Initialise the Flag for calculation Bit reversal or not */ 83 | S->bitReverseFlag = bitReverseFlag; 84 | 85 | /* Initializations of structure parameters depending on the FFT length */ 86 | switch (S->fftLen) 87 | { 88 | 89 | case 4096U: 90 | /* Initializations of structure parameters for 4096 point FFT */ 91 | 92 | /* Initialise the twiddle coef modifier value */ 93 | S->twidCoefModifier = 1U; 94 | /* Initialise the bit reversal table modifier */ 95 | S->bitRevFactor = 1U; 96 | /* Initialise the bit reversal table pointer */ 97 | S->pBitRevTable = (uint16_t *) xtensaBitRevTable; 98 | /* Initialise the 1/fftLen Value */ 99 | S->onebyfftLen = 0.000244140625; 100 | break; 101 | 102 | case 1024U: 103 | /* Initializations of structure parameters for 1024 point FFT */ 104 | 105 | /* Initialise the twiddle coef modifier value */ 106 | S->twidCoefModifier = 4U; 107 | /* Initialise the bit reversal table modifier */ 108 | S->bitRevFactor = 4U; 109 | /* Initialise the bit reversal table pointer */ 110 | S->pBitRevTable = (uint16_t *) & xtensaBitRevTable[3]; 111 | /* Initialise the 1/fftLen Value */ 112 | S->onebyfftLen = 0.0009765625f; 113 | break; 114 | 115 | 116 | case 256U: 117 | /* Initializations of structure parameters for 256 point FFT */ 118 | S->twidCoefModifier = 16U; 119 | S->bitRevFactor = 16U; 120 | S->pBitRevTable = (uint16_t *) & xtensaBitRevTable[15]; 121 | S->onebyfftLen = 0.00390625f; 122 | break; 123 | 124 | case 64U: 125 | /* Initializations of structure parameters for 64 point FFT */ 126 | S->twidCoefModifier = 64U; 127 | S->bitRevFactor = 64U; 128 | S->pBitRevTable = (uint16_t *) & xtensaBitRevTable[63]; 129 | S->onebyfftLen = 0.015625f; 130 | break; 131 | 132 | case 16U: 133 | /* Initializations of structure parameters for 16 point FFT */ 134 | S->twidCoefModifier = 256U; 135 | S->bitRevFactor = 256U; 136 | S->pBitRevTable = (uint16_t *) & xtensaBitRevTable[255]; 137 | S->onebyfftLen = 0.0625f; 138 | break; 139 | 140 | 141 | default: 142 | /* Reporting argument error if fftSize is not valid value */ 143 | status = XTENSA_MATH_ARGUMENT_ERROR; 144 | break; 145 | } 146 | 147 | return (status); 148 | } 149 | 150 | /** 151 | * @} end of ComplexFFT group 152 | */ 153 | -------------------------------------------------------------------------------- /Src/src/dsp_lib/xtensa_conv_f32.c: -------------------------------------------------------------------------------- 1 | /* ---------------------------------------------------------------------- 2 | * Project: CMSIS DSP Library 3 | * Title: xtensa_conv_f32.c 4 | * Description: Convolution of floating-point sequences 5 | * 6 | * $Date: 27. January 2017 7 | * $Revision: V.1.5.1 8 | * 9 | * Target Processor: Cortex-M cores 10 | * -------------------------------------------------------------------- */ 11 | /* 12 | * Copyright (C) 2010-2017 ARM Limited or its affiliates. All rights reserved. 13 | * 14 | * SPDX-License-Identifier: Apache-2.0 15 | * 16 | * Licensed under the Apache License, Version 2.0 (the License); you may 17 | * not use this file except in compliance with the License. 18 | * You may obtain a copy of the License at 19 | * 20 | * www.apache.org/licenses/LICENSE-2.0 21 | * 22 | * Unless required by applicable law or agreed to in writing, software 23 | * distributed under the License is distributed on an AS IS BASIS, WITHOUT 24 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 25 | * See the License for the specific language governing permissions and 26 | * limitations under the License. 27 | */ 28 | 29 | #include "xtensa_math.h" 30 | 31 | /** 32 | * @ingroup groupFilters 33 | */ 34 | 35 | /** 36 | * @defgroup Conv Convolution 37 | * 38 | * Convolution is a mathematical operation that operates on two finite length vectors to generate a finite length output vector. 39 | * Convolution is similar to correlation and is frequently used in filtering and data analysis. 40 | * The CMSIS DSP library contains functions for convolving Q7, Q15, Q31, and floating-point data types. 41 | * The library also provides fast versions of the Q15 and Q31 functions on Cortex-M4 and Cortex-M3. 42 | * 43 | * \par Algorithm 44 | * Let a[n] and b[n] be sequences of length srcALen and srcBLen samples respectively. 45 | * Then the convolution 46 | * 47 | *
 48 |  *                   c[n] = a[n] * b[n]
 49 |  * 
50 | * 51 | * \par 52 | * is defined as 53 | * \image html ConvolutionEquation.gif 54 | * \par 55 | * Note that c[n] is of length srcALen + srcBLen - 1 and is defined over the interval n=0, 1, 2, ..., srcALen + srcBLen - 2. 56 | * pSrcA points to the first input vector of length srcALen and 57 | * pSrcB points to the second input vector of length srcBLen. 58 | * The output result is written to pDst and the calling function must allocate srcALen+srcBLen-1 words for the result. 59 | * 60 | * \par 61 | * Conceptually, when two signals a[n] and b[n] are convolved, 62 | * the signal b[n] slides over a[n]. 63 | * For each offset \c n, the overlapping portions of a[n] and b[n] are multiplied and summed together. 64 | * 65 | * \par 66 | * Note that convolution is a commutative operation: 67 | * 68 | *
 69 |  *                   a[n] * b[n] = b[n] * a[n].
 70 |  * 
71 | * 72 | * \par 73 | * This means that switching the A and B arguments to the convolution functions has no effect. 74 | * 75 | * Fixed-Point Behavior 76 | * 77 | * \par 78 | * Convolution requires summing up a large number of intermediate products. 79 | * As such, the Q7, Q15, and Q31 functions run a risk of overflow and saturation. 80 | * Refer to the function specific documentation below for further details of the particular algorithm used. 81 | * 82 | * 83 | * Fast Versions 84 | * 85 | * \par 86 | * Fast versions are supported for Q31 and Q15. Cycles for Fast versions are less compared to Q31 and Q15 of conv and the design requires 87 | * the input signals should be scaled down to avoid intermediate overflows. 88 | * 89 | * 90 | * Opt Versions 91 | * 92 | * \par 93 | * Opt versions are supported for Q15 and Q7. Design uses internal scratch buffer for getting good optimisation. 94 | * These versions are optimised in cycles and consumes more memory(Scratch memory) compared to Q15 and Q7 versions 95 | */ 96 | 97 | /** 98 | * @addtogroup Conv 99 | * @{ 100 | */ 101 | 102 | /** 103 | * @brief Convolution of floating-point sequences. 104 | * @param[in] *pSrcA points to the first input sequence. 105 | * @param[in] srcALen length of the first input sequence. 106 | * @param[in] *pSrcB points to the second input sequence. 107 | * @param[in] srcBLen length of the second input sequence. 108 | * @param[out] *pDst points to the location where the output result is written. Length srcALen+srcBLen-1. 109 | * @return none. 110 | */ 111 | 112 | void xtensa_conv_f32( 113 | float32_t * pSrcA, 114 | uint32_t srcALen, 115 | float32_t * pSrcB, 116 | uint32_t srcBLen, 117 | float32_t * pDst) 118 | { 119 | 120 | 121 | 122 | 123 | float32_t *pIn1 = pSrcA; /* inputA pointer */ 124 | float32_t *pIn2 = pSrcB; /* inputB pointer */ 125 | float32_t sum; /* Accumulator */ 126 | uint32_t i, j; /* loop counters */ 127 | 128 | /* Loop to calculate convolution for output length number of times */ 129 | for (i = 0U; i < ((srcALen + srcBLen) - 1U); i++) 130 | { 131 | /* Initialize sum with zero to carry out MAC operations */ 132 | sum = 0.0f; 133 | 134 | /* Loop to perform MAC operations according to convolution equation */ 135 | for (j = 0U; j <= i; j++) 136 | { 137 | /* Check the array limitations */ 138 | if ((((i - j) < srcBLen) && (j < srcALen))) 139 | { 140 | /* z[i] += x[i-j] * y[j] */ 141 | sum += pIn1[j] * pIn2[i - j]; 142 | } 143 | } 144 | /* Store the output in the destination buffer */ 145 | pDst[i] = sum; 146 | } 147 | 148 | 149 | } 150 | 151 | /** 152 | * @} end of Conv group 153 | */ 154 | -------------------------------------------------------------------------------- /Src/src/dsp_lib/arm_mat_mult_f32.c: -------------------------------------------------------------------------------- 1 | /* ---------------------------------------------------------------------- 2 | * Project: CMSIS DSP Library 3 | * Title: xtensa_mat_mult_f32.c 4 | * Description: Floating-point matrix multiplication 5 | * 6 | * $Date: 27. January 2017 7 | * $Revision: V.1.5.1 8 | * 9 | * Target Processor: Cortex-M cores 10 | * -------------------------------------------------------------------- */ 11 | /* 12 | * Copyright (C) 2010-2017 XTENSA Limited or its affiliates. All rights reserved. 13 | * 14 | * SPDX-License-Identifier: Apache-2.0 15 | * 16 | * Licensed under the Apache License, Version 2.0 (the License); you may 17 | * not use this file except in compliance with the License. 18 | * You may obtain a copy of the License at 19 | * 20 | * www.apache.org/licenses/LICENSE-2.0 21 | * 22 | * Unless required by applicable law or agreed to in writing, software 23 | * distributed under the License is distributed on an AS IS BASIS, WITHOUT 24 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 25 | * See the License for the specific language governing permissions and 26 | * limitations under the License. 27 | */ 28 | 29 | #include "xtensa_math.h" 30 | 31 | /** 32 | * @ingroup groupMatrix 33 | */ 34 | 35 | /** 36 | * @defgroup MatrixMult Matrix Multiplication 37 | * 38 | * Multiplies two matrices. 39 | * 40 | * \image html MatrixMultiplication.gif "Multiplication of two 3 x 3 matrices" 41 | 42 | * Matrix multiplication is only defined if the number of columns of the 43 | * first matrix equals the number of rows of the second matrix. 44 | * Multiplying an M x N matrix with an N x P matrix results 45 | * in an M x P matrix. 46 | * When matrix size checking is enabled, the functions check: (1) that the inner dimensions of 47 | * pSrcA and pSrcB are equal; and (2) that the size of the output 48 | * matrix equals the outer dimensions of pSrcA and pSrcB. 49 | */ 50 | 51 | 52 | /** 53 | * @addtogroup MatrixMult 54 | * @{ 55 | */ 56 | 57 | /** 58 | * @brief Floating-point matrix multiplication. 59 | * @param[in] *pSrcA points to the first input matrix structure 60 | * @param[in] *pSrcB points to the second input matrix structure 61 | * @param[out] *pDst points to output matrix structure 62 | * @return The function returns either 63 | * XTENSA_MATH_SIZE_MISMATCH or XTENSA_MATH_SUCCESS based on the outcome of size checking. 64 | */ 65 | 66 | xtensa_status xtensa_mat_mult_f32( 67 | const xtensa_matrix_instance_f32 * pSrcA, 68 | const xtensa_matrix_instance_f32 * pSrcB, 69 | xtensa_matrix_instance_f32 * pDst) 70 | { 71 | float32_t *pIn1 = pSrcA->pData; /* input data matrix pointer A */ 72 | float32_t *pIn2 = pSrcB->pData; /* input data matrix pointer B */ 73 | float32_t *pInA = pSrcA->pData; /* input data matrix pointer A */ 74 | float32_t *pOut = pDst->pData; /* output data matrix pointer */ 75 | float32_t *px; /* Temporary output data matrix pointer */ 76 | float32_t sum; /* Accumulator */ 77 | uint16_t numRowsA = pSrcA->numRows; /* number of rows of input matrix A */ 78 | uint16_t numColsB = pSrcB->numCols; /* number of columns of input matrix B */ 79 | uint16_t numColsA = pSrcA->numCols; /* number of columns of input matrix A */ 80 | 81 | 82 | 83 | float32_t *pInB = pSrcB->pData; /* input data matrix pointer B */ 84 | uint16_t col, i = 0U, row = numRowsA, colCnt; /* loop counters */ 85 | xtensa_status status; /* status of matrix multiplication */ 86 | 87 | #ifdef XTENSA_MATH_MATRIX_CHECK 88 | 89 | /* Check for matrix mismatch condition */ 90 | if ((pSrcA->numCols != pSrcB->numRows) || 91 | (pSrcA->numRows != pDst->numRows) || (pSrcB->numCols != pDst->numCols)) 92 | { 93 | 94 | /* Set status as XTENSA_MATH_SIZE_MISMATCH */ 95 | status = XTENSA_MATH_SIZE_MISMATCH; 96 | } 97 | else 98 | #endif /* #ifdef XTENSA_MATH_MATRIX_CHECK */ 99 | 100 | { 101 | /* The following loop performs the dot-product of each row in pInA with each column in pInB */ 102 | /* row loop */ 103 | do 104 | { 105 | /* Output pointer is set to starting address of the row being processed */ 106 | px = pOut + i; 107 | 108 | /* For every row wise process, the column loop counter is to be initiated */ 109 | col = numColsB; 110 | 111 | /* For every row wise process, the pIn2 pointer is set 112 | ** to the starting address of the pSrcB data */ 113 | pIn2 = pSrcB->pData; 114 | 115 | /* column loop */ 116 | do 117 | { 118 | /* Set the variable sum, that acts as accumulator, to zero */ 119 | sum = 0.0f; 120 | 121 | /* Initialize the pointer pIn1 to point to the starting address of the row being processed */ 122 | pIn1 = pInA; 123 | 124 | /* Matrix A columns number of MAC operations are to be performed */ 125 | colCnt = numColsA; 126 | 127 | while (colCnt > 0U) 128 | { 129 | /* c(m,n) = a(1,1)*b(1,1) + a(1,2) * b(2,1) + .... + a(m,p)*b(p,n) */ 130 | sum += *pIn1++ * (*pIn2); 131 | pIn2 += numColsB; 132 | 133 | /* Decrement the loop counter */ 134 | colCnt--; 135 | } 136 | 137 | /* Store the result in the destination buffer */ 138 | *px++ = sum; 139 | 140 | /* Decrement the column loop counter */ 141 | col--; 142 | 143 | /* Update the pointer pIn2 to point to the starting address of the next column */ 144 | pIn2 = pInB + (numColsB - col); 145 | 146 | } while (col > 0U); 147 | 148 | 149 | /* Update the pointer pInA to point to the starting address of the next row */ 150 | i = i + numColsB; 151 | pInA = pInA + numColsA; 152 | 153 | /* Decrement the row loop counter */ 154 | row--; 155 | 156 | } while (row > 0U); 157 | /* Set status as XTENSA_MATH_SUCCESS */ 158 | status = XTENSA_MATH_SUCCESS; 159 | } 160 | 161 | /* Return to application */ 162 | return (status); 163 | } 164 | 165 | /** 166 | * @} end of MatrixMult group 167 | */ 168 | -------------------------------------------------------------------------------- /Src/rx.h: -------------------------------------------------------------------------------- 1 | 2 | xSemaphoreHandle xRXDSP; 3 | xSemaphoreHandle xRXIN; 4 | xSemaphoreHandle xRXOUT; 5 | 6 | int * input_buffer_ptr = &input_buffer[NUM_SAMPLE_BUF/2].re; 7 | 8 | void IRAM_ATTR rx_in(void * pvParameters){ 9 | size_t readsize = 0; 10 | 11 | while (true) { 12 | #ifdef DEBUG_RUN 13 | int rx_time = micros(); 14 | #endif 15 | xSemaphoreTake(xRXIN, portMAX_DELAY);//ждем сигнала от dsp-обработчика о готвности премного буфера для приема след.партии отсчетов 16 | #ifdef DEBUG_RUN 17 | if (access_in_wait){rx_in_wait_result = micros()-rx_time;access_in_wait=false;} 18 | rx_time = micros(); 19 | #endif 20 | //копирование ранее принятых отсчетов из старшей части рабочего буфера в младшую (50% overlap&save) 21 | for (int i=0;i>12); 29 | workbuf_in[i+NUM_SAMPLE_BUF].im = workbuf_tmp[i].im = (float)(input_buffer[i].im>>12); 30 | fft_in[i].re = workbuf_tmp[i].re;//заполняем fft-буфер для панорамы и спектра 31 | fft_in[i].im = workbuf_tmp[i].im; 32 | } 33 | fft_for_display((float*)&fft_in);//вычислить магнитуды для спектра и "водопада" для последующего отображения 34 | #ifdef DEBUG_RUN 35 | if (access_in_run){rx_in_run_result = micros()-rx_time;access_in_run=false;} 36 | #endif 37 | if(current_mode==RX_MODE){xSemaphoreGive(xRXDSP);}//разрешаем демодуляцию и фильтрацию рабочего буфера 38 | } 39 | } 40 | 41 | void IRAM_ATTR rx_out(void * pvParameters){ 42 | size_t readsize = 0; 43 | while(true){ 44 | #ifdef DEBUG_RUN 45 | int rx_time = micros(); 46 | #endif 47 | xSemaphoreTake(xRXOUT, portMAX_DELAY);//ждем окончания dsp-обработки 48 | #ifdef DEBUG_RUN 49 | if (access_out_wait){rx_out_wait_result = micros()-rx_time;access_out_wait=false;} 50 | rx_time = micros(); 51 | #endif 52 | if(!agc)agc_koeff=1.0f;// 53 | for (int i=0; i150)level=150; 82 | return level; 83 | } 84 | 85 | void IRAM_ATTR get_ssb(int pos,struct COMPLEX* input){//демодуляция SSB в частотной области 86 | 87 | switch (rf_mode){ 88 | case LSB: // 89 | for (int i=0;i old_smeter){old_smeter=smeter;} 143 | if(old_smeter>70)old_smeter=70; 144 | } 145 | } 146 | -------------------------------------------------------------------------------- /Src/lcd/LCD6BitI.h: -------------------------------------------------------------------------------- 1 | ///////////////////////////////////// 2 | //Дисплей TFTLCD24BIT https://datasheetspdf.com/pdf-file/746163/LG/LB043WQ2-TD01/1 3 | //синхронизация через DE 4 | //1,2 - GND 5 | //3,4 - VCC (3.3v) 6 | //5..12 - RED 7 | //13..20 - GREEN 8 | //21..28 - BLUE 9 | //29 - GND 10 | //30 - CLOCK 11 | //31 - +3.3v (дисплей всегда ON) 12 | //34 - DE (data enable - тип синхронизации без hsync/vsync, DE-only) 13 | //35 - +3.3v (PWSEL) 14 | //36 - GND 15 | //37 - Y2 TOP //touch 16 | //38 - X2 LEFT //touch 17 | //39 - Y1 BOTTOM //touch 18 | //40 - X1 RIGHT //touch 19 | //41 - GND 20 | //42 - LED-(подсветка, 28 вольт с огр.резистором 15ом) 21 | //43 - LED+ 22 | 23 | //ОПРЕДЕЛЕНИЯ 24 | //LCD6BitI tft; 25 | //const Mode VGA::MODE480x272(0, 48, 0, 480, 0, 14, 0, 272, 1, 9200000, 1, 1); //для LB043WQ2-TD01 sync DE only 26 | // 27 | //инициализация 28 | // Mode myMode = tft.MODE480x272;//I2S1 - для дисплея TFT24 в режим 6-бит цвет(R2G2B2) 29 | //tft.init(myMode, REDPIN,REDPIN1,GREENPIN,GREENPIN1,BLUEPIN,BLUEPIN1,HSYNCPIN,DEPIN,CLOCKPIN); 30 | // 31 | #pragma once 32 | #include 33 | 34 | i2s_dev_t *i2sDev[] = {&I2S0, &I2S1}; 35 | 36 | class LCD6BitI : public VGA, public GraphicsR2G2B2A2 37 | { 38 | public: 39 | LCD6BitI() //8 bit based modes only work with I2S1 40 | : VGA(1) 41 | { 42 | interruptStaticChild = &LCD6BitI::interrupt; 43 | } 44 | ////////////////////////////////////////// 45 | static const Mode MODE480x272; 46 | ///////////////////////////////////////// 47 | 48 | bool init(const Mode &mode, 49 | const int R0Pin, const int R1Pin, 50 | const int G0Pin, const int G1Pin, 51 | const int B0Pin, const int B1Pin, 52 | const int hsyncPin, const int vsyncPin, const int clockPin = -1) 53 | { 54 | int pinMap[8] = { 55 | R0Pin, R1Pin, 56 | G0Pin, G1Pin, 57 | B0Pin, B1Pin, 58 | hsyncPin, vsyncPin 59 | }; 60 | bool ret = VGA::init(mode, pinMap, 8, clockPin); 61 | /////////////////////////////////// 62 | div_corrections(); 63 | return ret; 64 | /////////////////////////////////// 65 | } 66 | 67 | bool init(const Mode &mode, const int *redPins, const int *greenPins, const int *bluePins, const int hsyncPin, const int vsyncPin, const int clockPin = -1) 68 | { 69 | int pinMap[8]; 70 | for (int i = 0; i < 2; i++) 71 | { 72 | pinMap[i] = redPins[i]; 73 | pinMap[i + 2] = greenPins[i]; 74 | pinMap[i + 4] = bluePins[i]; 75 | } 76 | pinMap[6] = hsyncPin; 77 | pinMap[7] = vsyncPin; 78 | bool ret = VGA::init(mode, pinMap, 8, clockPin); 79 | /////////////////////////////////// 80 | div_corrections(); 81 | return ret; 82 | /////////////////////////////////// 83 | } 84 | 85 | bool init(const Mode &mode, const PinConfig &pinConfig) 86 | { 87 | int pins[8]; 88 | pinConfig.fill6Bit(pins); 89 | bool ret = VGA::init(mode, pins, 8, pinConfig.clock); 90 | /////////////////////////////////// 91 | div_corrections(); 92 | return ret; 93 | /////////////////////////////////// 94 | } 95 | /////////////////////////////////////////// 96 | 97 | void div_corrections(){ 98 | volatile i2s_dev_t &i2s = *i2sDev[i2sIndex]; 99 | i2sStop(); 100 | i2s.clkm_conf.clka_en = 0; //источник тактирования APLL_SCLK = off, PLL_D2_CLK = on 101 | i2s.clkm_conf.clkm_div_num = 8; 102 | i2s.clkm_conf.clkm_div_a = 1; 103 | i2s.clkm_conf.clkm_div_b = 1; 104 | i2s.sample_rate_conf.tx_bck_div_num = 2; 105 | startTX(); 106 | } 107 | ///////////////////////////////////////// 108 | virtual void initSyncBits() 109 | { 110 | hsyncBitI = mode.hSyncPolarity ? 0x40 : 0; 111 | vsyncBitI = mode.vSyncPolarity ? 0x80 : 0; 112 | hsyncBit = hsyncBitI ^ 0x40; 113 | vsyncBit = vsyncBitI ^ 0x80; 114 | } 115 | 116 | virtual long syncBits(bool hSync, bool vSync) 117 | { 118 | return ((hSync ? hsyncBit : hsyncBitI) | (vSync ? vsyncBit : vsyncBitI)) * 0x1010101; 119 | } 120 | 121 | virtual int bytesPerSample() const 122 | { 123 | return 1; 124 | } 125 | 126 | virtual float pixelAspect() const 127 | { 128 | return 1; 129 | } 130 | 131 | virtual void propagateResolution(const int xres, const int yres) 132 | { 133 | setResolution(xres, yres); 134 | } 135 | 136 | virtual void show(bool vSync = false) 137 | { 138 | if (!frameBufferCount) 139 | return; 140 | if (vSync) 141 | { 142 | vSyncPassed = false; 143 | while (!vSyncPassed) 144 | delay(0); 145 | } 146 | Graphics::show(vSync); 147 | } 148 | 149 | protected: 150 | bool useInterrupt() 151 | { 152 | return true; 153 | }; 154 | 155 | static void interrupt(void *arg); 156 | 157 | static void interruptPixelLine(int y, unsigned long *pixels, unsigned long syncBits, void *arg); 158 | }; 159 | 160 | 161 | void IRAM_ATTR LCD6BitI::interrupt(void *arg) 162 | { 163 | LCD6BitI * staticthis = (LCD6BitI *)arg; 164 | 165 | unsigned long *signal = (unsigned long *)staticthis->dmaBufferDescriptors[staticthis->dmaBufferDescriptorActive].buffer(); 166 | unsigned long *pixels = &((unsigned long *)staticthis->dmaBufferDescriptors[staticthis->dmaBufferDescriptorActive].buffer())[(staticthis->mode.hSync + staticthis->mode.hBack) / 4]; 167 | unsigned long base, baseh; 168 | if (staticthis->currentLine >= staticthis->mode.vFront && staticthis->currentLine < staticthis->mode.vFront + staticthis->mode.vSync) 169 | { 170 | baseh = (staticthis->hsyncBit | staticthis->vsyncBit) * 0x1010101; 171 | base = (staticthis->hsyncBitI | staticthis->vsyncBit) * 0x1010101; 172 | } 173 | else 174 | { 175 | baseh = (staticthis->hsyncBit | staticthis->vsyncBit) * 0x1010101; 176 | base = (staticthis->hsyncBitI | staticthis->vsyncBitI) * 0x1010101; 177 | } 178 | for (int i = 0; i < staticthis->mode.hSync / 4; i++) 179 | signal[i] = baseh; 180 | for (int i = staticthis->mode.hSync / 4; i < (staticthis->mode.hSync + staticthis->mode.hBack) / 4; i++) 181 | signal[i] = base; 182 | 183 | int y = (staticthis->currentLine - staticthis->mode.vFront - staticthis->mode.vSync - staticthis->mode.vBack) / staticthis->mode.vDiv; 184 | if (y >= 0 && y < staticthis->mode.vRes) 185 | staticthis->interruptPixelLine(y, pixels, base, arg); 186 | else 187 | for (int i = 0; i < staticthis->mode.hRes / 4; i++) 188 | { 189 | pixels[i] = base; 190 | } 191 | for (int i = 0; i < staticthis->mode.hFront / 4; i++) 192 | signal[i + (staticthis->mode.hSync + staticthis->mode.hBack + staticthis->mode.hRes) / 4] = base; 193 | staticthis->currentLine = (staticthis->currentLine + 1) % staticthis->totalLines; 194 | staticthis->dmaBufferDescriptorActive = (staticthis->dmaBufferDescriptorActive + 1) % staticthis->dmaBufferDescriptorCount; 195 | if (staticthis->currentLine == 0) 196 | staticthis->vSyncPassed = true; 197 | } 198 | 199 | void IRAM_ATTR LCD6BitI::interruptPixelLine(int y, unsigned long *pixels, unsigned long syncBits, void *arg) 200 | { 201 | LCD6BitI * staticthis = (LCD6BitI *)arg; 202 | unsigned char *line = staticthis->frontBuffer[y]; 203 | int j = 0; 204 | for (int i = 0; i < staticthis->mode.hRes / 4; i++) 205 | { 206 | int p0 = (line[j++]) & 63; 207 | int p1 = (line[j++]) & 63; 208 | int p2 = (line[j++]) & 63; 209 | int p3 = (line[j++]) & 63; 210 | pixels[i] = syncBits | (p2 << 0) | (p3 << 8) | (p0 << 16) | (p1 << 24); 211 | } 212 | } 213 | -------------------------------------------------------------------------------- /Src/src/dsp_lib/xtensa_cfft_radix2_init_f32.c: -------------------------------------------------------------------------------- 1 | /* ---------------------------------------------------------------------- 2 | * Project: CMSIS DSP Library 3 | * Title: xtensa_cfft_radix2_init_f32.c 4 | * Description: Radix-2 Decimation in Frequency Floating-point CFFT & CIFFT Initialization function 5 | * 6 | * $Date: 27. January 2017 7 | * $Revision: V.1.5.1 8 | * 9 | * Target Processor: Cortex-M cores 10 | * -------------------------------------------------------------------- */ 11 | /* 12 | * Copyright (C) 2010-2017 XTENSA Limited or its affiliates. All rights reserved. 13 | * 14 | * SPDX-License-Identifier: Apache-2.0 15 | * 16 | * Licensed under the Apache License, Version 2.0 (the License); you may 17 | * not use this file except in compliance with the License. 18 | * You may obtain a copy of the License at 19 | * 20 | * www.apache.org/licenses/LICENSE-2.0 21 | * 22 | * Unless required by applicable law or agreed to in writing, software 23 | * distributed under the License is distributed on an AS IS BASIS, WITHOUT 24 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 25 | * See the License for the specific language governing permissions and 26 | * limitations under the License. 27 | */ 28 | 29 | #include "xtensa_math.h" 30 | #include "xtensa_common_tables.h" 31 | 32 | /** 33 | * @ingroup groupTransforms 34 | */ 35 | 36 | /** 37 | * @addtogroup ComplexFFT 38 | * @{ 39 | */ 40 | 41 | /** 42 | * @brief Initialization function for the floating-point CFFT/CIFFT. 43 | * @deprecated Do not use this function. It has been superseded by \ref xtensa_cfft_f32 and will be removed 44 | * in the future. 45 | * @param[in,out] *S points to an instance of the floating-point CFFT/CIFFT structure. 46 | * @param[in] fftLen length of the FFT. 47 | * @param[in] ifftFlag flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. 48 | * @param[in] bitReverseFlag flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. 49 | * @return The function returns XTENSA_MATH_SUCCESS if initialization is successful or XTENSA_MATH_ARGUMENT_ERROR if fftLen is not a supported value. 50 | * 51 | * \par Description: 52 | * \par 53 | * The parameter ifftFlag controls whether a forward or inverse transform is computed. 54 | * Set(=1) ifftFlag for calculation of CIFFT otherwise CFFT is calculated 55 | * \par 56 | * The parameter bitReverseFlag controls whether output is in normal order or bit reversed order. 57 | * Set(=1) bitReverseFlag for output to be in normal order otherwise output is in bit reversed order. 58 | * \par 59 | * The parameter fftLen Specifies length of CFFT/CIFFT process. Supported FFT Lengths are 16, 64, 256, 1024. 60 | * \par 61 | * This Function also initializes Twiddle factor table pointer and Bit reversal table pointer. 62 | */ 63 | xtensa_status xtensa_cfft_radix2_init_f32( 64 | xtensa_cfft_radix2_instance_f32 * S, 65 | uint16_t fftLen, 66 | uint8_t ifftFlag, 67 | uint8_t bitReverseFlag) 68 | { 69 | /* Initialise the default xtensa status */ 70 | xtensa_status status = XTENSA_MATH_SUCCESS; 71 | 72 | /* Initialise the FFT length */ 73 | S->fftLen = fftLen; 74 | 75 | /* Initialise the Twiddle coefficient pointer */ 76 | S->pTwiddle = (float32_t *) twiddleCoef; 77 | 78 | /* Initialise the Flag for selection of CFFT or CIFFT */ 79 | S->ifftFlag = ifftFlag; 80 | 81 | /* Initialise the Flag for calculation Bit reversal or not */ 82 | S->bitReverseFlag = bitReverseFlag; 83 | 84 | /* Initializations of structure parameters depending on the FFT length */ 85 | switch (S->fftLen) 86 | { 87 | 88 | case 4096U: 89 | /* Initializations of structure parameters for 4096 point FFT */ 90 | 91 | /* Initialise the twiddle coef modifier value */ 92 | S->twidCoefModifier = 1U; 93 | /* Initialise the bit reversal table modifier */ 94 | S->bitRevFactor = 1U; 95 | /* Initialise the bit reversal table pointer */ 96 | S->pBitRevTable = (uint16_t *) xtensaBitRevTable; 97 | /* Initialise the 1/fftLen Value */ 98 | S->onebyfftLen = 0.000244140625; 99 | break; 100 | 101 | case 2048U: 102 | /* Initializations of structure parameters for 2048 point FFT */ 103 | 104 | /* Initialise the twiddle coef modifier value */ 105 | S->twidCoefModifier = 2U; 106 | /* Initialise the bit reversal table modifier */ 107 | S->bitRevFactor = 2U; 108 | /* Initialise the bit reversal table pointer */ 109 | S->pBitRevTable = (uint16_t *) & xtensaBitRevTable[1]; 110 | /* Initialise the 1/fftLen Value */ 111 | S->onebyfftLen = 0.00048828125; 112 | break; 113 | 114 | case 1024U: 115 | /* Initializations of structure parameters for 1024 point FFT */ 116 | 117 | /* Initialise the twiddle coef modifier value */ 118 | S->twidCoefModifier = 4U; 119 | /* Initialise the bit reversal table modifier */ 120 | S->bitRevFactor = 4U; 121 | /* Initialise the bit reversal table pointer */ 122 | S->pBitRevTable = (uint16_t *) & xtensaBitRevTable[3]; 123 | /* Initialise the 1/fftLen Value */ 124 | S->onebyfftLen = 0.0009765625f; 125 | break; 126 | 127 | case 512U: 128 | /* Initializations of structure parameters for 512 point FFT */ 129 | 130 | /* Initialise the twiddle coef modifier value */ 131 | S->twidCoefModifier = 8U; 132 | /* Initialise the bit reversal table modifier */ 133 | S->bitRevFactor = 8U; 134 | /* Initialise the bit reversal table pointer */ 135 | S->pBitRevTable = (uint16_t *) & xtensaBitRevTable[7]; 136 | /* Initialise the 1/fftLen Value */ 137 | S->onebyfftLen = 0.001953125; 138 | break; 139 | 140 | case 256U: 141 | /* Initializations of structure parameters for 256 point FFT */ 142 | S->twidCoefModifier = 16U; 143 | S->bitRevFactor = 16U; 144 | S->pBitRevTable = (uint16_t *) & xtensaBitRevTable[15]; 145 | S->onebyfftLen = 0.00390625f; 146 | break; 147 | 148 | case 128U: 149 | /* Initializations of structure parameters for 128 point FFT */ 150 | S->twidCoefModifier = 32U; 151 | S->bitRevFactor = 32U; 152 | S->pBitRevTable = (uint16_t *) & xtensaBitRevTable[31]; 153 | S->onebyfftLen = 0.0078125; 154 | break; 155 | 156 | case 64U: 157 | /* Initializations of structure parameters for 64 point FFT */ 158 | S->twidCoefModifier = 64U; 159 | S->bitRevFactor = 64U; 160 | S->pBitRevTable = (uint16_t *) & xtensaBitRevTable[63]; 161 | S->onebyfftLen = 0.015625f; 162 | break; 163 | 164 | case 32U: 165 | /* Initializations of structure parameters for 64 point FFT */ 166 | S->twidCoefModifier = 128U; 167 | S->bitRevFactor = 128U; 168 | S->pBitRevTable = (uint16_t *) & xtensaBitRevTable[127]; 169 | S->onebyfftLen = 0.03125; 170 | break; 171 | 172 | case 16U: 173 | /* Initializations of structure parameters for 16 point FFT */ 174 | S->twidCoefModifier = 256U; 175 | S->bitRevFactor = 256U; 176 | S->pBitRevTable = (uint16_t *) & xtensaBitRevTable[255]; 177 | S->onebyfftLen = 0.0625f; 178 | break; 179 | 180 | 181 | default: 182 | /* Reporting argument error if fftSize is not valid value */ 183 | status = XTENSA_MATH_ARGUMENT_ERROR; 184 | break; 185 | } 186 | 187 | return (status); 188 | } 189 | 190 | /** 191 | * @} end of ComplexFFT group 192 | */ 193 | -------------------------------------------------------------------------------- /Src/lcd/LCD6BitIS.h: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////// 2 | //Дисплей tft KD43-G18-45TB аналог LMS430HF02 3 | //синхронизация через HSync/VSync 4 | //1,2 - GND 5 | //3,4 - VCC (3.3v) 6 | //4..12 - RED 7 | //13..20 - GREEN 8 | //21..28 - BLUE 9 | //29 - GND 10 | //30 - CLOCK 11 | //31 - PON +3.3v (дисплей всегда ON) 12 | //32 - HSync 13 | //33 - VSync 14 | //34 - DE (data enable) GND 15 | //35 - +3.3v (PWSEL) 16 | //36 - GND 17 | //37 - Y2 TOP //touch 18 | //38 - X2 LEFT //touch 19 | //39 - Y1 BOTTOM //touch 20 | //40 - X1 RIGHT //touch 21 | //41 - GND 22 | //42 - LED-GND 23 | //43 - LED+(подсветка, +28 вольт с огр.резистором 15ом) 24 | // 25 | // 26 | //определения 27 | //LCD6BitIS tft; 28 | //const Mode LCD6BitIS::MODE480x272(0, 54, 42, 480, 1, 2, 12, 272, 1, 0, 0, 0);//для LMS430HF02 sync Hsync/Vsync 29 | //инициализация //INTERFACE TIMING of datasheet 30 | // Mode myMode = tft.MODE480x272;//I2S1 - для дисплея TFT24 в режим 6-бит цвет(R2G2B2) 31 | // tft.init(myMode, REDPIN,REDPIN1,GREENPIN,GREENPIN1,BLUEPIN,BLUEPIN1,HSYNCPIN,VSYNCPIN,CLOCKPIN); 32 | #pragma once 33 | #include 34 | 35 | i2s_dev_t *i2sDev[] = {&I2S0, &I2S1}; 36 | 37 | class LCD6BitIS : public VGA, public GraphicsR2G2B2A2 38 | { 39 | public: 40 | LCD6BitIS() //8 bit based modes only work with I2S1 41 | : VGA(1) 42 | { 43 | interruptStaticChild = &LCD6BitIS::interrupt; 44 | } 45 | ////////////////////////////////////////// 46 | static const Mode MODE480x272; 47 | ///////////////////////////////////////// 48 | bool init(const Mode &mode, 49 | const int R0Pin, const int R1Pin, 50 | const int G0Pin, const int G1Pin, 51 | const int B0Pin, const int B1Pin, 52 | const int hsyncPin, const int vsyncPin, const int clockPin = -1) 53 | { 54 | int pinMap[8] = { 55 | R0Pin, R1Pin, 56 | G0Pin, G1Pin, 57 | B0Pin, B1Pin, 58 | hsyncPin, vsyncPin 59 | }; 60 | bool ret = VGA::init(mode, pinMap, 8, clockPin); 61 | /////////////////////////////////// 62 | div_corrections(); 63 | return ret; 64 | /////////////////////////////////// 65 | } 66 | 67 | bool init(const Mode &mode, const int *redPins, const int *greenPins, const int *bluePins, const int hsyncPin, const int vsyncPin, const int clockPin = -1) 68 | { 69 | int pinMap[8]; 70 | for (int i = 0; i < 2; i++) 71 | { 72 | pinMap[i] = redPins[i]; 73 | pinMap[i + 2] = greenPins[i]; 74 | pinMap[i + 4] = bluePins[i]; 75 | } 76 | pinMap[6] = hsyncPin; 77 | pinMap[7] = vsyncPin; 78 | bool ret = VGA::init(mode, pinMap, 8, clockPin); 79 | ///////////////////////////////////////// 80 | div_corrections(); 81 | return ret; 82 | /////////////////////////////////////////// 83 | } 84 | 85 | bool init(const Mode &mode, const PinConfig &pinConfig) 86 | { 87 | int pins[8]; 88 | pinConfig.fill6Bit(pins); 89 | bool ret = VGA::init(mode, pins, 8, pinConfig.clock); 90 | /////////////////////////////////////////////////////// 91 | div_corrections(); 92 | return ret; 93 | /////////////////////////////////////////////////////// 94 | } 95 | /////////////////////////////////////////// 96 | 97 | void div_corrections(){ 98 | volatile i2s_dev_t &i2s = *i2sDev[i2sIndex]; 99 | i2sStop(); 100 | i2s.clkm_conf.clka_en = 0; //источник тактирования APLL_SCLK = off, PLL_D2_CLK = on 101 | i2s.clkm_conf.clkm_div_num = 7; 102 | i2s.clkm_conf.clkm_div_a = 1; 103 | i2s.clkm_conf.clkm_div_b = 1; 104 | i2s.sample_rate_conf.tx_bck_div_num = 2; 105 | startTX(); 106 | } 107 | ///////////////////////////////////////// 108 | virtual void initSyncBits() 109 | { 110 | hsyncBitI = mode.hSyncPolarity ? 0x40 : 0; 111 | vsyncBitI = mode.vSyncPolarity ? 0x80 : 0; 112 | hsyncBit = hsyncBitI ^ 0x40; 113 | vsyncBit = vsyncBitI ^ 0x80; 114 | } 115 | 116 | virtual long syncBits(bool hSync, bool vSync) 117 | { 118 | return ((hSync ? hsyncBit : hsyncBitI) | (vSync ? vsyncBit : vsyncBitI)) * 0x1010101; 119 | } 120 | 121 | virtual int bytesPerSample() const 122 | { 123 | return 1; 124 | } 125 | 126 | virtual float pixelAspect() const 127 | { 128 | return 1; 129 | } 130 | 131 | virtual void propagateResolution(const int xres, const int yres) 132 | { 133 | setResolution(xres, yres); 134 | } 135 | 136 | virtual void show(bool vSync = false) 137 | { 138 | if (!frameBufferCount) 139 | return; 140 | if (vSync) 141 | { 142 | vSyncPassed = false; 143 | while (!vSyncPassed) 144 | delay(0); 145 | } 146 | Graphics::show(vSync); 147 | } 148 | 149 | protected: 150 | bool useInterrupt() 151 | { 152 | return true; 153 | }; 154 | 155 | static void interrupt(void *arg); 156 | 157 | static void interruptPixelLine(int y, unsigned long *pixels, unsigned long syncBits, void *arg); 158 | }; 159 | 160 | 161 | void IRAM_ATTR LCD6BitIS::interrupt(void *arg) 162 | { 163 | //start_m = xthal_get_ccount(); 164 | LCD6BitIS * staticthis = (LCD6BitIS *)arg; 165 | 166 | unsigned long *signal = (unsigned long *)staticthis->dmaBufferDescriptors[staticthis->dmaBufferDescriptorActive].buffer(); 167 | unsigned long *pixels = &((unsigned long *)staticthis->dmaBufferDescriptors[staticthis->dmaBufferDescriptorActive].buffer())[(staticthis->mode.hSync + staticthis->mode.hBack) / 4]; 168 | unsigned long base, baseh; 169 | if (staticthis->currentLine >= staticthis->mode.vFront && staticthis->currentLine < staticthis->mode.vFront + staticthis->mode.vSync) 170 | { 171 | baseh = (staticthis->hsyncBit | staticthis->vsyncBit) * 0x1010101; 172 | base = (staticthis->hsyncBitI | staticthis->vsyncBit) * 0x1010101; 173 | } 174 | else 175 | { 176 | baseh = (staticthis->hsyncBit | staticthis->vsyncBitI) * 0x1010101; 177 | base = (staticthis->hsyncBitI | staticthis->vsyncBitI) * 0x1010101; 178 | } 179 | for (int i = 0; i < staticthis->mode.hSync / 4; i++) 180 | signal[i] = baseh; 181 | for (int i = staticthis->mode.hSync / 4; i < (staticthis->mode.hSync + staticthis->mode.hBack) / 4; i++) 182 | signal[i] = base; 183 | 184 | int y = (staticthis->currentLine - staticthis->mode.vFront - staticthis->mode.vSync - staticthis->mode.vBack) / staticthis->mode.vDiv; 185 | if (y >= 0 && y < staticthis->mode.vRes) 186 | staticthis->interruptPixelLine(y, pixels, base, arg); 187 | else 188 | for (int i = 0; i < staticthis->mode.hRes / 4; i++) 189 | { 190 | pixels[i] = base; 191 | } 192 | for (int i = 0; i < staticthis->mode.hFront / 4; i++) 193 | signal[i + (staticthis->mode.hSync + staticthis->mode.hBack + staticthis->mode.hRes) / 4] = base; 194 | staticthis->currentLine = (staticthis->currentLine + 1) % staticthis->totalLines; 195 | staticthis->dmaBufferDescriptorActive = (staticthis->dmaBufferDescriptorActive + 1) % staticthis->dmaBufferDescriptorCount; 196 | if (staticthis->currentLine == 0) 197 | staticthis->vSyncPassed = true; 198 | //stop_m = xthal_get_ccount(); 199 | } 200 | 201 | void IRAM_ATTR LCD6BitIS::interruptPixelLine(int y, unsigned long *pixels, unsigned long syncBits, void *arg) 202 | { 203 | LCD6BitIS * staticthis = (LCD6BitIS *)arg; 204 | unsigned char *line = staticthis->frontBuffer[y]; 205 | int j = 0; 206 | for (int i = 0; i < staticthis->mode.hRes / 4; i++) 207 | { 208 | int p0 = (line[j++]) & 63; 209 | int p1 = (line[j++]) & 63; 210 | int p2 = (line[j++]) & 63; 211 | int p3 = (line[j++]) & 63; 212 | pixels[i] = syncBits | (p2 << 0) | (p3 << 8) | (p0 << 16) | (p1 << 24); 213 | } 214 | } 215 | -------------------------------------------------------------------------------- /Src/src/dsp_lib/xtensa_cfft_radix2_f32.c: -------------------------------------------------------------------------------- 1 | /* ---------------------------------------------------------------------- 2 | * Project: CMSIS DSP Library 3 | * Title: xtensa_cfft_radix2_f32.c 4 | * Description: Radix-2 Decimation in Frequency CFFT & CIFFT Floating point processing function 5 | * 6 | * $Date: 27. January 2017 7 | * $Revision: V.1.5.1 8 | * 9 | * Target Processor: Cortex-M cores 10 | * -------------------------------------------------------------------- */ 11 | /* 12 | * Copyright (C) 2010-2017 ARM Limited or its affiliates. All rights reserved. 13 | * 14 | * SPDX-License-Identifier: Apache-2.0 15 | * 16 | * Licensed under the Apache License, Version 2.0 (the License); you may 17 | * not use this file except in compliance with the License. 18 | * You may obtain a copy of the License at 19 | * 20 | * www.apache.org/licenses/LICENSE-2.0 21 | * 22 | * Unless required by applicable law or agreed to in writing, software 23 | * distributed under the License is distributed on an AS IS BASIS, WITHOUT 24 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 25 | * See the License for the specific language governing permissions and 26 | * limitations under the License. 27 | */ 28 | 29 | #include "xtensa_math.h" 30 | 31 | void xtensa_radix2_butterfly_f32( 32 | float32_t * pSrc, 33 | uint32_t fftLen, 34 | float32_t * pCoef, 35 | uint16_t twidCoefModifier); 36 | 37 | void xtensa_radix2_butterfly_inverse_f32( 38 | float32_t * pSrc, 39 | uint32_t fftLen, 40 | float32_t * pCoef, 41 | uint16_t twidCoefModifier, 42 | float32_t onebyfftLen); 43 | 44 | extern void xtensa_bitreversal_f32( 45 | float32_t * pSrc, 46 | uint16_t fftSize, 47 | uint16_t bitRevFactor, 48 | uint16_t * pBitRevTab); 49 | 50 | /** 51 | * @ingroup groupTransforms 52 | */ 53 | 54 | /** 55 | * @addtogroup ComplexFFT 56 | * @{ 57 | */ 58 | 59 | /** 60 | * @details 61 | * @brief Radix-2 CFFT/CIFFT. 62 | * @deprecated Do not use this function. It has been superseded by \ref xtensa_cfft_f32 and will be removed 63 | * in the future. 64 | * @param[in] *S points to an instance of the floating-point Radix-2 CFFT/CIFFT structure. 65 | * @param[in, out] *pSrc points to the complex data buffer of size 2*fftLen. Processing occurs in-place. 66 | * @return none. 67 | */ 68 | 69 | void xtensa_cfft_radix2_f32( 70 | const xtensa_cfft_radix2_instance_f32 * S, 71 | float32_t * pSrc) 72 | { 73 | 74 | if (S->ifftFlag == 1U) 75 | { 76 | /* Complex IFFT radix-2 */ 77 | xtensa_radix2_butterfly_inverse_f32(pSrc, S->fftLen, S->pTwiddle, 78 | S->twidCoefModifier, S->onebyfftLen); 79 | } 80 | else 81 | { 82 | /* Complex FFT radix-2 */ 83 | xtensa_radix2_butterfly_f32(pSrc, S->fftLen, S->pTwiddle, 84 | S->twidCoefModifier); 85 | } 86 | 87 | if (S->bitReverseFlag == 1U) 88 | { 89 | /* Bit Reversal */ 90 | xtensa_bitreversal_f32(pSrc, S->fftLen, S->bitRevFactor, S->pBitRevTable); 91 | } 92 | 93 | } 94 | 95 | 96 | /** 97 | * @} end of ComplexFFT group 98 | */ 99 | 100 | 101 | 102 | /* ---------------------------------------------------------------------- 103 | ** Internal helper function used by the FFTs 104 | ** ------------------------------------------------------------------- */ 105 | 106 | /* 107 | * @brief Core function for the floating-point CFFT butterfly process. 108 | * @param[in, out] *pSrc points to the in-place buffer of floating-point data type. 109 | * @param[in] fftLen length of the FFT. 110 | * @param[in] *pCoef points to the twiddle coefficient buffer. 111 | * @param[in] twidCoefModifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. 112 | * @return none. 113 | */ 114 | 115 | void xtensa_radix2_butterfly_f32( 116 | float32_t * pSrc, 117 | uint32_t fftLen, 118 | float32_t * pCoef, 119 | uint16_t twidCoefModifier) 120 | { 121 | 122 | uint32_t i, j, k, l; 123 | uint32_t n1, n2, ia; 124 | float32_t xt, yt, cosVal, sinVal; 125 | float32_t p0, p1, p2, p3; 126 | float32_t a0, a1; 127 | 128 | 129 | 130 | n2 = fftLen; 131 | 132 | // loop for stage 133 | for (k = fftLen; k > 1; k = k >> 1) 134 | { 135 | n1 = n2; 136 | n2 = n2 >> 1; 137 | ia = 0; 138 | 139 | // loop for groups 140 | j = 0; 141 | do 142 | { 143 | cosVal = pCoef[ia * 2]; 144 | sinVal = pCoef[(ia * 2) + 1]; 145 | ia += twidCoefModifier; 146 | 147 | // loop for butterfly 148 | i = j; 149 | do 150 | { 151 | l = i + n2; 152 | a0 = pSrc[2 * i] + pSrc[2 * l]; 153 | xt = pSrc[2 * i] - pSrc[2 * l]; 154 | 155 | yt = pSrc[2 * i + 1] - pSrc[2 * l + 1]; 156 | a1 = pSrc[2 * l + 1] + pSrc[2 * i + 1]; 157 | 158 | p0 = xt * cosVal; 159 | p1 = yt * sinVal; 160 | p2 = yt * cosVal; 161 | p3 = xt * sinVal; 162 | 163 | pSrc[2 * i] = a0; 164 | pSrc[2 * i + 1] = a1; 165 | 166 | pSrc[2 * l] = p0 + p1; 167 | pSrc[2 * l + 1] = p2 - p3; 168 | 169 | i += n1; 170 | } while (i < fftLen); 171 | j++; 172 | } while (j < n2); 173 | twidCoefModifier <<= 1U; 174 | } 175 | 176 | 177 | } 178 | 179 | 180 | void xtensa_radix2_butterfly_inverse_f32( 181 | float32_t * pSrc, 182 | uint32_t fftLen, 183 | float32_t * pCoef, 184 | uint16_t twidCoefModifier, 185 | float32_t onebyfftLen) 186 | { 187 | 188 | uint32_t i, j, k, l; 189 | uint32_t n1, n2, ia; 190 | float32_t xt, yt, cosVal, sinVal; 191 | float32_t p0, p1, p2, p3; 192 | float32_t a0, a1; 193 | 194 | 195 | n2 = fftLen; 196 | 197 | // loop for stage 198 | for (k = fftLen; k > 2; k = k >> 1) 199 | { 200 | n1 = n2; 201 | n2 = n2 >> 1; 202 | ia = 0; 203 | 204 | // loop for groups 205 | j = 0; 206 | do 207 | { 208 | cosVal = pCoef[ia * 2]; 209 | sinVal = pCoef[(ia * 2) + 1]; 210 | ia = ia + twidCoefModifier; 211 | 212 | // loop for butterfly 213 | i = j; 214 | do 215 | { 216 | l = i + n2; 217 | a0 = pSrc[2 * i] + pSrc[2 * l]; 218 | xt = pSrc[2 * i] - pSrc[2 * l]; 219 | 220 | yt = pSrc[2 * i + 1] - pSrc[2 * l + 1]; 221 | a1 = pSrc[2 * l + 1] + pSrc[2 * i + 1]; 222 | 223 | p0 = xt * cosVal; 224 | p1 = yt * sinVal; 225 | p2 = yt * cosVal; 226 | p3 = xt * sinVal; 227 | 228 | pSrc[2 * i] = a0; 229 | pSrc[2 * i + 1] = a1; 230 | 231 | pSrc[2 * l] = p0 - p1; 232 | pSrc[2 * l + 1] = p2 + p3; 233 | 234 | i += n1; 235 | } while ( i < fftLen ); // butterfly loop end 236 | j++; 237 | } while ( j < n2 ); // groups loop end 238 | 239 | twidCoefModifier = twidCoefModifier << 1U; 240 | } // stages loop end 241 | 242 | n1 = n2; 243 | n2 = n2 >> 1; 244 | 245 | // loop for butterfly 246 | for (i = 0; i < fftLen; i += n1) 247 | { 248 | l = i + n2; 249 | 250 | a0 = pSrc[2 * i] + pSrc[2 * l]; 251 | xt = pSrc[2 * i] - pSrc[2 * l]; 252 | 253 | a1 = pSrc[2 * l + 1] + pSrc[2 * i + 1]; 254 | yt = pSrc[2 * i + 1] - pSrc[2 * l + 1]; 255 | 256 | p0 = a0 * onebyfftLen; 257 | p2 = xt * onebyfftLen; 258 | p1 = a1 * onebyfftLen; 259 | p3 = yt * onebyfftLen; 260 | 261 | pSrc[2 * i] = p0; 262 | pSrc[2U * l] = p2; 263 | 264 | pSrc[2 * i + 1] = p1; 265 | pSrc[2U * l + 1U] = p3; 266 | } // butterfly loop end 267 | 268 | } 269 | --------------------------------------------------------------------------------