.origin 0                        // start of program in PRU memory
.entrypoint START                // program entry point for the debugger

// Copyright Doug Lewis Sept 2017

//#include </usr/include/prussdrv.h>
//#include </usr/include/pruss_intc_mapping.h>
#include <./pruadc.h>



START:

//  Clear all outputs to the ADS 1278 
        CLR     r30.t0
        CLR     r30.t1
        CLR     r30.t2
        CLR     r30.t3
        CLR     r30.t4
        CLR     r30.t5
        CLR     r30.t6
        CLR     r30.t7
        CLR     r30.t8


// Clear all registers we are going to use, since we know that they can come up 
// with garbage in them 
        MOV     r0, 0 
        MOV     r1, 0
        MOV     CLOCK_COUNT, 0     // R2
        MOV     RUN_STATE, 0       // R3
        MOV     ADC_CNTRL_STR, 0   // R4 
        MOV     ADC_CHNG_FLG, 0    // R5 
        MOV     SMPL_BIT_CNTR, 0   // R6 
        MOV     CHAN_BITMASK, 0    // R7
        MOV     SHR_MEM_PTR, 0     // R8 
        MOV     SHR_MEM_SZ, 0      // R9
        MOV     COUNT,      0      // R10
        MOV     HEAD, 0            // R11
        MOV     TAIL, 0            // R12
        MOV     PRU_DATA_STRT, 0  // R13
        MOV     CURRENT_SAMPLE, 0  // R14 
        MOV     CURRENT_BUF, 0     // R15
        MOV     CUR_BUF_ADRS, 0    // R16
        MOV     CUR_BUF_LEFT, 0    // R17
        MOV     SHR_MEM_START, 0    // R18
        MOV     NUM_BLOCKS, 0      // R19
        MOV     BUFF_COUNT, 0      // R20
        MOV     SAMPLE1    , 0     // R21
	MOV     SAMPLE2    , 0     // R22
	MOV     SAMPLE3    , 0     // R23
	MOV     SAMPLE4    , 0     // R24
	MOV     SAMPLE5    , 0     // R25
	MOV     SAMPLE6    , 0     // R26
	MOV     SAMPLE7    , 0     // R27
	MOV     SAMPLE8    , 0     // R28
        MOV     R29, 0
        MOV     R30, 0
	MOV     R31, 0

// Enable the OCP master port -- allows transfer of data to Linux userspace
        LBCO    r0, C4, 4, 4     // load PRU-ICSS CFG reg into r0 
        CLR     r0, r0, 4        // clear bit 4 (STANDBY_INIT)
        SBCO    r0, C4, 4, 4     // store the modified r0 back at the load addr

START_LOOP:                                  // This is an easy place to halt the debugger
	MOV	r1,ADC_STATE_ADDR	 
	LBBO	RUN_STATE, r1, 0, 4	     // the daq state is now loaded into r3. 
        QBEQ    START_LOOP, RUN_STATE, 0     // We hang out in a loop until told to read the adc


	MOV	r1,ADC_ADDR	 
	LBBO    SHR_MEM_START, r1, 0, 4     // load the Linux address that is passed into r8 -- to store sample values

        //Skip the offset  bytes that we use for adc_conf at the beginning of the shared memory region
        MOV     r1, PRU1_START_OFFSET
        ADD     PRU_DATA_STRT, SHR_MEM_START, R1
	MOV	SHR_MEM_PTR, PRU_DATA_STRT

	MOV	r1,ADC_SIZE	
	LBBO	SHR_MEM_SZ, r1, 0, 4	 // load the size that is passed into r9 -- the number of samples to take
 
	MOV	r1,PRU1_NUM_BLOCKS	 
	LBBO	NUM_BLOCKS, r1, 0, 4	 // load the count of how many 128K blocks we are going to record 

        
MEM_BUF_ALLOCATED:        
        MOV     CUR_BUF_LEFT, BUFSIZE

	MOV	r1,ADC_CNTRL_CHANGE       // load the base address into r1
	LBBO	ADC_CHNG_FLG, r1, 0, 4	  // the ADC_CNTL_CHANGE is now loaded into R5 


        QBBS   CONFIG_CHANGE, ADC_CHNG_FLG.t0     // If bit 1 of ADC_CTRL_CHANGE is set, there is a config
                                        //change
        QBA    CONFIG_DONE              // Else no changes, goto CONFIG_DONE

