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.

425 lines
15 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 <./pruadc.h>
  5. START:
  6. // Clear clock outputs to the ADS 1278
  7. CLR SPI_CLK_A_C_PIN
  8. // Clear all registers we are going to use, since we know that they can come up
  9. // with garbage in them
  10. MOV r0, 0
  11. MOV r1, 0
  12. MOV CLOCK_COUNT, 0 // R2
  13. MOV RUN_STATE, 0 // R3
  14. MOV ADC_CNTRL_STR, 0 // R4
  15. MOV ADC_CHNG_FLG, 0 // R5
  16. MOV SMPL_BIT_CNTR, 0 // R6
  17. MOV CHAN_BITMASK, 0 // R7
  18. MOV SHR_MEM_PTR, 0 // R8
  19. MOV SHR_MEM_SZ, 0 // R9
  20. MOV COUNT, 0 // R10
  21. MOV HEAD, 0 // R11
  22. MOV TAIL, 0 // R12
  23. MOV PRU_DATA_STRT, 0 // R13
  24. MOV CURRENT_SAMPLE, 0 // R14
  25. MOV CURRENT_BUF, 0 // R15
  26. MOV CUR_BUF_ADRS, 0 // R16
  27. MOV CUR_BUF_LEFT, 0 // R17
  28. MOV SHR_MEM_START, 0 // R18
  29. MOV NUM_BLOCKS, 0 // R19
  30. MOV BUFF_COUNT, 0 // R20
  31. MOV SAMPLE1 , 0 // R21
  32. MOV SAMPLE2 , 0 // R22
  33. MOV SAMPLE3 , 0 // R23
  34. MOV SAMPLE4 , 0 // R24
  35. MOV SAMPLE5 , 0 // R25
  36. MOV SAMPLE6 , 0 // R26
  37. MOV SAMPLE7 , 0 // R27
  38. MOV SAMPLE8 , 0 // R28
  39. MOV WRAP_COUNT, 0 // R29
  40. // Enable the OCP master port -- allows transfer of data to Linux userspace
  41. LBCO r0, C4, 4, 4 // load PRU-ICSS CFG reg into r0
  42. CLR r0, r0, 4 // clear bit 4 (STANDBY_INIT)
  43. SBCO r0, C4, 4, 4 // store the modified r0 back at the load addr
  44. START_LOOP: // This is an easy place to halt the debugger
  45. MOV r1,ADC_STATE_ADDR
  46. LBBO RUN_STATE, r1, 0, 4 // the daq state is now loaded into r3.
  47. QBEQ START_LOOP, RUN_STATE, 0 // We hang out in a loop until told to read the adc
  48. MOV r1,ADC_ADDR //
  49. LBBO SHR_MEM_PTR, r1, 0, 4 // load the Linux address that is passed into r8 -- to store sample values
  50. MOV R1, PRU0_START_OFFSET
  51. ADD PRU_DATA_STRT, SHR_MEM_START, R1
  52. MOV SHR_MEM_PTR, PRU_DATA_STRT
  53. MOV r1,ADC_SIZE //
  54. LBBO SHR_MEM_SZ, r1, 0, 4 // load the size that is passed into r9 -- the number of samples to take
  55. MOV r1,PRU0_NUM_BLOCKS //
  56. LBBO NUM_BLOCKS, r1, 0, 4 // load the count of how many 128K blocks we are going to record
  57. MEM_BUF_ALLOCATED:
  58. MOV CUR_BUF_LEFT, BUFSIZE
  59. MOV r1,ADC_CNTRL_CHANGE // load the base address into r1
  60. LBBO ADC_CHNG_FLG, r1, 0, 4 // the ADC_CNTL_CHANGE is now loaded into R5
  61. QBBS CONFIG_CHANGE, ADC_CHNG_FLG.t0 // If bit 1 of ADC_CTRL_CHANGE is set, there is a config
  62. //change
  63. QBA CONFIG_DONE // Else no changes, goto CONFIG_DONE
  64. CONFIG_CHANGE:
  65. MOV r1, CLOCK_CNTR_ADDR
  66. LBBO CLOCK_COUNT, r1, 0, 4 // the clock delay is now loaded into r2.
  67. MOV r1,ADC_CNTRL_STR_ADDR
  68. LBBO ADC_CNTRL_STR, r1, 0, 4 // the ADC_CNTL_STR is now loaded into R4
  69. CLR ADC_CHNG_FLG.t1 // Clear the change flag so we dont do the config every loop
  70. CONFIG_DONE:
  71. //We want to look at the first bit in the config bitmask.
  72. READ_NEXT_SAMPLE:
  73. MOV r1,ADC_STATE_ADDR //Check to see if we are still need to be running
  74. LBBO RUN_STATE, r1, 0, 4
  75. QBEQ CONTINUE_DAQ, RUN_STATE, 1
  76. HALT // We've been told to stop.
  77. CONTINUE_DAQ:
  78. MOV SAMPLE1, 0
  79. MOV SAMPLE2, 0
  80. MOV SAMPLE3, 0
  81. MOV SAMPLE4, 0
  82. MOV SAMPLE5, 0
  83. MOV SAMPLE6, 0
  84. MOV SAMPLE7, 0
  85. MOV SAMPLE8, 0
  86. // We check data ready to make sure the ADC has had a chance to initialize and set dready high before sampling.
  87. DATA_READY_HIGH:
  88. QBBS DATA_READY_WAIT, SPI_DSR_A_C_PIN
  89. QBA DATA_READY_HIGH
  90. DATA_READY_WAIT:
  91. QBBC DATA_READY, SPI_DSR_A_C_PIN // If Data Ready line clear, read a sample
  92. QBA DATA_READY_WAIT // Else hang out in a tight loop ...
  93. DATA_READY:
  94. MOV SMPL_BIT_CNTR, SAMPLE_SIZE // We're going to read 24 bits
  95. READ_CHANNEL1:
  96. MOV r0, CLOCK_COUNT // Reload the clock delay val into R0
  97. SET SPI_CLK_A_C_PIN // set the clock line to be high
  98. DELAYON1:
  99. SUB r0, r0, 1
  100. QBNE DELAYON1, r0, 0
  101. CLR SPI_CLK_A_C_PIN // set the clock to be low
  102. // Read Data In
  103. QBBC ZERO_BIT1, SPI_DATA_IN_A_C_PIN // Check to see whether Data In is a 0 or 1
  104. OR SAMPLE1, SAMPLE1, 0x00000001
  105. ZERO_BIT1:
  106. LSL SAMPLE1, SAMPLE1, 1 // Shift current sample contents left by one
  107. MOV r0, CLOCK_COUNT
  108. DELAYOFF1:
  109. SUB r0, r0, 1
  110. QBNE DELAYOFF1, r0, 0 // loop until the delay has expired (equals 0)
  111. SUB SMPL_BIT_CNTR, SMPL_BIT_CNTR, 1 // See if we have read all 24 bits of the sample
  112. QBNE READ_CHANNEL1, SMPL_BIT_CNTR, 0
  113. //////////////////////////
  114. MOV SMPL_BIT_CNTR, SAMPLE_SIZE // We're going to read 24 bits
  115. READ_CHANNEL2:
  116. MOV r0, CLOCK_COUNT // Reload the clock delay val into R0
  117. SET SPI_CLK_A_C_PIN // set the clock to be high
  118. DELAYON2:
  119. SUB r0, r0, 1
  120. QBNE DELAYON2, r0, 0
  121. // Reload the clock delay val into R0
  122. CLR SPI_CLK_A_C_PIN // set the clock to be low
  123. // Read Data In
  124. QBBC ZERO_BIT2, SPI_DATA_IN_A_C_PIN // Check to see whether Data In is a 0 or 1
  125. OR SAMPLE2, SAMPLE2, 0x00000001
  126. ZERO_BIT2:
  127. LSL SAMPLE2, SAMPLE2, 1 // Shift current sample contents left by one
  128. SUB SMPL_BIT_CNTR, SMPL_BIT_CNTR, 1 // See if we have read all 24 bits of the sample
  129. MOV r0, CLOCK_COUNT
  130. DELAYOFF2:
  131. SUB r0, r0, 1
  132. QBNE DELAYOFF2, r0, 0 // loop until the delay has expired (equals 0)
  133. QBNE READ_CHANNEL2, SMPL_BIT_CNTR, 0
  134. //////////////////////
  135. MOV SMPL_BIT_CNTR, SAMPLE_SIZE // We're going to read 24 bits
  136. READ_CHANNEL3:
  137. MOV r0, CLOCK_COUNT // Reload the clock delay val into R0
  138. SET SPI_CLK_A_C_PIN // set the clock to be high
  139. DELAYON3:
  140. SUB r0, r0, 1
  141. QBNE DELAYON3, r0, 0
  142. // Reload the clock delay val into R0
  143. CLR SPI_CLK_A_C_PIN // set the clock to be low
  144. // Read Data In
  145. QBBC ZERO_BIT3, SPI_DATA_IN_A_C_PIN // Check to see whether Data In is a 0 or 1
  146. OR SAMPLE3, SAMPLE3, 0x00000001
  147. ZERO_BIT3:
  148. LSL SAMPLE3, SAMPLE3, 1 // Shift current sample contents left by one
  149. SUB SMPL_BIT_CNTR, SMPL_BIT_CNTR, 1 // See if we have read all 24 bits of the sample
  150. MOV r0, CLOCK_COUNT
  151. DELAYOFF3:
  152. SUB r0, r0, 1
  153. QBNE DELAYOFF3, r0, 0 // loop until the delay has expired (equals 0)
  154. QBNE READ_CHANNEL3, SMPL_BIT_CNTR, 0
  155. /////////////////////////
  156. MOV SMPL_BIT_CNTR, SAMPLE_SIZE // We're going to read 24 bits
  157. READ_CHANNEL4:
  158. MOV r0, CLOCK_COUNT // Reload the clock delay val into R0
  159. SET SPI_CLK_A_C_PIN // set the clock to be high
  160. DELAYON4:
  161. SUB r0, r0, 1
  162. QBNE DELAYON4, r0, 0
  163. // Reload the clock delay val into R0
  164. CLR SPI_CLK_A_C_PIN // set the clock to be low
  165. // Read Data In
  166. QBBC ZERO_BIT4, SPI_DATA_IN_A_C_PIN // Check to see whether Data In is a 0 or 1
  167. OR SAMPLE4, SAMPLE4, 0x00000001
  168. ZERO_BIT4:
  169. LSL SAMPLE4, SAMPLE4, 1 // Shift current sample contents left by one
  170. SUB SMPL_BIT_CNTR, SMPL_BIT_CNTR, 1 // See if we have read all 24 bits of the sample
  171. MOV r0, CLOCK_COUNT
  172. DELAYOFF4:
  173. SUB r0, r0, 1
  174. QBNE DELAYOFF4, r0, 0 // loop until the delay has expired (equals 0)
  175. QBNE READ_CHANNEL4, SMPL_BIT_CNTR, 0
  176. /////////////////////////
  177. MOV SMPL_BIT_CNTR, SAMPLE_SIZE // We're going to read 24 bits
  178. READ_CHANNEL5:
  179. MOV r0, CLOCK_COUNT // Reload the clock delay val into R0
  180. SET SPI_CLK_A_C_PIN // set the clock to be high
  181. DELAYON5:
  182. SUB r0, r0, 1
  183. QBNE DELAYON5, r0, 0
  184. // Reload the clock delay val into R0
  185. CLR SPI_CLK_A_C_PIN // set the clock to be low
  186. // Read Data In
  187. QBBC ZERO_BIT5, SPI_DATA_IN_A_C_PIN // Check to see whether Data In is a 0 or 1
  188. OR SAMPLE5, SAMPLE5, 0x00000001
  189. ZERO_BIT5:
  190. LSL SAMPLE5, SAMPLE5, 1 // Shift current sample contents left by one
  191. SUB SMPL_BIT_CNTR, SMPL_BIT_CNTR, 1 // See if we have read all 24 bits of the sample
  192. MOV r0, CLOCK_COUNT
  193. DELAYOFF5:
  194. SUB r0, r0, 1
  195. QBNE DELAYOFF5, r0, 0 // loop until the delay has expired (equals 0)
  196. QBNE READ_CHANNEL5, SMPL_BIT_CNTR, 0
  197. /////////////////////////
  198. MOV SMPL_BIT_CNTR, SAMPLE_SIZE // We're going to read 24 bits
  199. READ_CHANNEL6:
  200. MOV r0, CLOCK_COUNT // Reload the clock delay val into R0
  201. SET SPI_CLK_A_C_PIN // set the clock to be high
  202. DELAYON6:
  203. SUB r0, r0, 1
  204. QBNE DELAYON6, r0, 0
  205. // Reload the clock delay val into R0
  206. CLR SPI_CLK_A_C_PIN // set the clock to be low
  207. // Read Data In
  208. QBBC ZERO_BIT6, SPI_DATA_IN_A_C_PIN // Check to see whether Data In is a 0 or 1
  209. OR SAMPLE6, SAMPLE6, 0x00000001
  210. ZERO_BIT6:
  211. LSL SAMPLE6, SAMPLE6, 1 // Shift current sample contents left by one
  212. SUB SMPL_BIT_CNTR, SMPL_BIT_CNTR, 1 // See if we have read all 24 bits of the sample
  213. MOV r0, CLOCK_COUNT
  214. DELAYOFF6:
  215. SUB r0, r0, 1
  216. QBNE DELAYOFF6, r0, 0 // loop until the delay has expired (equals 0)
  217. QBNE READ_CHANNEL6, SMPL_BIT_CNTR, 0
  218. /////////////////////////
  219. MOV SMPL_BIT_CNTR, SAMPLE_SIZE // We're going to read 24 bits
  220. READ_CHANNEL7:
  221. MOV r0, CLOCK_COUNT // Reload the clock delay val into R0
  222. SET SPI_CLK_A_C_PIN // set the clock to be high
  223. DELAYON7:
  224. SUB r0, r0, 1
  225. QBNE DELAYON7, r0, 0
  226. // Reload the clock delay val into R0
  227. CLR SPI_CLK_A_C_PIN // set the clock to be low
  228. // Read Data In
  229. QBBC ZERO_BIT7, SPI_DATA_IN_A_C_PIN // Check to see whether Data In is a 0 or 1
  230. OR SAMPLE7, SAMPLE7, 0x00000001
  231. ZERO_BIT7:
  232. LSL SAMPLE7, SAMPLE7, 1 // Shift current sample contents left by one
  233. SUB SMPL_BIT_CNTR, SMPL_BIT_CNTR, 1 // See if we have read all 24 bits of the sample
  234. MOV r0, CLOCK_COUNT
  235. DELAYOFF7:
  236. SUB r0, r0, 1
  237. QBNE DELAYOFF7, r0, 0 // loop until the delay has expired (equals 0)
  238. QBNE READ_CHANNEL7, SMPL_BIT_CNTR, 0
  239. /////////////////////////
  240. MOV SMPL_BIT_CNTR, SAMPLE_SIZE // We're going to read 24 bits
  241. READ_CHANNEL8:
  242. MOV r0, CLOCK_COUNT // Reload the clock delay val into R0
  243. SET SPI_CLK_A_C_PIN // set the clock to be high
  244. DELAYON8:
  245. SUB r0, r0, 1
  246. QBNE DELAYON8, r0, 0
  247. // Reload the clock delay val into R0
  248. CLR SPI_CLK_A_C_PIN // set the clock to be low
  249. // Read Data In
  250. QBBC ZERO_BIT8, SPI_DATA_IN_A_C_PIN // Check to see whether Data In is a 0 or 1
  251. OR SAMPLE8, SAMPLE8, 0x00000001
  252. ZERO_BIT8:
  253. LSL SAMPLE8, SAMPLE8, 1 // Shift current sample contents left by one
  254. SUB SMPL_BIT_CNTR, SMPL_BIT_CNTR, 1 // See if we have read all 24 bits of the sample
  255. MOV r0, CLOCK_COUNT
  256. DELAYOFF8:
  257. SUB r0, r0, 1
  258. QBNE DELAYOFF8, r0, 0 // loop until the delay has expired (equals 0)
  259. QBNE READ_CHANNEL8, SMPL_BIT_CNTR, 0
  260. /////////////////////////
  261. STORE_SAMPLE:
  262. LSR SAMPLE1, SAMPLE1, 1 // Need to shift the sample word back to the right by one
  263. LSR SAMPLE2, SAMPLE2, 1
  264. LSR SAMPLE3, SAMPLE3, 1
  265. LSR SAMPLE4, SAMPLE4, 1
  266. LSR SAMPLE5, SAMPLE5, 1
  267. LSR SAMPLE6, SAMPLE6, 1
  268. LSR SAMPLE7, SAMPLE7, 1
  269. LSR SAMPLE8, SAMPLE8, 1
  270. MOV SAMPLE1.b3, 0x01 // Stash the channel bitmask in the upper byte used to store the sample
  271. MOV SAMPLE2.b3, 0x02
  272. MOV SAMPLE3.b3, 0x04
  273. MOV SAMPLE4.b3, 0x08
  274. MOV SAMPLE5.b3, 0x10
  275. MOV SAMPLE6.b3, 0x20
  276. MOV SAMPLE7.b3, 0x40
  277. MOV SAMPLE8.b3, 0x80
  278. SBBO SAMPLE1, SHR_MEM_PTR, 0, 4 // store the sample value into shared memory space
  279. ADD SHR_MEM_PTR, SHR_MEM_PTR, 4 // Add 4 bytes per sample to the address pointer
  280. SBBO SAMPLE2, SHR_MEM_PTR, 0, 4 // store the sample value into shared memory space
  281. ADD SHR_MEM_PTR, SHR_MEM_PTR, 4 // Add 4 bytes per sample to the address pointer
  282. SBBO SAMPLE3, SHR_MEM_PTR, 0, 4 // store the sample value into shared memory space
  283. ADD SHR_MEM_PTR, SHR_MEM_PTR, 4 // Add 4 bytes per sample to the address pointer
  284. SBBO SAMPLE4, SHR_MEM_PTR, 0, 4 // store the sample value into shared memory space
  285. ADD SHR_MEM_PTR, SHR_MEM_PTR, 4 // Add 4 bytes per sample to the address pointer
  286. SBBO SAMPLE5, SHR_MEM_PTR, 0, 4 // store the sample value into shared memory space
  287. ADD SHR_MEM_PTR, SHR_MEM_PTR, 4 // Add 4 bytes per sample to the address pointer
  288. SBBO SAMPLE6, SHR_MEM_PTR, 0, 4 // store the sample value into shared memory space
  289. ADD SHR_MEM_PTR, SHR_MEM_PTR, 4 // Add 4 bytes per sample to the address pointer
  290. SBBO SAMPLE7, SHR_MEM_PTR, 0, 4 // store the sample value into shared memory space
  291. ADD SHR_MEM_PTR, SHR_MEM_PTR, 4 // Add 4 bytes per sample to the address pointer
  292. SBBO SAMPLE8, SHR_MEM_PTR, 0, 4 // store the sample value into shared memory space
  293. ADD SHR_MEM_PTR, SHR_MEM_PTR, 4 // Add 4 bytes per sample to the address pointer
  294. SUB CUR_BUF_LEFT, CUR_BUF_LEFT, 32 // reducing the number of samples - 4 bytes per sample, 8 channels
  295. QBEQ BUFFER_DONE, CUR_BUF_LEFT, 0 // See if we have taken 128kb of samples
  296. QBA READ_NEXT_SAMPLE // If we've looped thru all channels in the sample. wait for the next sample
  297. BUFFER_DONE:
  298. MOV CUR_BUF_LEFT, BUFSIZE
  299. // If we have recorded all of the buffers that we need to, then halt.
  300. SUB NUM_BLOCKS, NUM_BLOCKS, 1
  301. QBEQ END, NUM_BLOCKS, 0
  302. MOV R1, BUFSIZE
  303. ADD CUR_BUF_ADRS, CUR_BUF_ADRS, R1
  304. MOV r1, SHARED_MEM_SIZE
  305. QBEQ WRAP_TIME, CUR_BUF_ADRS, r1
  306. QBA READ_NEXT_SAMPLE
  307. WRAP_TIME:
  308. // Always wanted to be a rapper ;-0)
  309. // We have used all the shared memory to write samples, wrap back to the beginning.
  310. MOV CUR_BUF_ADRS, 0
  311. MOV r31.b0, PRU0_R31_VEC_VALID | PRU_EVTOUT_0
  312. HALT //DEBUG
  313. QBA READ_NEXT_SAMPLE
  314. // halt the pru program -- we reach here when the file is full.
  315. END:
  316. HALT