Mercurial > hg > beaglert
diff core/PRU.cpp @ 12:a6beeba3a648
Initial support for higher matrix sample rates by reducing the number of channels. Input not tested yet, and not all examples updated to new format.
author | andrewm |
---|---|
date | Thu, 22 Jan 2015 19:00:22 +0000 |
parents | 8a575ba3ab52 |
children | 901d205d1a3c |
line wrap: on
line diff
--- a/core/PRU.cpp Thu Nov 13 16:02:59 2014 +0100 +++ b/core/PRU.cpp Thu Jan 22 19:00:22 2015 +0000 @@ -50,8 +50,9 @@ #define PRU_LED_PIN_MASK 7 #define PRU_FRAME_COUNT 8 #define PRU_USE_SPI 9 +#define PRU_SPI_NUM_CHANNELS 10 -#define PRU_SAMPLE_INTERVAL_NS 45351 // 22050Hz per SPI sample = 45.351us +#define PRU_SAMPLE_INTERVAL_NS 11338 // 88200Hz per SPI sample = 11.338us #define GPIO0_ADDRESS 0x44E07000 #define GPIO1_ADDRESS 0x4804C000 @@ -79,7 +80,7 @@ // Constructor: specify a PRU number (0 or 1) PRU::PRU() : pru_number(0), running(false), spi_enabled(false), gpio_enabled(false), led_enabled(false), - gpio_test_pin_enabled(false), xenomai_gpio_fd(-1), xenomai_gpio(0) + gpio_test_pin_enabled(false), spi_num_channels(0), xenomai_gpio_fd(-1), xenomai_gpio(0) { } @@ -224,7 +225,7 @@ } // Initialise and open the PRU -int PRU::initialise(int pru_num, int frames_per_buffer, bool xenomai_test_pin) +int PRU::initialise(int pru_num, int frames_per_buffer, int spi_channels, bool xenomai_test_pin) { uint32_t *pruMem = 0; @@ -235,6 +236,13 @@ pru_number = pru_num; + /* Set number of SPI ADC / DAC channels to use. This implicitly + * also determines the sample rate relative to the audio clock + * (half audio clock for 8 channels, full audio clock for 4, + * double audio clock for 2) + */ + spi_num_channels = spi_channels; + /* Initialize structure used by prussdrv_pruintc_intc */ /* PRUSS_INTC_INITDATA is found in pruss_intc_mapping.h */ tpruss_intc_initdata pruss_intc_initdata = PRUSS_INTC_INITDATA; @@ -250,22 +258,22 @@ prussdrv_pruintc_init(&pruss_intc_initdata); spi_buffer_frames = frames_per_buffer; - audio_buffer_frames = spi_buffer_frames * 2; + audio_buffer_frames = spi_buffer_frames * spi_num_channels / 4; /* Map PRU memory to pointers */ prussdrv_map_prumem (PRUSS0_SHARED_DATARAM, (void **)&pruMem); pru_buffer_comm = (uint32_t *)&pruMem[PRU_MEM_COMM_OFFSET/sizeof(uint32_t)]; pru_buffer_audio_dac = (int16_t *)&pruMem[PRU_MEM_MCASP_OFFSET/sizeof(uint32_t)]; - /* ADC memory starts 2(ch)*2(buffers)*2(samples/spi)*bufsize samples later */ - pru_buffer_audio_adc = &pru_buffer_audio_dac[8 * spi_buffer_frames]; + /* ADC memory starts 2(ch)*2(buffers)*bufsize samples later */ + pru_buffer_audio_adc = &pru_buffer_audio_dac[4 * audio_buffer_frames]; if(spi_enabled) { prussdrv_map_prumem (pru_number == 0 ? PRUSS0_PRU0_DATARAM : PRUSS0_PRU1_DATARAM, (void **)&pruMem); pru_buffer_spi_dac = (uint16_t *)&pruMem[PRU_MEM_DAC_OFFSET/sizeof(uint32_t)]; - /* ADC memory starts after 8(ch)*2(buffers)*bufsize samples */ - pru_buffer_spi_adc = &pru_buffer_spi_dac[16 * spi_buffer_frames]; + /* ADC memory starts after N(ch)*2(buffers)*bufsize samples */ + pru_buffer_spi_adc = &pru_buffer_spi_dac[2 * spi_num_channels * spi_buffer_frames]; } else { pru_buffer_spi_dac = pru_buffer_spi_adc = 0; @@ -288,9 +296,11 @@ } if(spi_enabled) { pru_buffer_comm[PRU_USE_SPI] = 1; + pru_buffer_comm[PRU_SPI_NUM_CHANNELS] = spi_num_channels; } else { pru_buffer_comm[PRU_USE_SPI] = 0; + pru_buffer_comm[PRU_SPI_NUM_CHANNELS] = 0; } /* Clear ADC and DAC memory */ @@ -340,7 +350,7 @@ void PRU::loop() { // Polling interval is 1/4 of the period - RTIME sleepTime = PRU_SAMPLE_INTERVAL_NS * spi_buffer_frames / 4; + RTIME sleepTime = PRU_SAMPLE_INTERVAL_NS * (spi_num_channels / 2) * spi_buffer_frames / 4; float *audioInBuffer, *audioOutBuffer; audioInBuffer = (float *)malloc(2 * audio_buffer_frames * sizeof(float)); @@ -410,7 +420,7 @@ if(spi_enabled) render(spi_buffer_frames, audio_buffer_frames, audioInBuffer, audioOutBuffer, - &pru_buffer_spi_adc[spi_buffer_frames * 8], &pru_buffer_spi_dac[spi_buffer_frames * 8]); + &pru_buffer_spi_adc[spi_buffer_frames * spi_num_channels], &pru_buffer_spi_dac[spi_buffer_frames * spi_num_channels]); else render(0, audio_buffer_frames, audioInBuffer, audioOutBuffer, 0, 0);