CONFIG_CHANGE:
	MOV	r1, CLOCK_CNTR_ADDR	 
	LBBO	CLOCK_COUNT, r1, 0, 4	         // the clock delay is now loaded into r2. 

	MOV	r1,ADC_CNTRL_STR_ADDR	
	LBBO	ADC_CNTRL_STR, r1, 0, 4	         // the ADC_CNTL_STR is now loaded into R4 

        CLR     ADC_CHNG_FLG.t1                    // Clear the change flag so we dont do the config every loop


        QBBS    SET_PWDN1, ADC_CNTRL_STR.t0         
        QBA     PWDN2
SET_PWDN1: 
	SET     r30.t6   // Pin 39, CH B 1-4 

PWDN2:
        QBBS    SET_PWDN2, ADC_CNTRL_STR.t1 
        QBA     PWDN3
SET_PWDN2:
	SET     r30.t7  // Pin 40, CH C 1-4

PWDN3:
        QBBS    SET_PWDN3, ADC_CNTRL_STR.t2  
        QBA     PWDN4
SET_PWDN3:
	SET     r30.t4  // Pin 41, CH B 5-8 

PWDN4:
        QBBS    SET_PWDN4, ADC_CNTRL_STR.t3  
        QBA     PWDN5
SET_PWDN4:
	SET     r30.t5  // Pin 42, CH D 1-4

PWDN5:
        QBBS    SET_PWDN5, ADC_CNTRL_STR.t4
        QBA     PWDN6
SET_PWDN5:
	SET     r30.t2  // Pin 43, CH A 5-8

PWDN6:
        QBBS    SET_PWDN6, ADC_CNTRL_STR.t5
        QBA     PWDN7
SET_PWDN6:
	SET     r30.t3 // Pin 44, CHD 5-8

PWDN7:
        QBBS    SET_PWDN7, ADC_CNTRL_STR.t6
        QBA     PWDN8
SET_PWDN7:
	SET     r30.t0  // Pin 45 CH A 1-4

PWDN8:
        QBBS    SET_PWDN8, ADC_CNTRL_STR.t7  
        QBA     CONFIG_DONE
SET_PWDN8:
        SET    r30.t1  // Pin 46, CH C 5-8



CONFIG_DONE:
        QBEQ    THROUGH_TEST, RUN_STATE, TEST   // If RUN_STATE = 1, start data collection, If 2, test mode.

// Set the SYNC Pin High
        SET SPI_SYNC_PIN

        MOV     r1, DELAY_PULSES     // We are going to delay here for a little bit in order for the 5V and 10V
                                     // rail voltages to ramp after enabling the daqs.
DELAY_START:
// Generate one clock pulse for test purposes       
        MOV     r0, CLOCK_COUNT      // Reload the clock delay val into R0
	SET	SPI_CLK_B_D_PIN     					 // set the clock line to be high
DELAY_CLOCK_TEST_PULSE:
        SUB     r0, r0, 1        
        QBNE    DELAY_CLOCK_TEST_PULSE, r0, 0   
 
        CLR     SPI_CLK_B_D_PIN

        SUB     r1, r1, 1
        QBNE    DELAY_START, r1, 0


//  sync  is active low, so we clear it
        MOV     r0, CLOCK_COUNT      // Reload the clock delay val into R0
	CLR	SPI_SYNC_PIN         // CLR the sync pin. Once it goes low, the ADC will start to 
                                     // convert data, and the DSR should go high after this.

DELAY_SYNC_PULSE:
        SUB     r0, r0, 1        
        QBNE    DELAY_SYNC_PULSE, r0, 0   

        SET     SPI_SYNC_PIN
 


NEXT_BUFFER:
        MOV     CUR_BUF_LEFT, BUFSIZE

        // Move a well known cow into first four bytes of the buffer header.
        MOV     R1, 0xDEADBEEF
        SBBO    R1, SHR_MEM_PTR, 0, 4

        //  Copy the buffer count  into the second 4 bytes of the header
	SBBO	BUFF_COUNT, SHR_MEM_PTR, 4, 4 // store the sample value into shared  memory space

        //Skip 32 bytes that we will use for the 128k buffer header.
	ADD	SHR_MEM_PTR, SHR_MEM_PTR, BUF_HDR_SIZE 

        SUB     CUR_BUF_LEFT, CUR_BUF_LEFT, BUF_HDR_SIZE

