753 lines
25 KiB
OpenEdge ABL
753 lines
25 KiB
OpenEdge ABL
.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
|
|
|
|
|