KISS Data Aquisition and Control System
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

752 lines
25 KiB

  1. .origin 0 // start of program in PRU memory
  2. .entrypoint START // program entry point for the debugger
  3. // Copyright Doug Lewis Sept 2017
  4. //#include </usr/include/prussdrv.h>
  5. //#include </usr/include/pruss_intc_mapping.h>
  6. #include <./pruadc.h>
  7. START:
  8. // Clear all outputs to the ADS 1278
  9. CLR r30.t0
  10. CLR r30.t1
  11. CLR r30.t2
  12. CLR r30.t3
  13. CLR r30.t4
  14. CLR r30.t5
  15. CLR r30.t6
  16. CLR r30.t7
  17. CLR r30.t8
  18. // Clear all registers we are going to use, since we know that they can come up
  19. // with garbage in them
  20. MOV r0, 0
  21. MOV r1, 0
  22. MOV CLOCK_COUNT, 0 // R2
  23. MOV RUN_STATE, 0 // R3
  24. MOV ADC_CNTRL_STR, 0 // R4
  25. MOV ADC_CHNG_FLG, 0 // R5
  26. MOV SMPL_BIT_CNTR, 0 // R6
  27. MOV CHAN_BITMASK, 0 // R7
  28. MOV SHR_MEM_PTR, 0 // R8
  29. MOV SHR_MEM_SZ, 0 // R9
  30. MOV COUNT, 0 // R10
  31. MOV HEAD, 0 // R11
  32. MOV TAIL, 0 // R12
  33. MOV PRU_DATA_STRT, 0 // R13
  34. MOV CURRENT_SAMPLE, 0 // R14
  35. MOV CURRENT_BUF, 0 // R15
  36. MOV CUR_BUF_ADRS, 0 // R16
  37. MOV CUR_BUF_LEFT, 0 // R17
  38. MOV SHR_MEM_START, 0 // R18
  39. MOV NUM_BLOCKS, 0 // R19
  40. MOV BUFF_COUNT, 0 // R20
  41. MOV SAMPLE1 , 0 // R21
  42. MOV SAMPLE2 , 0 // R22
  43. MOV SAMPLE3 , 0 // R23
  44. MOV SAMPLE4 , 0 // R24
  45. MOV SAMPLE5 , 0 // R25
  46. MOV SAMPLE6 , 0 // R26
  47. MOV SAMPLE7 , 0 // R27
  48. MOV SAMPLE8 , 0 // R28
  49. MOV R29, 0
  50. MOV R30, 0
  51. MOV R31, 0
  52. // Enable the OCP master port -- allows transfer of data to Linux userspace
  53. LBCO r0, C4, 4, 4 // load PRU-ICSS CFG reg into r0
  54. CLR r0, r0, 4 // clear bit 4 (STANDBY_INIT)
  55. SBCO r0, C4, 4, 4 // store the modified r0 back at the load addr
  56. START_LOOP: // This is an easy place to halt the debugger
  57. MOV r1,ADC_STATE_ADDR
  58. LBBO RUN_STATE, r1, 0, 4 // the daq state is now loaded into r3.
  59. QBEQ START_LOOP, RUN_STATE, 0 // We hang out in a loop until told to read the adc
  60. MOV r1,ADC_ADDR
  61. LBBO SHR_MEM_START, r1, 0, 4 // load the Linux address that is passed into r8 -- to store sample values
  62. //Skip the offset bytes that we use for adc_conf at the beginning of the shared memory region
  63. MOV r1, PRU1_START_OFFSET
  64. ADD PRU_DATA_STRT, SHR_MEM_START, R1
  65. MOV SHR_MEM_PTR, PRU_DATA_STRT
  66. MOV r1,ADC_SIZE
  67. LBBO SHR_MEM_SZ, r1, 0, 4 // load the size that is passed into r9 -- the number of samples to take
  68. MOV r1,PRU1_NUM_BLOCKS
  69. LBBO NUM_BLOCKS, r1, 0, 4 // load the count of how many 128K blocks we are going to record
  70. MEM_BUF_ALLOCATED:
  71. MOV CUR_BUF_LEFT, BUFSIZE
  72. MOV r1,ADC_CNTRL_CHANGE // load the base address into r1
  73. LBBO ADC_CHNG_FLG, r1, 0, 4 // the ADC_CNTL_CHANGE is now loaded into R5
  74. QBBS CONFIG_CHANGE, ADC_CHNG_FLG.t0 // If bit 1 of ADC_CTRL_CHANGE is set, there is a config
  75. //change
  76. QBA CONFIG_DONE // Else no changes, goto CONFIG_DONE
  77. CONFIG_CHANGE:
  78. MOV r1, CLOCK_CNTR_ADDR
  79. LBBO CLOCK_COUNT, r1, 0, 4 // the clock delay is now loaded into r2.
  80. MOV r1,ADC_CNTRL_STR_ADDR
  81. LBBO ADC_CNTRL_STR, r1, 0, 4 // the ADC_CNTL_STR is now loaded into R4
  82. CLR ADC_CHNG_FLG.t1 // Clear the change flag so we dont do the config every loop
  83. QBBS SET_PWDN1, ADC_CNTRL_STR.t0
  84. QBA PWDN2
  85. SET_PWDN1:
  86. SET r30.t6 // Pin 39, CH B 1-4
  87. PWDN2:
  88. QBBS SET_PWDN2, ADC_CNTRL_STR.t1
  89. QBA PWDN3
  90. SET_PWDN2:
  91. SET r30.t7 // Pin 40, CH C 1-4
  92. PWDN3:
  93. QBBS SET_PWDN3, ADC_CNTRL_STR.t2
  94. QBA PWDN4
  95. SET_PWDN3:
  96. SET r30.t4 // Pin 41, CH B 5-8
  97. PWDN4:
  98. QBBS SET_PWDN4, ADC_CNTRL_STR.t3
  99. QBA PWDN5
  100. SET_PWDN4:
  101. SET r30.t5 // Pin 42, CH D 1-4
  102. PWDN5:
  103. QBBS SET_PWDN5, ADC_CNTRL_STR.t4
  104. QBA PWDN6
  105. SET_PWDN5:
  106. SET r30.t2 // Pin 43, CH A 5-8
  107. PWDN6:
  108. QBBS SET_PWDN6, ADC_CNTRL_STR.t5
  109. QBA PWDN7
  110. SET_PWDN6:
  111. SET r30.t3 // Pin 44, CHD 5-8
  112. PWDN7:
  113. QBBS SET_PWDN7, ADC_CNTRL_STR.t6
  114. QBA PWDN8
  115. SET_PWDN7:
  116. SET r30.t0 // Pin 45 CH A 1-4
  117. PWDN8:
  118. QBBS SET_PWDN8, ADC_CNTRL_STR.t7
  119. QBA CONFIG_DONE
  120. SET_PWDN8:
  121. SET r30.t1 // Pin 46, CH C 5-8
  122. CONFIG_DONE:
  123. QBEQ THROUGH_TEST, RUN_STATE, TEST // If RUN_STATE = 1, start data collection, If 2, test mode.
  124. // Set the SYNC Pin High
  125. SET SPI_SYNC_PIN
  126. MOV r1, DELAY_PULSES // We are going to delay here for a little bit in order for the 5V and 10V
  127. // rail voltages to ramp after enabling the daqs.
  128. DELAY_START:
  129. // Generate one clock pulse for test purposes
  130. MOV r0, CLOCK_COUNT // Reload the clock delay val into R0
  131. SET SPI_CLK_B_D_PIN // set the clock line to be high
  132. DELAY_CLOCK_TEST_PULSE:
  133. SUB r0, r0, 1
  134. QBNE DELAY_CLOCK_TEST_PULSE, r0, 0
  135. CLR SPI_CLK_B_D_PIN
  136. SUB r1, r1, 1
  137. QBNE DELAY_START, r1, 0
  138. // sync is active low, so we clear it
  139. MOV r0, CLOCK_COUNT // Reload the clock delay val into R0
  140. CLR SPI_SYNC_PIN // CLR the sync pin. Once it goes low, the ADC will start to
  141. // convert data, and the DSR should go high after this.
  142. DELAY_SYNC_PULSE:
  143. SUB r0, r0, 1
  144. QBNE DELAY_SYNC_PULSE, r0, 0
  145. SET SPI_SYNC_PIN
  146. NEXT_BUFFER:
  147. MOV CUR_BUF_LEFT, BUFSIZE
  148. // Move a well known cow into first four bytes of the buffer header.
  149. MOV R1, 0xDEADBEEF
  150. SBBO R1, SHR_MEM_PTR, 0, 4
  151. // Copy the buffer count into the second 4 bytes of the header
  152. SBBO BUFF_COUNT, SHR_MEM_PTR, 4, 4 // store the sample value into shared memory space
  153. //Skip 32 bytes that we will use for the 128k buffer header.
  154. ADD SHR_MEM_PTR, SHR_MEM_PTR, BUF_HDR_SIZE
  155. SUB CUR_BUF_LEFT, CUR_BUF_LEFT, BUF_HDR_SIZE
  156. //We want to look at the first bit in the config bitmask.
  157. READ_NEXT_SAMPLE:
  158. MOV r1,ADC_STATE_ADDR //Check to see if we are still need to be running
  159. LBBO RUN_STATE, r1, 0, 4
  160. QBEQ CONTINUE_DAQ, RUN_STATE, 1
  161. QBA END // We've been told to stop.
  162. CONTINUE_DAQ:
  163. MOV SAMPLE1, 0
  164. MOV SAMPLE2, 0
  165. MOV SAMPLE3, 0
  166. MOV SAMPLE4, 0
  167. MOV SAMPLE5, 0
  168. MOV SAMPLE6, 0
  169. MOV SAMPLE7, 0
  170. MOV SAMPLE8, 0
  171. // We look for DSR to be high
  172. DATA_READY_HIGH:
  173. QBBS DATA_READY_WAIT, SPI_DSR_B_D_PIN
  174. QBA DATA_READY_HIGH
  175. DATA_READY_WAIT:
  176. QBBC DATA_READY, SPI_DSR_B_D_PIN // If Data Ready line clear, read a sample
  177. QBA DATA_READY_WAIT // Else hang out in a tight loop ...
  178. MOV r0, 0
  179. MOV r0, 0
  180. DATA_READY:
  181. MOV SMPL_BIT_CNTR, SAMPLE_SIZE // We're going to read 24 bits
  182. READ_CHANNEL1:
  183. MOV r0, CLOCK_COUNT // Reload the clock delay val into R0
  184. SET SPI_CLK_B_D_PIN // set the clock line to be high
  185. DELAYON1:
  186. SUB r0, r0, 1
  187. QBNE DELAYON1, r0, 0
  188. CLR SPI_CLK_B_D_PIN // set the clock to be low
  189. // Read Data In
  190. QBBC ZERO_BIT1, SPI_DATA_IN_B_D_PIN // Check to see whether Data In is a 0 or 1
  191. OR SAMPLE1, SAMPLE1, 0x00000001
  192. MOV r0, CLOCK_COUNT
  193. DELAYOFF1:
  194. SUB r0, r0, 1
  195. QBNE DELAYOFF1, r0, 0 // loop until the delay has expired (equals 0)
  196. ZERO_BIT1:
  197. LSL SAMPLE1, SAMPLE1, 1 // Shift current sample contents left by one
  198. SUB SMPL_BIT_CNTR, SMPL_BIT_CNTR, 1 // See if we have read all 24 bits of the sample
  199. QBNE READ_CHANNEL1, SMPL_BIT_CNTR, 0
  200. //////////////////////////
  201. MOV SMPL_BIT_CNTR, SAMPLE_SIZE // We're going to read 24 bits
  202. READ_CHANNEL2:
  203. MOV r0, CLOCK_COUNT // Reload the clock delay val into R0
  204. SET SPI_CLK_B_D_PIN // set the clock to be high
  205. DELAYON2:
  206. SUB r0, r0, 1
  207. QBNE DELAYON2, r0, 0
  208. // Reload the clock delay val into R0
  209. CLR SPI_CLK_B_D_PIN // set the clock to be low
  210. // Read Data In
  211. QBBC ZERO_BIT2, SPI_DATA_IN_B_D_PIN // Check to see whether Data In is a 0 or 1
  212. OR SAMPLE2, SAMPLE2, 0x00000001
  213. MOV r0, CLOCK_COUNT
  214. DELAYOFF2:
  215. SUB r0, r0, 1
  216. QBNE DELAYOFF2, r0, 0 // loop until the delay has expired (equals 0)
  217. ZERO_BIT2:
  218. LSL SAMPLE2, SAMPLE2, 1 // Shift current sample contents left by one
  219. SUB SMPL_BIT_CNTR, SMPL_BIT_CNTR, 1 // See if we have read all 24 bits of the sample
  220. QBNE READ_CHANNEL2, SMPL_BIT_CNTR, 0
  221. //////////////////////
  222. MOV SMPL_BIT_CNTR, SAMPLE_SIZE // We're going to read 24 bits
  223. READ_CHANNEL3:
  224. MOV r0, CLOCK_COUNT // Reload the clock delay val into R0
  225. SET SPI_CLK_B_D_PIN // set the clock to be high
  226. DELAYON3:
  227. SUB r0, r0, 1
  228. QBNE DELAYON3, r0, 0
  229. // Reload the clock delay val into R0
  230. CLR SPI_CLK_B_D_PIN // set the clock to be low
  231. // Read Data In
  232. QBBC ZERO_BIT3, SPI_DATA_IN_B_D_PIN // Check to see whether Data In is a 0 or 1
  233. OR SAMPLE3, SAMPLE3, 0x00000001
  234. MOV r0, CLOCK_COUNT
  235. DELAYOFF3:
  236. SUB r0, r0, 1
  237. QBNE DELAYOFF3, r0, 0 // loop until the delay has expired (equals 0)
  238. ZERO_BIT3:
  239. LSL SAMPLE3, SAMPLE3, 1 // Shift current sample contents left by one
  240. SUB SMPL_BIT_CNTR, SMPL_BIT_CNTR, 1 // See if we have read all 24 bits of the sample
  241. QBNE READ_CHANNEL3, SMPL_BIT_CNTR, 0
  242. /////////////////////////
  243. MOV SMPL_BIT_CNTR, SAMPLE_SIZE // We're going to read 24 bits
  244. READ_CHANNEL4:
  245. MOV r0, CLOCK_COUNT // Reload the clock delay val into R0
  246. SET SPI_CLK_B_D_PIN // set the clock to be high
  247. DELAYON4:
  248. SUB r0, r0, 1
  249. QBNE DELAYON4, r0, 0
  250. // Reload the clock delay val into R0
  251. CLR SPI_CLK_B_D_PIN // set the clock to be low
  252. // Read Data In
  253. QBBC ZERO_BIT4, SPI_DATA_IN_B_D_PIN // Check to see whether Data In is a 0 or 1
  254. OR SAMPLE4, SAMPLE4, 0x00000001
  255. MOV r0, CLOCK_COUNT
  256. DELAYOFF4:
  257. SUB r0, r0, 1
  258. QBNE DELAYOFF4, r0, 0 // loop until the delay has expired (equals 0)
  259. ZERO_BIT4:
  260. LSL SAMPLE4, SAMPLE4, 1 // Shift current sample contents left by one
  261. SUB SMPL_BIT_CNTR, SMPL_BIT_CNTR, 1 // See if we have read all 24 bits of the sample
  262. QBNE READ_CHANNEL4, SMPL_BIT_CNTR, 0
  263. /////////////////////////
  264. MOV SMPL_BIT_CNTR, SAMPLE_SIZE // We're going to read 24 bits
  265. READ_CHANNEL5:
  266. MOV r0, CLOCK_COUNT // Reload the clock delay val into R0
  267. SET SPI_CLK_B_D_PIN // set the clock to be high
  268. DELAYON5:
  269. SUB r0, r0, 1
  270. QBNE DELAYON5, r0, 0
  271. // Reload the clock delay val into R0
  272. CLR SPI_CLK_B_D_PIN // set the clock to be low
  273. // Read Data In
  274. QBBC ZERO_BIT5, SPI_DATA_IN_B_D_PIN // Check to see whether Data In is a 0 or 1
  275. OR SAMPLE5, SAMPLE5, 0x00000001
  276. MOV r0, CLOCK_COUNT
  277. DELAYOFF5:
  278. SUB r0, r0, 1
  279. QBNE DELAYOFF5, r0, 0 // loop until the delay has expired (equals 0)
  280. ZERO_BIT5:
  281. LSL SAMPLE5, SAMPLE5, 1 // Shift current sample contents left by one
  282. SUB SMPL_BIT_CNTR, SMPL_BIT_CNTR, 1 // See if we have read all 24 bits of the sample
  283. QBNE READ_CHANNEL5, SMPL_BIT_CNTR, 0
  284. /////////////////////////
  285. MOV SMPL_BIT_CNTR, SAMPLE_SIZE // We're going to read 24 bits
  286. READ_CHANNEL6:
  287. MOV r0, CLOCK_COUNT // Reload the clock delay val into R0
  288. SET SPI_CLK_B_D_PIN // set the clock to be high
  289. DELAYON6:
  290. SUB r0, r0, 1
  291. QBNE DELAYON6, r0, 0
  292. // Reload the clock delay val into R0
  293. CLR SPI_CLK_B_D_PIN // set the clock to be low
  294. // Read Data In
  295. QBBC ZERO_BIT6, SPI_DATA_IN_B_D_PIN // Check to see whether Data In is a 0 or 1
  296. OR SAMPLE6, SAMPLE6, 0x00000001
  297. MOV r0, CLOCK_COUNT
  298. DELAYOFF6:
  299. SUB r0, r0, 1
  300. QBNE DELAYOFF6, r0, 0 // loop until the delay has expired (equals 0)
  301. ZERO_BIT6:
  302. LSL SAMPLE6, SAMPLE6, 1 // Shift current sample contents left by one
  303. SUB SMPL_BIT_CNTR, SMPL_BIT_CNTR, 1 // See if we have read all 24 bits of the sample
  304. QBNE READ_CHANNEL6, SMPL_BIT_CNTR, 0
  305. /////////////////////////
  306. MOV SMPL_BIT_CNTR, SAMPLE_SIZE // We're going to read 24 bits
  307. READ_CHANNEL7:
  308. MOV r0, CLOCK_COUNT // Reload the clock delay val into R0
  309. SET SPI_CLK_B_D_PIN // set the clock to be high
  310. DELAYON7:
  311. SUB r0, r0, 1
  312. QBNE DELAYON7, r0, 0
  313. // Reload the clock delay val into R0
  314. CLR SPI_CLK_B_D_PIN // set the clock to be low
  315. // Read Data In
  316. QBBC ZERO_BIT7, SPI_DATA_IN_B_D_PIN // Check to see whether Data In is a 0 or 1
  317. OR SAMPLE7, SAMPLE7, 0x00000001
  318. MOV r0, CLOCK_COUNT
  319. DELAYOFF7:
  320. SUB r0, r0, 1
  321. QBNE DELAYOFF7, r0, 0 // loop until the delay has expired (equals 0)
  322. ZERO_BIT7:
  323. LSL SAMPLE7, SAMPLE7, 1 // Shift current sample contents left by one
  324. SUB SMPL_BIT_CNTR, SMPL_BIT_CNTR, 1 // See if we have read all 24 bits of the sample
  325. QBNE READ_CHANNEL7, SMPL_BIT_CNTR, 0
  326. /////////////////////////
  327. MOV SMPL_BIT_CNTR, SAMPLE_SIZE // We're going to read 24 bits
  328. READ_CHANNEL8:
  329. MOV r0, CLOCK_COUNT // Reload the clock delay val into R0
  330. SET SPI_CLK_B_D_PIN // set the clock to be high
  331. DELAYON8:
  332. SUB r0, r0, 1
  333. QBNE DELAYON8, r0, 0
  334. // Reload the clock delay val into R0
  335. CLR SPI_CLK_B_D_PIN // set the clock to be low
  336. // Read Data In
  337. QBBC ZERO_BIT8, SPI_DATA_IN_B_D_PIN //to see whether Data In is a 0 or 1
  338. OR SAMPLE8, SAMPLE8, 0x00000001
  339. MOV r0, CLOCK_COUNT
  340. DELAYOFF8:
  341. SUB r0, r0, 1
  342. QBNE DELAYOFF8, r0, 0 // loop until the delay has expired (equals 0)
  343. ZERO_BIT8:
  344. LSL SAMPLE8, SAMPLE8, 1 // Shift current sample contents left by one
  345. SUB SMPL_BIT_CNTR, SMPL_BIT_CNTR, 1 // See if we have read all 24 bits of the sample
  346. QBNE READ_CHANNEL8, SMPL_BIT_CNTR, 0
  347. /////////////////////////
  348. STORE_SAMPLE:
  349. LSR SAMPLE1, SAMPLE1, 1 // Need to shift the sample word back to the right by one
  350. LSR SAMPLE2, SAMPLE2, 1
  351. LSR SAMPLE3, SAMPLE3, 1
  352. LSR SAMPLE4, SAMPLE4, 1
  353. LSR SAMPLE5, SAMPLE5, 1
  354. LSR SAMPLE6, SAMPLE6, 1
  355. LSR SAMPLE7, SAMPLE7, 1
  356. LSR SAMPLE8, SAMPLE8, 1
  357. MOV SAMPLE1.b3, 0x01 // Stash the channel bitmask in the upper byte used to store the sample
  358. MOV SAMPLE2.b3, 0x02
  359. MOV SAMPLE3.b3, 0x04
  360. MOV SAMPLE4.b3, 0x08
  361. MOV SAMPLE5.b3, 0x10
  362. MOV SAMPLE6.b3, 0x20
  363. MOV SAMPLE7.b3, 0x40
  364. MOV SAMPLE8.b3, 0x80
  365. SBBO SAMPLE1, SHR_MEM_PTR, 0, 4 // store the sample value into shared memory space
  366. ADD SHR_MEM_PTR, SHR_MEM_PTR, 4 // Add 4 bytes per sample to the address pointer
  367. SBBO SAMPLE2, SHR_MEM_PTR, 0, 4 // store the sample value into shared memory space
  368. ADD SHR_MEM_PTR, SHR_MEM_PTR, 4 // Add 4 bytes per sample to the address pointer
  369. SBBO SAMPLE3, SHR_MEM_PTR, 0, 4 // store the sample value into shared memory space
  370. ADD SHR_MEM_PTR, SHR_MEM_PTR, 4 // Add 4 bytes per sample to the address pointer
  371. SBBO SAMPLE4, SHR_MEM_PTR, 0, 4 // store the sample value into shared memory space
  372. ADD SHR_MEM_PTR, SHR_MEM_PTR, 4 // Add 4 bytes per sample to the address pointer
  373. SBBO SAMPLE5, SHR_MEM_PTR, 0, 4 // store the sample value into shared memory space
  374. ADD SHR_MEM_PTR, SHR_MEM_PTR, 4 // Add 4 bytes per sample to the address pointer
  375. SBBO SAMPLE6, SHR_MEM_PTR, 0, 4 // store the sample value into shared memory space
  376. ADD SHR_MEM_PTR, SHR_MEM_PTR, 4 // Add 4 bytes per sample to the address pointer
  377. SBBO SAMPLE7, SHR_MEM_PTR, 0, 4 // store the sample value into shared memory space
  378. ADD SHR_MEM_PTR, SHR_MEM_PTR, 4 // Add 4 bytes per sample to the address pointer
  379. SBBO SAMPLE8, SHR_MEM_PTR, 0, 4 // store the sample value into shared memory space
  380. ADD SHR_MEM_PTR, SHR_MEM_PTR, 4 // Add 4 bytes per sample to the address pointer
  381. SUB CUR_BUF_LEFT, CUR_BUF_LEFT, 32 // reducing the number of samples - 4 bytes per sample, 8 channels
  382. QBEQ BUFFER_DONE, CUR_BUF_LEFT, 0 // See if we have taken 128kb of samples
  383. QBA READ_NEXT_SAMPLE // If we've looped thru all channels in the sample. wait for the next sample
  384. BUFFER_DONE:
  385. MOV CUR_BUF_LEFT, BUFSIZE
  386. // Subtract 32 bytes that are the header
  387. SUB CUR_BUF_LEFT, CUR_BUF_LEFT, 32 // reducing the number of samples - 4 bytes per sample, 8 channels
  388. // Set the amount of the current buffer left to be 128k
  389. ADD BUFF_COUNT, BUFF_COUNT, 1
  390. MOV R1, 1
  391. SBBO R1, SHR_MEM_START, PRU1_WR_FLAG, 4
  392. SBBO BUFF_COUNT, SHR_MEM_START, PRU1_BUFF_COUNT, 4
  393. ADD HEAD, HEAD, 1
  394. SBBO HEAD, SHR_MEM_START, PRU1_HEAD, 4
  395. QBNE NO_WRAP, HEAD, QUEUE_SIZE
  396. MOV HEAD, 0
  397. SBBO HEAD, SHR_MEM_START, PRU1_HEAD, 4
  398. QBA WRAP_TIME
  399. NO_WRAP:
  400. // If we have recorded all of the buffers that we need to, then halt.
  401. SUB NUM_BLOCKS, NUM_BLOCKS, 1
  402. QBEQ END, NUM_BLOCKS, 0
  403. QBA NEXT_BUFFER
  404. WRAP_TIME:
  405. // Always wanted to be a rapper ;-0)
  406. // We have used all the buffers in the shmem queue, wrap to the beginning.
  407. SUB NUM_BLOCKS, NUM_BLOCKS, 1
  408. QBEQ END, NUM_BLOCKS, 0
  409. ADD WRAP_COUNT, WRAP_COUNT, 1
  410. // We've wrapped, so we need to point back to the start of data buffer start
  411. MOV SHR_MEM_PTR, PRU_DATA_STRT
  412. // We want to write WRAP_COUNT to shared memory adc_pru_data0[12] here.
  413. SBBO WRAP_COUNT, SHR_MEM_START, PRU1_WRAP_COUNT, 4
  414. QBA NEXT_BUFFER
  415. //////////////////////////////////////////////////////////////////////////////////////////////////////
  416. //
  417. // Throughput test
  418. //
  419. //////////////////////////////////////////////////////////////////////////////////////////////////////
  420. THROUGH_TEST:
  421. MOV r1,ADC_ADDR
  422. LBBO SHR_MEM_PTR, r1, 0, 4 // load the Linux address that is passed into r8 -- to store sample values
  423. //Skip the offset bytes that we use for adc_conf at the beginning of the shared memory region
  424. MOV r1, PRU1_START_OFFSET
  425. ADD SHR_MEM_PTR, SHR_MEM_PTR, r1
  426. MOV r1,ADC_SIZE
  427. LBBO SHR_MEM_SZ, r1, 0, 4 // load the size that is passed into r9 -- the number of samples to take
  428. NEXT_TEST_BUFFER:
  429. MOV CUR_BUF_LEFT, BUFSIZE
  430. // Move a well done hamburger into the first four bytes of the buffer header.
  431. MOV R1, 0xDEADBEEF
  432. SBBO R1, SHR_MEM_PTR, 0, 4
  433. // Copy the buffer count into the second 4 bytes of the header
  434. SBBO BUFF_COUNT, SHR_MEM_PTR, 4, 4 // store the sample value into shared memory space
  435. //Skip 32 bytes that we will use for the 128k buffer header.
  436. ADD SHR_MEM_PTR, SHR_MEM_PTR, BUF_HDR_SIZE
  437. SUB CUR_BUF_LEFT, CUR_BUF_LEFT, BUF_HDR_SIZE
  438. CREATE_NEXT_TEST_SAMPLE:
  439. // Move a counter value into each of the eight 32 bit sample words.
  440. // We are going to do this brute force (instead of a small) loop to be as fast as possible.
  441. MOV SAMPLE1, COUNT
  442. ADD COUNT, COUNT, 1
  443. MOV SAMPLE2, COUNT
  444. ADD COUNT, COUNT, 1
  445. MOV SAMPLE3, COUNT
  446. ADD COUNT, COUNT, 1
  447. MOV SAMPLE4, COUNT
  448. ADD COUNT, COUNT, 1
  449. MOV SAMPLE5, COUNT
  450. ADD COUNT, COUNT, 1
  451. MOV SAMPLE6, COUNT
  452. ADD COUNT, COUNT, 1
  453. MOV SAMPLE7, COUNT
  454. ADD COUNT, COUNT, 1
  455. MOV SAMPLE8, COUNT
  456. ADD COUNT, COUNT, 1
  457. // We look to see if COUNT > FFFFFF, if so, set to zero.
  458. MOV R1, FULL_COUNT
  459. QBEQ ZERO_COUNT, R1, COUNT
  460. QBA WRITE_CHAN_BYTE
  461. ZERO_COUNT:
  462. MOV COUNT, 0
  463. WRITE_CHAN_BYTE:
  464. MOV SAMPLE1.b3, 0x01 // Stash the channel bitmask in the upper byte used to store the sample
  465. MOV SAMPLE2.b3, 0x02
  466. MOV SAMPLE3.b3, 0x04
  467. MOV SAMPLE4.b3, 0x08
  468. MOV SAMPLE5.b3, 0x10
  469. MOV SAMPLE6.b3, 0x20
  470. MOV SAMPLE7.b3, 0x40
  471. MOV SAMPLE8.b3, 0x80
  472. SBBO SAMPLE1, SHR_MEM_PTR, 0, 4 // store the sample value into shared memory space
  473. ADD SHR_MEM_PTR, SHR_MEM_PTR, 4 // Add 4 bytes per sample to the address pointer
  474. SBBO SAMPLE2, SHR_MEM_PTR, 0, 4 // store the sample value into shared memory space
  475. ADD SHR_MEM_PTR, SHR_MEM_PTR, 4 // Add 4 bytes per sample to the address pointer
  476. SBBO SAMPLE3, SHR_MEM_PTR, 0, 4 // store the sample value into shared memory space
  477. ADD SHR_MEM_PTR, SHR_MEM_PTR, 4 // Add 4 bytes per sample to the address pointer
  478. SBBO SAMPLE4, SHR_MEM_PTR, 0, 4 // store the sample value into shared memory space
  479. ADD SHR_MEM_PTR, SHR_MEM_PTR, 4 // Add 4 bytes per sample to the address pointer
  480. SBBO SAMPLE5, SHR_MEM_PTR, 0, 4 // store the sample value into shared memory space
  481. ADD SHR_MEM_PTR, SHR_MEM_PTR, 4 // Add 4 bytes per sample to the address pointer
  482. SBBO SAMPLE6, SHR_MEM_PTR, 0, 4 // store the sample value into shared memory space
  483. ADD SHR_MEM_PTR, SHR_MEM_PTR, 4 // Add 4 bytes per sample to the address pointer
  484. SBBO SAMPLE7, SHR_MEM_PTR, 0, 4 // store the sample value into shared memory space
  485. ADD SHR_MEM_PTR, SHR_MEM_PTR, 4 // Add 4 bytes per sample to the address pointer
  486. SBBO SAMPLE8, SHR_MEM_PTR, 0, 4 // store the sample value into shared memory space
  487. ADD SHR_MEM_PTR, SHR_MEM_PTR, 4 // Add 4 bytes per sample to the address pointer
  488. SUB CUR_BUF_LEFT, CUR_BUF_LEFT, 32 // reducing the number of samples - 4 bytes per sample, 8 channels
  489. // We have created one sample, wait roughly 1/10547 secs to simulate sample time from DAQ
  490. MOV r0, INSTRUCTIONS_PER_SAMPLE
  491. DELAY:
  492. SUB r0, r0, 1
  493. QBNE DELAY, r0, 0 // loop until the delay has expired (equals 0)
  494. QBEQ TEST_BUFFER_DONE, CUR_BUF_LEFT, 0 // See if we have taken 128kb of samples
  495. QBA CREATE_NEXT_TEST_SAMPLE // If we've looped thru all channels in the sample. wait for the next sample
  496. TEST_BUFFER_DONE:
  497. // Set the amount of the current buffer left to be 128k
  498. MOV CUR_BUF_LEFT, BUFSIZE
  499. // Subtract 32 bytes that are the header
  500. SUB CUR_BUF_LEFT, CUR_BUF_LEFT, 32 // reducing the number of samples - 4 bytes per sample, 8 channels
  501. ADD BUFF_COUNT, BUFF_COUNT, 1
  502. MOV R1, 1
  503. SBBO R1, SHR_MEM_START, PRU1_WR_FLAG, 4
  504. SBBO BUFF_COUNT, SHR_MEM_START, PRU1_BUFF_COUNT, 4
  505. ADD HEAD, HEAD, 1
  506. SBBO HEAD, SHR_MEM_START, PRU1_HEAD, 4
  507. QBNE NO_TEST_WRAP, HEAD, QUEUE_SIZE
  508. MOV HEAD, 0
  509. SBBO HEAD, SHR_MEM_START, PRU1_HEAD, 4
  510. QBA TEST_WRAP_TIME
  511. NO_TEST_WRAP:
  512. // If we have recorded all of the buffers that we need to, then halt.
  513. SUB NUM_BLOCKS, NUM_BLOCKS, 1
  514. QBEQ END, NUM_BLOCKS, 0
  515. QBA NEXT_TEST_BUFFER
  516. TEST_WRAP_TIME:
  517. // Always wanted to be a rapper ;-0)
  518. // We have used all the buffers in the shmem queue, wrap to the beginning.
  519. SUB NUM_BLOCKS, NUM_BLOCKS, 1
  520. QBEQ END, NUM_BLOCKS, 0
  521. ADD WRAP_COUNT, WRAP_COUNT, 1
  522. // We've wrapped, so we need to point back to the start of data buffer start
  523. MOV SHR_MEM_PTR, PRU_DATA_STRT
  524. // We want to write WRAP_COUNT to shared memory adc_pru_data0[12] here.
  525. SBBO WRAP_COUNT, SHR_MEM_START, PRU1_WRAP_COUNT, 4
  526. QBA NEXT_TEST_BUFFER
  527. // halt the pru program -- we reach here when we have read all of the intended buffers.
  528. END:
  529. CLR r30.t6 // Pin 39, CH B 1-4
  530. CLR r30.t7 // Pin 40, CH C 1-4
  531. CLR r30.t4 // Pin 41, CH B 5-8
  532. CLR r30.t5 // Pin 42, CH D 1-4
  533. CLR r30.t2 // Pin 43, CH A 5-8
  534. CLR r30.t3 // Pin 44, CHD 5-8
  535. CLR r30.t0 // Pin 45 CH A 1-4
  536. CLR r30.t1 // Pin 46, CH C 5-8
  537. CLR r30.t8
  538. MOV r31.b0, PRU0_R31_VEC_VALID | PRU_EVTOUT_0
  539. HALT