//We want to look at the first bit in the config bitmask.
READ_NEXT_SAMPLE:
	MOV	r1,ADC_STATE_ADDR    //Check to see if we are still need to be running	  
	LBBO	RUN_STATE, r1, 0, 4	       
        QBEQ    CONTINUE_DAQ, RUN_STATE, 1      
        QBA END // We've been told to stop.

CONTINUE_DAQ:
	MOV	SAMPLE1, 0
	MOV	SAMPLE2, 0
	MOV	SAMPLE3, 0
	MOV	SAMPLE4, 0
	MOV	SAMPLE5, 0
	MOV	SAMPLE6, 0
	MOV	SAMPLE7, 0
	MOV	SAMPLE8, 0

// We look for DSR to be high 
DATA_READY_HIGH:
        QBBS    DATA_READY_WAIT, SPI_DSR_B_D_PIN      
        QBA     DATA_READY_HIGH

DATA_READY_WAIT:
        QBBC    DATA_READY, SPI_DSR_B_D_PIN    // If Data Ready line clear, read a sample
        QBA     DATA_READY_WAIT      // Else hang out in a tight loop ...

        MOV     r0, 0
        MOV     r0, 0

DATA_READY:
	MOV     SMPL_BIT_CNTR, SAMPLE_SIZE  // We're going to read 24 bits        
READ_CHANNEL1:
        MOV     r0, CLOCK_COUNT      // Reload the clock delay val into R0
	SET	SPI_CLK_B_D_PIN     					 // set the clock line to be high

DELAYON1:
        SUB     r0, r0, 1        
        QBNE    DELAYON1, r0, 0   

	    
	CLR	SPI_CLK_B_D_PIN   // set the clock to be low
        

	// Read Data In 
	QBBC	ZERO_BIT1, SPI_DATA_IN_B_D_PIN  // Check to see whether Data In is a 0 or 1
	OR	SAMPLE1, SAMPLE1, 0x00000001

	MOV     r0, CLOCK_COUNT
DELAYOFF1:
        SUB     r0, r0, 1        
        QBNE    DELAYOFF1, r0, 0   // loop until the delay has expired (equals 0)

ZERO_BIT1:	
        LSL     SAMPLE1, SAMPLE1, 1      // Shift current sample contents left by one
        
	SUB     SMPL_BIT_CNTR, SMPL_BIT_CNTR, 1            // See if we have read all 24 bits of the sample
	QBNE    READ_CHANNEL1, SMPL_BIT_CNTR, 0


//////////////////////////
	MOV     SMPL_BIT_CNTR, SAMPLE_SIZE  // We're going to read 24 bits        
READ_CHANNEL2:
        MOV     r0, CLOCK_COUNT      // Reload the clock delay val into R0
	SET	SPI_CLK_B_D_PIN         // set the clock to be high

DELAYON2:
        SUB     r0, r0, 1        
        QBNE    DELAYON2, r0, 0   

        // Reload the clock delay val into R0
	CLR	 SPI_CLK_B_D_PIN   // set the clock to be low

	// Read Data In 
	QBBC	ZERO_BIT2, SPI_DATA_IN_B_D_PIN  // Check to see whether Data In is a 0 or 1
	OR	SAMPLE2, SAMPLE2, 0x00000001

	MOV     r0, CLOCK_COUNT
DELAYOFF2:
        SUB     r0, r0, 1        
        QBNE    DELAYOFF2, r0, 0   // loop until the delay has expired (equals 0)

ZERO_BIT2:	
        LSL     SAMPLE2, SAMPLE2, 1      // Shift current sample contents left by one

        SUB     SMPL_BIT_CNTR, SMPL_BIT_CNTR, 1            // See if we have read all 24 bits of the sample
         
	QBNE    READ_CHANNEL2, SMPL_BIT_CNTR, 0

//////////////////////
	MOV     SMPL_BIT_CNTR, SAMPLE_SIZE  // We're going to read 24 bits        
READ_CHANNEL3:
        MOV     r0, CLOCK_COUNT      // Reload the clock delay val into R0
	SET	SPI_CLK_B_D_PIN         // set the clock to be high

