/** * \brief DSP task core function. * * \param pvParameters Junk parameter. */ static void dsp_task(void *pvParameters) { uint32_t i, j; uint32_t adc_potentiometer = 0; const float32_t display_factor = 700; float32_t bin; float32_t tmp; /* Just to avoid compiler warnings. */ UNUSED(pvParameters); /* Wait for user to read instructions. */ WAIT_FOR_TOUCH_EVENT; dsp_configure_button2(); dsp_configure_tc(); dsp_configure_adc(); dsp_configure_dacc(); dsp_sin_init(); /* Enable PDC transfer. */ dsp_clean_buffer(dacc_out_buffer[0], SAMPLE_BLOCK_SIZE); dsp_clean_buffer(dacc_out_buffer[1], SAMPLE_BLOCK_SIZE); dsp_clean_buffer(dacc_out_buffer[2], SAMPLE_BLOCK_SIZE); g_pdc_packet.ul_addr = (uint32_t) dacc_out_buffer[0]; g_pdc_packet.ul_size = SAMPLE_BLOCK_SIZE; g_pdc_nextpacket.ul_addr = (uint32_t) dacc_out_buffer[1]; g_pdc_nextpacket.ul_size = SAMPLE_BLOCK_SIZE; pdc_tx_init(dacc_pdc, &g_pdc_packet, &g_pdc_nextpacket); pdc_enable_transfer(dacc_pdc, PERIPH_PTCR_TXTEN); /* Start Timer counter 0 channel 0 for ADC-DACC trigger. */ tc_start(TC0, 1); /** DSP task loop. */ while (1) { /* Using input wave signal. */ if (g_mode_select == 1) { if (xSemaphoreTake(dacc_notification_semaphore, max_block_time_ticks)) { /* Copy dsp_sfx into wav_in_buffer and prepare Q15 format. */ for (i = 0, j = 0; i < 512; ++j) { tmp = (((dsp_sfx[offset] - (float) 128)) / 100); /* Store Audio sample real part in memory. */ wav_in_buffer[i++] = tmp; /* Store Audio sample imaginary part in memory. */ wav_in_buffer[i++] = 0; /* Prepare buffer for DACC. */ dacc_out_buffer[cur_dac_buffer][j] = (uint16_t)((tmp * 100 * sin_buffer[slider_pos][j]) + 128); /* Update the wave file offset pointer. */ if (offset < dsp_sfx_size - 1) { offset++; } else { offset = WAVE_OFFSET; } } } else { /* Ensure we take the semaphore. */ continue; } } else { /* Using generated input sinus signal. */ if (xSemaphoreTake(dacc_notification_semaphore, max_block_time_ticks)) { /* * Read potentiometer value and generate * sinus signal accordingly. */ adc_potentiometer_old = adc_potentiometer; adc_potentiometer = (afec_channel_get_value(AFEC0, ADC_CHANNEL_POTENTIOMETER)); adc_potentiometer = adc_potentiometer * 10000 / 4096; if (adc_potentiometer > adc_potentiometer_old && adc_potentiometer - adc_potentiometer_old < ADC_POTENTIOMETER_NOISE) { adc_potentiometer = adc_potentiometer_old; } else if (adc_potentiometer_old > adc_potentiometer && adc_potentiometer_old - adc_potentiometer < ADC_POTENTIOMETER_NOISE) { adc_potentiometer = adc_potentiometer_old; } /* Generate the sinus signal. */ dsp_sin_input(adc_potentiometer); /* Prepare buffer for DACC. */ for (i = 0, j = 0; i < 512; ++j, i += 2) { /* * 2048 is the 0 position for DACC. * 50 is an amplification factor. */ dacc_out_buffer[cur_dac_buffer][j] = (uint16_t)((wav_in_buffer[i] * sin_buffer[slider_pos][j]) * 50 + 2048); } } } afec_start_software_conversion(AFEC0); /* Perform FFT and bin Magnitude calculation */ arm_float_to_q15(wav_in_buffer, cfft_q15, SAMPLE_BLOCK_SIZE * 2); arm_cfft_radix4_init_q15(&cfft_instance, SAMPLE_BLOCK_SIZE, 0, 1); arm_cfft_radix4_q15(&cfft_instance, cfft_q15); arm_cmplx_mag_q15(cfft_q15, mag_in_buffer_q15, SAMPLE_BLOCK_SIZE); arm_q15_to_float(mag_in_buffer_q15, mag_in_buffer, 128); /* * Prepare bins rendering for web page and display. * Limit to 99, even if we got 128 magnitudes to display. * Bins are printed using col, incremented by mean of 2 to keep * a clean rendering. Hence we cannot render all the magnitudes, * because of the screen width. It would require a 128*2 space. */ for (i = 0; i < 99; ++i) { bin = (mag_in_buffer[i] * display_factor); if (bin > 0) { if (bin > 98) { bin = 98; } mag_in_buffer_int[i] = (uint32_t)bin; } else { mag_in_buffer_int[i] = 0; } } /* Notify GFX task to start refreshing screen (if necessary). */ if (g_mode_select == 1 || (g_mode_select == 0 && adc_potentiometer != adc_potentiometer_old)) { xSemaphoreGive(gfx_notification_semaphore); } } }
arm_status arm_rfft_init_q15( arm_rfft_instance_q15 * S, arm_cfft_radix4_instance_q15 * S_CFFT, uint32_t fftLenReal, uint32_t ifftFlagR, uint32_t bitReverseFlag) { /* Initialise the default arm status */ arm_status status = ARM_MATH_SUCCESS; /* Initialize the Real FFT length */ S->fftLenReal = (uint16_t) fftLenReal; /* Initialize the Complex FFT length */ S->fftLenBy2 = (uint16_t) fftLenReal / 2u; /* Initialize the Twiddle coefficientA pointer */ S->pTwiddleAReal = (q15_t *) realCoefAQ15; /* Initialize the Twiddle coefficientB pointer */ S->pTwiddleBReal = (q15_t *) realCoefBQ15; /* Initialize the Flag for selection of RFFT or RIFFT */ S->ifftFlagR = (uint8_t) ifftFlagR; /* Initialize the Flag for calculation Bit reversal or not */ S->bitReverseFlagR = (uint8_t) bitReverseFlag; /* Initialization of coef modifier depending on the FFT length */ switch (S->fftLenReal) { case 2048u: S->twidCoefRModifier = 1u; break; case 512u: S->twidCoefRModifier = 4u; break; case 128u: S->twidCoefRModifier = 16u; break; default: /* Reporting argument error if rfftSize is not valid value */ status = ARM_MATH_ARGUMENT_ERROR; break; } /* Init Complex FFT Instance */ S->pCfft = S_CFFT; if(S->ifftFlagR) { /* Initializes the CIFFT Module for fftLenreal/2 length */ arm_cfft_radix4_init_q15(S->pCfft, S->fftLenBy2, 1u, 1u); } else { /* Initializes the CFFT Module for fftLenreal/2 length */ arm_cfft_radix4_init_q15(S->pCfft, S->fftLenBy2, 0u, 1u); } /* return the status of RFFT Init function */ return (status); }