Mercurial > hg > beaglert
diff pru_rtaudio.p @ 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 | 6d64ee8c0754 |
children | 638bc1ae2500 |
line wrap: on
line diff
--- 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