DELAYON3:
        SUB     r0, r0, 1        
        QBNE    DELAYON3, r0, 0   

        // Reload the clock delay val into R0
	CLR	SPI_CLK_B_D_PIN        // set the clock to be low

        // Read Data In 
	QBBC	ZERO_BIT3, SPI_DATA_IN_B_D_PIN  // Check to see whether Data In is a 0 or 1
	OR	SAMPLE3, SAMPLE3, 0x00000001

	MOV     r0, CLOCK_COUNT
DELAYOFF3:
        SUB     r0, r0, 1        
        QBNE    DELAYOFF3, r0, 0   // loop until the delay has expired (equals 0)

ZERO_BIT3:	
        LSL     SAMPLE3, SAMPLE3, 1      // Shift current sample contents left by one

        SUB     SMPL_BIT_CNTR, SMPL_BIT_CNTR, 1            // See if we have read all 24 bits of the sample
         
	QBNE    READ_CHANNEL3, SMPL_BIT_CNTR, 0

/////////////////////////

	MOV     SMPL_BIT_CNTR, SAMPLE_SIZE  // We're going to read 24 bits        
READ_CHANNEL4:
        MOV     r0, CLOCK_COUNT      // Reload the clock delay val into R0
	SET	SPI_CLK_B_D_PIN         // set the clock to be high

DELAYON4:
        SUB     r0, r0, 1        
        QBNE    DELAYON4, r0, 0   

        // Reload the clock delay val into R0
	CLR	SPI_CLK_B_D_PIN       // set the clock to be low

	// Read Data In 
	QBBC	ZERO_BIT4, SPI_DATA_IN_B_D_PIN  // Check to see whether Data In is a 0 or 1
	OR	SAMPLE4, SAMPLE4, 0x00000001

	MOV     r0, CLOCK_COUNT
DELAYOFF4:
        SUB     r0, r0, 1        
        QBNE    DELAYOFF4, r0, 0   // loop until the delay has expired (equals 0)

ZERO_BIT4:	
        LSL     SAMPLE4, SAMPLE4, 1      // Shift current sample contents left by one

        SUB     SMPL_BIT_CNTR, SMPL_BIT_CNTR, 1            // See if we have read all 24 bits of the sample
         
	QBNE    READ_CHANNEL4, SMPL_BIT_CNTR, 0

/////////////////////////
	MOV     SMPL_BIT_CNTR, SAMPLE_SIZE  // We're going to read 24 bits        
READ_CHANNEL5:
        MOV     r0, CLOCK_COUNT      // Reload the clock delay val into R0
	SET	SPI_CLK_B_D_PIN         // set the clock to be high

DELAYON5:
        SUB     r0, r0, 1        
        QBNE    DELAYON5, r0, 0   

        // Reload the clock delay val into R0
	CLR	SPI_CLK_B_D_PIN         // set the clock to be low

	// Read Data In 
	QBBC	ZERO_BIT5, SPI_DATA_IN_B_D_PIN  // Check to see whether Data In is a 0 or 1
	OR	SAMPLE5, SAMPLE5, 0x00000001

	MOV     r0, CLOCK_COUNT
DELAYOFF5:
        SUB     r0, r0, 1        
        QBNE    DELAYOFF5, r0, 0   // loop until the delay has expired (equals 0)

ZERO_BIT5:	
        LSL     SAMPLE5, SAMPLE5, 1      // Shift current sample contents left by one

        SUB     SMPL_BIT_CNTR, SMPL_BIT_CNTR, 1            // See if we have read all 24 bits of the sample
         
	QBNE    READ_CHANNEL5, SMPL_BIT_CNTR, 0

/////////////////////////
	MOV     SMPL_BIT_CNTR, SAMPLE_SIZE  // We're going to read 24 bits        
READ_CHANNEL6:
        MOV     r0, CLOCK_COUNT      // Reload the clock delay val into R0
	SET	SPI_CLK_B_D_PIN         // set the clock to be high

DELAYON6:
        SUB     r0, r0, 1        
        QBNE    DELAYON6, r0, 0   

        // Reload the clock delay val into R0
	CLR	SPI_CLK_B_D_PIN         // set the clock to be low

	// Read Data In 
	QBBC	ZERO_BIT6, SPI_DATA_IN_B_D_PIN  // Check to see whether Data In is a 0 or 1
	OR	SAMPLE6, SAMPLE6, 0x00000001

	MOV     r0, CLOCK_COUNT
