Mercurial > hg > beaglert
changeset 38:a9af130097e8 staging
GPIO pins are initialised as inputs by ARM to avoid spikes at startup, through gpio_set_dir. The buffers are set to 0x000ffff during initialisation. LastDigitalBuffer is
initialized to 0x0000ffff.
author | Giulio Moro <giuliomoro@yahoo.it> |
---|---|
date | Tue, 12 May 2015 23:48:37 +0100 |
parents | 46571f8f04a1 |
children | 638bc1ae2500 |
files | .cproject core/PRU.cpp include/pru_rtaudio_bin.h pru_rtaudio.bin pru_rtaudio.p |
diffstat | 5 files changed, 95 insertions(+), 47 deletions(-) [+] |
line wrap: on
line diff
--- a/.cproject Mon May 11 20:11:20 2015 +0100 +++ b/.cproject Tue May 12 23:48:37 2015 +0100 @@ -92,7 +92,7 @@ <sourceEntries> <entry excluding="audio_routines_old.S" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="core"/> <entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="include"/> - <entry flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name="projects/basic_network"/> + <entry flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name="projects/analogDigitalDemo"/> <entry flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name="source"/> </sourceEntries> </configuration> @@ -177,7 +177,7 @@ <sourceEntries> <entry excluding="audio_routines_old.S" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="core"/> <entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="include"/> - <entry flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name="projects/basic_network"/> + <entry flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name="projects/analogDigitalDemo"/> <entry flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name="source"/> </sourceEntries> </configuration>
--- a/core/PRU.cpp Mon May 11 20:11:20 2015 +0100 +++ b/core/PRU.cpp Tue May 12 23:48:37 2015 +0100 @@ -56,7 +56,7 @@ #define PRU_FRAME_COUNT 8 #define PRU_USE_SPI 9 #define PRU_SPI_NUM_CHANNELS 10 -#define PRU_USE_GPIO_ANALOG 11 +#define PRU_USE_DIGITAL 11 short int digitalPins[NUM_DIGITALS]={ GPIO_NO_BIT_0, @@ -170,16 +170,11 @@ for(int i=0; i<gNumDigitalChannels; i++){ if(gpio_export(digitalPins[i])) { if(gRTAudioVerbose) - cout << "Warning: couldn't export digital GPIO pin " << digitalPins[i] << "\n"; + cerr << "Warning: couldn't export digital GPIO pin " << digitalPins[i] << "\n"; // this is left as a warning because if the pin has been exported by somebody else, can still be used } - if(gpio_set_dir(digitalPins[i], OUTPUT_PIN)) { + if(gpio_set_dir(digitalPins[i], INPUT_PIN)) { if(gRTAudioVerbose) - cout << "Couldn't set direction on digital GPIO pin " << digitalPins[i] << "\n"; - return -1; - } - if(gpio_set_value(digitalPins[i], HIGH)) { - if(gRTAudioVerbose) - cout << "Couldn't set value on digital GPIO pin " << digitalPins[i] << "\n"; + cerr << "Error: Couldn't set direction on digital GPIO pin " << digitalPins[i] << "\n"; return -1; } } @@ -361,18 +356,24 @@ pru_buffer_comm[PRU_SPI_NUM_CHANNELS] = 0; } if(digital_enabled) { - pru_buffer_comm[PRU_USE_GPIO_ANALOG] = 1; - pru_buffer_comm[NUM_DIGITALS] = spi_num_channels; + pru_buffer_comm[PRU_USE_DIGITAL] = 1; +//TODO: add mask } else { - pru_buffer_comm[PRU_USE_GPIO_ANALOG] = 0; - pru_buffer_comm[NUM_DIGITALS] = 0; + pru_buffer_comm[PRU_USE_DIGITAL] = 0; + } - /* Clear ADC and DAC memory */ + /* Clear ADC and DAC memory.*/ + //TODO: this initialisation should only address the memory effectively used by these buffers, i.e.:depend on the number of frames + // (otherwise might cause issues if we move memory locations later on) if(spi_enabled) { for(int i = 0; i < PRU_MEM_DAC_LENGTH / 2; i++) pru_buffer_spi_dac[i] = 0; + if(digital_enabled){ + for(int i = 0; i < PRU_MEM_DIGITAL_OFFSET*2; i++) + pru_buffer_digital[i] = 0x0000ffff; // set to all inputs, to avoid unexpected spikes + } } for(int i = 0; i < PRU_MEM_MCASP_LENGTH / 2; i++) pru_buffer_audio_dac[i] = 0; @@ -460,7 +461,10 @@ rt_printf("Error: couldn't allocate digital buffers\n"); return; } - + + for(unsigned int n=0; n<digital_buffer_frames; n++){ //initialize lastDigitalFrames to all inputs + lastDigitalBuffer[n]= 0x0000ffff; + } while(!gShouldStop) { // Wait for PRU to move to buffer 1 while(pru_buffer_comm[PRU_CURRENT_BUFFER] == 0 && !gShouldStop) {
--- a/include/pru_rtaudio_bin.h Mon May 11 20:11:20 2015 +0100 +++ b/include/pru_rtaudio_bin.h Tue May 12 23:48:37 2015 +0100 @@ -608,13 +608,12 @@ 0x0901f7f7, 0x02f6f7f7, 0x240000ea, - 0xd100f803, - 0x240000e2, - 0x79000002, - 0x240400e2, + 0xd100f804, 0x240001c6, 0x24100086, - 0x00e2e6e6, + 0x79000003, + 0x240001c6, + 0x24140086, 0x240000e1, 0xc901f805, 0x90f2388c, @@ -786,7 +785,7 @@ 0x00e1e3e3, 0xe1002382, 0xf1003982, - 0x5700e244, + 0x5700e245, 0x240000fb, 0xe1443d9b, 0xc901f80c,
--- a/pru_rtaudio.p Mon May 11 20:11:20 2015 +0100 +++ b/pru_rtaudio.p Tue May 12 23:48:37 2015 +0100 @@ -182,9 +182,6 @@ #define FLAG_BIT_USE_SPI 1 #define FLAG_BIT_MCASP_HWORD 2 // Whether we are on the high word for McASP transmission #define FLAG_BIT_USE_DIGITAL 3 -/*#define FLAG_BIT_DIGITAL_BUFFER 4 //Whether we are using buffer located at - // 0: MEM_DIGITAL_BASE or -*/ // 1: MEM_DIGITAL_BASE + 512 // Registers used throughout // r1, r2, r3 are used for temporary storage @@ -414,7 +411,13 @@ // DIGITAL new code ends here - + +.macro HANG +DALOOP: +set r30.t14 +clr r30.t14 +QBA DALOOP +.endm // Bring CS line low to write to DAC .macro DAC_CS_ASSERT MOV r27, DAC_CS_PIN @@ -597,15 +600,25 @@ // Find out whether we should use DIGITAL LBBO r2, reg_comm_addr, COMM_USE_DIGITAL, 4 - QBEQ DIGITAL_FLAG_CHECK_DONE, r2, 0 - SET reg_flags, reg_flags, FLAG_BIT_USE_DIGITAL -// SET reg_flags, reg_flags, FLAG_BIT_DIGITAL_BUFFER //set the flag, so that in WRITE_ONE_BUFFER we will start from buffer0 -DIGITAL_FLAG_CHECK_DONE: + QBEQ DIGITAL_INIT_DONE, r2, 0 // if we use digital + SET reg_flags, reg_flags, FLAG_BIT_USE_DIGITAL +/* This block of code is not really needed, as the memory is initialized by ARM before the PRU is started. +Will leave it here for future reference +DIGITAL_INIT: //set the digital buffer to 0x0000ffff (all inputs), to prevent unwanted high outputs + //the loop is unrolled by a factor of four just to take advantage of the speed of SBBO on larger byte bursts, but there is no real need for it + MOV r2, 0x0000ffff //value to store. 0x0000ffff means all inputs + MOV r3, MEM_DIGITAL_BASE //start of the digital buffer + MOV r4, MEM_DIGITAL_BASE+2*MEM_DIGITAL_BUFFER1_OFFSET //end of the digital buffer +DIGITAL_INIT_BUFFER_LOOP: + SBBO r2, r3, 0, 4 + ADD r3, r3, 4 //increment pointer + QBGT DIGITAL_INIT_BUFFER_LOOP, r3, r4 //loop until we reach the end of the buffer +*/ +DIGITAL_INIT_DONE: // Find out whether we should use SPI ADC and DAC LBBO r2, reg_comm_addr, COMM_USE_SPI, 4 QBEQ SPI_FLAG_CHECK_DONE, r2, 0 SET reg_flags, reg_flags, FLAG_BIT_USE_SPI - SPI_FLAG_CHECK_DONE: // If we don't use SPI, then skip all this init QBBC SPI_INIT_DONE, reg_flags, FLAG_BIT_USE_SPI @@ -749,17 +762,49 @@ MCASP_REG_SET_BIT_AND_POLL MCASP_XGBLCTL, (1 << 12) // Set XFRST // Initialisation -LBBO reg_frame_total, reg_comm_addr, COMM_BUFFER_FRAMES, 4 // Total frame count (SPI; 0.5x-2x for McASP) -MOV reg_dac_buf0, 0 // DAC buffer 0 start pointer -LSL reg_dac_buf1, reg_frame_total, 1 // DAC buffer 1 start pointer = N[ch]*2[bytes]*bufsize -LMBD r2, reg_num_channels, 1 // Returns 1, 2 or 3 depending on the number of channels -LSL reg_dac_buf1, reg_dac_buf1, r2 // Multiply by 2, 4 or 8 to get the N[ch] scaling above -MOV reg_mcasp_buf0, 0 // McASP DAC buffer 0 start pointer -LSL reg_mcasp_buf1, reg_frame_total, r2 // McASP DAC buffer 1 start pointer = 2[ch]*2[bytes]*(N/4)[samples/spi]*bufsize -CLR reg_flags, reg_flags, FLAG_BIT_BUFFER1 // Bit 0 holds which buffer we are on -MOV r2, 0 -SBBO r2, reg_comm_addr, COMM_FRAME_COUNT, 4 // Start with frame count of 0 - + LBBO reg_frame_total, reg_comm_addr, COMM_BUFFER_FRAMES, 4 // Total frame count (SPI; 0.5x-2x for McASP) + MOV reg_dac_buf0, 0 // DAC buffer 0 start pointer + LSL reg_dac_buf1, reg_frame_total, 1 // DAC buffer 1 start pointer = N[ch]*2[bytes]*bufsize + LMBD r2, reg_num_channels, 1 // Returns 1, 2 or 3 depending on the number of channels + LSL reg_dac_buf1, reg_dac_buf1, r2 // Multiply by 2, 4 or 8 to get the N[ch] scaling above + MOV reg_mcasp_buf0, 0 // McASP DAC buffer 0 start pointer + LSL reg_mcasp_buf1, reg_frame_total, r2 // McASP DAC buffer 1 start pointer = 2[ch]*2[bytes]*(N/4)[samples/spi]*bufsize + CLR reg_flags, reg_flags, FLAG_BIT_BUFFER1 // Bit 0 holds which buffer we are on + MOV r2, 0 + SBBO r2, reg_comm_addr, COMM_FRAME_COUNT, 4 // Start with frame count of 0 +/* This block of code is not really needed, as the memory is initialized by ARM before the PRU is started. +Will leave it here for future reference +//Initialise all SPI and audio buffers (DAC0, DAC1, ADC0, ADC1) to zero. +//This is useful for analog outs so they do not have spikes during the first buffer. +//This is not very useful for audio, as you still hear the initial "tumpf" when the converter starts +//and each sample in the DAC buffer is reset to 0 after it is written to the DAC. + + QBBC SPI_INIT_BUFFER_DONE, reg_flags, FLAG_BIT_USE_SPI +//Initialize SPI buffers +//compute the memory offset of the end of the audio buffer and store it in r4 + SUB r4, reg_dac_buf1, reg_dac_buf0 // length of the buffer, assumes reg_dac_buf1>ref_dac_buf0 + LSL r4, r4, 2 //length of four buffers (DAC0, DAC1, ADC0, ADC1) + ADD r4, reg_dac_buf0, r4 //total offset + MOV r2, 0// value to store + MOV r3, 0 // offset counter +SPI_INIT_BUFFER_LOOP: + SBCO r2, C_ADC_DAC_MEM, r3, 4 + ADD r3, r3, 4 + QBGT SPI_INIT_BUFFER_LOOP, r3, r4 +SPI_INIT_BUFFER_DONE: + +//Initialize audio buffers +//compute the memory offset of the end of the audio buffer and store it in r4 + SUB r4, reg_mcasp_buf1, reg_mcasp_buf0 // length of the buffer, assumes reg_mcasp_buf1>ref_mcasp_buf0 + LSL r4, r4, 2 //length of four buffers (DAC0, DAC1, ADC0, ADC1) + ADD r4, reg_mcasp_buf0, r4 //total offset + MOV r2, 0 // value to store + MOV r3, 0 // offset counter + MCASP_INIT_BUFFER_LOOP: + SBCO r2, C_MCASP_MEM, r3, 4 + ADD r3, r3, 4 + QBGT MCASP_INIT_BUFFER_LOOP, r3, r4 +*/ // Here we are out of sync by one TDM slot since the 0 word transmitted above will have occupied // the first output slot. Send one more word before jumping into the loop. MCASP_DAC_WAIT_BEFORE_LOOP: @@ -778,6 +823,7 @@ MCASP_REG_READ_EXT MCASP_RBUF, r2 WRITE_ONE_BUFFER: + // Write a single buffer of DAC samples and read a buffer of ADC samples // Load starting positions MOV reg_dac_current, reg_dac_buf0 // DAC: reg_dac_current is current pointer @@ -792,13 +838,11 @@ MOV reg_frame_current, 0 QBBS DIGITAL_BASE_CHECK_SET, reg_flags, FLAG_BIT_BUFFER1 //check which buffer we are using for DIGITAL // if we are here, we are using buffer0 - MOV r2, 0 //so adjust offset appropriately + MOV reg_digital_current, MEM_DIGITAL_BASE QBA DIGITAL_BASE_CHECK_DONE DIGITAL_BASE_CHECK_SET: //if we are here, we are using buffer1 - MOV r2, MEM_DIGITAL_BUFFER1_OFFSET //so adjust offset appropriately + MOV reg_digital_current, MEM_DIGITAL_BASE+MEM_DIGITAL_BUFFER1_OFFSET //so adjust offset appropriately DIGITAL_BASE_CHECK_DONE: - MOV reg_digital_current, MEM_DIGITAL_BASE - ADD reg_digital_current, reg_digital_current, r2 WRITE_LOOP: // Write N channels to DAC from successive values in memory @@ -899,6 +943,7 @@ LSL r8, r8, AD7699_CHANNEL_OFFSET MOV r7, AD7699_CFG_MASK OR r7, r7, r8 + //ssssssssssssssssssssssssssss ADC_WRITE_GPIO r7, r7, r1