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