DELAYOFF6:
        SUB     r0, r0, 1        
        QBNE    DELAYOFF6, r0, 0   // loop until the delay has expired (equals 0)

ZERO_BIT6:	
        LSL     SAMPLE6, SAMPLE6, 1      // Shift current sample contents left by one

        SUB     SMPL_BIT_CNTR, SMPL_BIT_CNTR, 1            // See if we have read all 24 bits of the sample
         
	QBNE    READ_CHANNEL6, SMPL_BIT_CNTR, 0

/////////////////////////
	MOV     SMPL_BIT_CNTR, SAMPLE_SIZE  // We're going to read 24 bits        
READ_CHANNEL7:
        MOV     r0, CLOCK_COUNT      // Reload the clock delay val into R0
	SET	SPI_CLK_B_D_PIN         // set the clock to be high

DELAYON7:
        SUB     r0, r0, 1        
        QBNE    DELAYON7, r0, 0   

        // Reload the clock delay val into R0
	CLR	SPI_CLK_B_D_PIN         // set the clock to be low

	// Read Data In 
	QBBC	ZERO_BIT7, SPI_DATA_IN_B_D_PIN  // Check to see whether Data In is a 0 or 1
	OR	SAMPLE7, SAMPLE7, 0x00000001

	MOV     r0, CLOCK_COUNT
DELAYOFF7:
        SUB     r0, r0, 1        
        QBNE    DELAYOFF7, r0, 0   // loop until the delay has expired (equals 0)

ZERO_BIT7:	
        LSL     SAMPLE7, SAMPLE7, 1      // Shift current sample contents left by one

        SUB     SMPL_BIT_CNTR, SMPL_BIT_CNTR, 1            // See if we have read all 24 bits of the sample
         
	QBNE    READ_CHANNEL7, SMPL_BIT_CNTR, 0

/////////////////////////
	MOV     SMPL_BIT_CNTR, SAMPLE_SIZE  // We're going to read 24 bits        
READ_CHANNEL8:
        MOV     r0, CLOCK_COUNT      // Reload the clock delay val into R0
	SET	SPI_CLK_B_D_PIN         // set the clock to be high

DELAYON8:
        SUB     r0, r0, 1        
        QBNE    DELAYON8, r0, 0   

       // Reload the clock delay val into R0
	CLR	SPI_CLK_B_D_PIN         // set the clock to be low

	// Read Data In 
	QBBC	ZERO_BIT8, SPI_DATA_IN_B_D_PIN  //to see whether Data In is a 0 or 1
	OR	SAMPLE8, SAMPLE8, 0x00000001

	MOV     r0, CLOCK_COUNT
DELAYOFF8:
        SUB     r0, r0, 1        
        QBNE    DELAYOFF8, r0, 0   // loop until the delay has expired (equals 0)

ZERO_BIT8:	
        LSL     SAMPLE8, SAMPLE8, 1     // Shift current sample contents left by one

        SUB     SMPL_BIT_CNTR, SMPL_BIT_CNTR, 1            // See if we have read all 24 bits of the sample
         
	QBNE    READ_CHANNEL8, SMPL_BIT_CNTR, 0

