Beispiel #1
0
/**
 * \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);
		}
	}
}
Beispiel #2
0
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);

}