/////////////////////////
STORE_SAMPLE:                     
 
        LSR	SAMPLE1, SAMPLE1, 1      // Need to shift the sample word back to the right by one
	LSR	SAMPLE2, SAMPLE2, 1
	LSR	SAMPLE3, SAMPLE3, 1
	LSR	SAMPLE4, SAMPLE4, 1
	LSR	SAMPLE5, SAMPLE5, 1
	LSR	SAMPLE6, SAMPLE6, 1
	LSR	SAMPLE7, SAMPLE7, 1
	LSR	SAMPLE8, SAMPLE8, 1

        MOV     SAMPLE1.b3, 0x01    // Stash the channel bitmask in the upper byte used to store the sample  
	MOV     SAMPLE2.b3, 0x02
	MOV     SAMPLE3.b3, 0x04
	MOV     SAMPLE4.b3, 0x08
	MOV     SAMPLE5.b3, 0x10
	MOV     SAMPLE6.b3, 0x20
	MOV     SAMPLE7.b3, 0x40
	MOV     SAMPLE8.b3, 0x80

	SBBO	SAMPLE1, SHR_MEM_PTR, 0, 4 // store the sample value into shared  memory space
	ADD	SHR_MEM_PTR, SHR_MEM_PTR, 4	 // Add 4  bytes per sample to the address pointer
		
	SBBO	SAMPLE2, SHR_MEM_PTR, 0, 4 // store the sample value into shared  memory space
	ADD	SHR_MEM_PTR, SHR_MEM_PTR, 4	 // Add 4  bytes per sample to the address pointer

	SBBO	SAMPLE3, SHR_MEM_PTR, 0, 4 // store the sample value into shared  memory space
	ADD	SHR_MEM_PTR, SHR_MEM_PTR, 4	 // Add 4  bytes per sample to the address pointer
		 
	SBBO	SAMPLE4, SHR_MEM_PTR, 0, 4 // store the sample value into shared  memory space
	ADD	SHR_MEM_PTR, SHR_MEM_PTR, 4	 // Add 4  bytes per sample to the address pointer

	SBBO	SAMPLE5, SHR_MEM_PTR, 0, 4 // store the sample value into shared  memory space
	ADD	SHR_MEM_PTR, SHR_MEM_PTR, 4	 // Add 4  bytes per sample to the address pointer

	SBBO	SAMPLE6, SHR_MEM_PTR, 0, 4 // store the sample value into shared  memory space
	ADD	SHR_MEM_PTR, SHR_MEM_PTR, 4	 // Add 4  bytes per sample to the address pointer

	SBBO	SAMPLE7, SHR_MEM_PTR, 0, 4 // store the sample value into shared  memory space
	ADD	SHR_MEM_PTR, SHR_MEM_PTR, 4	 // Add 4  bytes per sample to the address pointer

	SBBO	SAMPLE8, SHR_MEM_PTR, 0, 4 // store the sample value into shared  memory space
	ADD	SHR_MEM_PTR, SHR_MEM_PTR, 4	 // Add 4  bytes per sample to the address pointer

	SUB	CUR_BUF_LEFT, CUR_BUF_LEFT, 32	 // reducing the number of samples - 4 bytes per sample, 8 channels
	
	QBEQ	BUFFER_DONE, CUR_BUF_LEFT, 0       // See if we have taken 128kb of samples
 
        QBA     READ_NEXT_SAMPLE  // If we've looped thru all channels in the sample. wait for the next sample

BUFFER_DONE:				 
        MOV     CUR_BUF_LEFT, BUFSIZE

        // Subtract 32 bytes that are the header
	SUB	CUR_BUF_LEFT, CUR_BUF_LEFT, 32	 // reducing the number of samples - 4 bytes per sample, 8 channels
        // Set the amount of the current buffer left to be 128k
        
        ADD     BUFF_COUNT, BUFF_COUNT, 1

        MOV     R1, 1
        SBBO    R1, SHR_MEM_START, PRU1_WR_FLAG, 4
        
        SBBO    BUFF_COUNT, SHR_MEM_START, PRU1_BUFF_COUNT, 4 

        ADD     HEAD, HEAD, 1
        SBBO    HEAD, SHR_MEM_START, PRU1_HEAD, 4 

        QBNE    NO_WRAP, HEAD, QUEUE_SIZE  
         
        MOV     HEAD, 0
        SBBO    HEAD, SHR_MEM_START, PRU1_HEAD, 4

        QBA     WRAP_TIME

NO_WRAP:
        // If we have recorded all of the buffers that we need to, then halt.
        SUB     NUM_BLOCKS, NUM_BLOCKS, 1
        QBEQ    END, NUM_BLOCKS, 0  


        QBA     NEXT_BUFFER

WRAP_TIME:
        // Always wanted to be a rapper ;-0)
        // We have used all the buffers in the shmem queue, wrap to the beginning.
        SUB     NUM_BLOCKS, NUM_BLOCKS, 1
        QBEQ    END, NUM_BLOCKS, 0  

        ADD     WRAP_COUNT, WRAP_COUNT, 1

        // We've wrapped, so we need to point back to the start of data buffer start 
        MOV  SHR_MEM_PTR, PRU_DATA_STRT    


        // We want to write WRAP_COUNT to shared memory adc_pru_data0[12] here.
        SBBO    WRAP_COUNT, SHR_MEM_START, PRU1_WRAP_COUNT, 4 

        QBA     NEXT_BUFFER


//////////////////////////////////////////////////////////////////////////////////////////////////////
//
//   Throughput test 
//
//////////////////////////////////////////////////////////////////////////////////////////////////////
THROUGH_TEST:

	MOV	r1,ADC_ADDR	 
	LBBO    SHR_MEM_PTR, r1, 0, 4     // load the Linux address that is passed into r8 -- to store sample values

        //Skip the offset  bytes that we use for adc_conf at the beginning of the shared memory region
        MOV     r1, PRU1_START_OFFSET
	ADD	SHR_MEM_PTR, SHR_MEM_PTR, r1


	MOV	r1,ADC_SIZE	
	LBBO	SHR_MEM_SZ, r1, 0, 4	 // load the size that is passed into r9 -- the number of samples to take

NEXT_TEST_BUFFER:
        MOV     CUR_BUF_LEFT, BUFSIZE

        // Move a well done hamburger into the first four  bytes of the buffer header.
        MOV     R1, 0xDEADBEEF
        SBBO    R1, SHR_MEM_PTR, 0, 4

        //  Copy the buffer count  into the second 4 bytes of the header
	SBBO	BUFF_COUNT, SHR_MEM_PTR, 4, 4 // store the sample value into shared  memory space

        //Skip 32 bytes that we will use for the 128k buffer header. 
	ADD	SHR_MEM_PTR, SHR_MEM_PTR, BUF_HDR_SIZE

        SUB     CUR_BUF_LEFT, CUR_BUF_LEFT, BUF_HDR_SIZE

CREATE_NEXT_TEST_SAMPLE:
       
        // Move a counter value into each of the eight 32 bit sample words. 
        // We are going to do this brute force (instead of a small) loop to be as fast as possible.
        MOV     SAMPLE1, COUNT
        ADD     COUNT, COUNT, 1

        MOV     SAMPLE2, COUNT
        ADD     COUNT, COUNT, 1

        MOV     SAMPLE3, COUNT
        ADD     COUNT, COUNT, 1

        MOV     SAMPLE4, COUNT
        ADD     COUNT, COUNT, 1

        MOV     SAMPLE5, COUNT
        ADD     COUNT, COUNT, 1

        MOV     SAMPLE6, COUNT
        ADD     COUNT, COUNT, 1

        MOV     SAMPLE7, COUNT
        ADD     COUNT, COUNT, 1

        MOV     SAMPLE8, COUNT
        ADD     COUNT, COUNT, 1


        // We look to see if COUNT > FFFFFF, if so, set to zero. 
        MOV     R1, FULL_COUNT
        QBEQ    ZERO_COUNT, R1, COUNT
        QBA     WRITE_CHAN_BYTE

ZERO_COUNT:
        MOV     COUNT, 0

WRITE_CHAN_BYTE:
        MOV     SAMPLE1.b3, 0x01    // Stash the channel bitmask in the upper byte used to store the sample  
	MOV     SAMPLE2.b3, 0x02
	MOV     SAMPLE3.b3, 0x04
	MOV     SAMPLE4.b3, 0x08
	MOV     SAMPLE5.b3, 0x10
	MOV     SAMPLE6.b3, 0x20
	MOV     SAMPLE7.b3, 0x40
	MOV     SAMPLE8.b3, 0x80

	SBBO	SAMPLE1, SHR_MEM_PTR, 0, 4 // store the sample value into shared  memory space
	ADD	SHR_MEM_PTR, SHR_MEM_PTR, 4	 // Add 4  bytes per sample to the address pointer
		
	SBBO	SAMPLE2, SHR_MEM_PTR, 0, 4 // store the sample value into shared  memory space
	ADD	SHR_MEM_PTR, SHR_MEM_PTR, 4	 // Add 4  bytes per sample to the address pointer

	SBBO	SAMPLE3, SHR_MEM_PTR, 0, 4 // store the sample value into shared  memory space
	ADD	SHR_MEM_PTR, SHR_MEM_PTR, 4	 // Add 4  bytes per sample to the address pointer
		 
	SBBO	SAMPLE4, SHR_MEM_PTR, 0, 4 // store the sample value into shared  memory space
	ADD	SHR_MEM_PTR, SHR_MEM_PTR, 4	 // Add 4  bytes per sample to the address pointer

	SBBO	SAMPLE5, SHR_MEM_PTR, 0, 4 // store the sample value into shared  memory space
	ADD	SHR_MEM_PTR, SHR_MEM_PTR, 4	 // Add 4  bytes per sample to the address pointer

	SBBO	SAMPLE6, SHR_MEM_PTR, 0, 4 // store the sample value into shared  memory space
	ADD	SHR_MEM_PTR, SHR_MEM_PTR, 4	 // Add 4  bytes per sample to the address pointer

	SBBO	SAMPLE7, SHR_MEM_PTR, 0, 4 // store the sample value into shared  memory space
	ADD	SHR_MEM_PTR, SHR_MEM_PTR, 4	 // Add 4  bytes per sample to the address pointer

	SBBO	SAMPLE8, SHR_MEM_PTR, 0, 4 // store the sample value into shared  memory space
	ADD	SHR_MEM_PTR, SHR_MEM_PTR, 4	 // Add 4  bytes per sample to the address pointer

	SUB	CUR_BUF_LEFT, CUR_BUF_LEFT, 32	 // reducing the number of samples - 4 bytes per sample, 8 channels

        // We have created one sample, wait roughly 1/10547 secs to simulate sample time from DAQ	
	MOV     r0, INSTRUCTIONS_PER_SAMPLE
DELAY:
        SUB     r0, r0, 1        
        QBNE    DELAY, r0, 0   // loop until the delay has expired (equals 0)

	QBEQ	TEST_BUFFER_DONE, CUR_BUF_LEFT, 0       // See if we have taken 128kb of samples
 
        QBA     CREATE_NEXT_TEST_SAMPLE  // If we've looped thru all channels in the sample. wait for the next sample


TEST_BUFFER_DONE:				 
        // Set the amount of the current buffer left to be 128k
        MOV     CUR_BUF_LEFT, BUFSIZE

        // Subtract 32 bytes that are the header
	SUB	CUR_BUF_LEFT, CUR_BUF_LEFT, 32	 // reducing the number of samples - 4 bytes per sample, 8 channels
        
        ADD     BUFF_COUNT, BUFF_COUNT, 1

        MOV     R1, 1
        SBBO    R1, SHR_MEM_START, PRU1_WR_FLAG, 4
        
        SBBO    BUFF_COUNT, SHR_MEM_START, PRU1_BUFF_COUNT, 4 

        ADD     HEAD, HEAD, 1
        SBBO    HEAD, SHR_MEM_START, PRU1_HEAD, 4 

        QBNE    NO_TEST_WRAP, HEAD, QUEUE_SIZE  
         
        MOV     HEAD, 0
        SBBO    HEAD, SHR_MEM_START, PRU1_HEAD, 4

        QBA     TEST_WRAP_TIME

NO_TEST_WRAP:
        // If we have recorded all of the buffers that we need to, then halt.
        SUB     NUM_BLOCKS, NUM_BLOCKS, 1
        QBEQ    END, NUM_BLOCKS, 0  


        QBA     NEXT_TEST_BUFFER

TEST_WRAP_TIME:
        // Always wanted to be a rapper ;-0)
        // We have used all the buffers in the shmem queue, wrap to the beginning.
        SUB     NUM_BLOCKS, NUM_BLOCKS, 1
        QBEQ    END, NUM_BLOCKS, 0  

        ADD     WRAP_COUNT, WRAP_COUNT, 1

        // We've wrapped, so we need to point back to the start of data buffer start 
        MOV  SHR_MEM_PTR, PRU_DATA_STRT    


        // We want to write WRAP_COUNT to shared memory adc_pru_data0[12] here.
        SBBO    WRAP_COUNT, SHR_MEM_START, PRU1_WRAP_COUNT, 4 

        QBA     NEXT_TEST_BUFFER

// halt the pru program -- we reach here when we have read all of the intended buffers. 
END:
        CLR     r30.t6   // Pin 39, CH B 1-4
        CLR     r30.t7  // Pin 40, CH C 1-4
        CLR     r30.t4  // Pin 41, CH B 5-8
        CLR     r30.t5  // Pin 42, CH D 1-4
        CLR     r30.t2  // Pin 43, CH A 5-8
        CLR     r30.t3 // Pin 44, CHD 5-8
        CLR     r30.t0  // Pin 45 CH A 1-4
        CLR     r30.t1  // Pin 46, CH C 5-8
        CLR     r30.t8

        MOV     r31.b0, PRU0_R31_VEC_VALID | PRU_EVTOUT_0
	HALT                  


