comparison pru_rtaudio.p @ 67:472e892c6e41

Merge newapi into default
author Andrew McPherson <a.mcpherson@qmul.ac.uk>
date Fri, 17 Jul 2015 15:28:18 +0100
parents 0d80ff9e2227 579c86316008
children b697e82ebb25
comparison
equal deleted inserted replaced
21:0d80ff9e2227 67:472e892c6e41
29 #define GPIO0 0x44E07000 29 #define GPIO0 0x44E07000
30 #define GPIO1 0x4804C000 30 #define GPIO1 0x4804C000
31 #define GPIO_CLEARDATAOUT 0x190 31 #define GPIO_CLEARDATAOUT 0x190
32 #define GPIO_SETDATAOUT 0x194 32 #define GPIO_SETDATAOUT 0x194
33 33
34 #define PRU0_ARM_INTERRUPT 19 34 #define PRU0_ARM_INTERRUPT 19 // Interrupt signalling we're done
35 #define PRU1_ARM_INTERRUPT 20 // Interrupt signalling a block is ready
35 36
36 #define C_ADC_DAC_MEM C24 // PRU0 mem 37 #define C_ADC_DAC_MEM C24 // PRU0 mem
37 #ifdef DBOX_CAPE 38 #ifdef DBOX_CAPE
38 #define DAC_GPIO GPIO0 39 #define DAC_GPIO GPIO0
39 #define DAC_CS_PIN (1<<5) // GPIO0:5 = P9 pin 17 40 #define DAC_CS_PIN (1<<5) // GPIO0:5 = P9 pin 17
79 #define COMM_LED_ADDRESS 24 // Which memory address to find the status LED on 80 #define COMM_LED_ADDRESS 24 // Which memory address to find the status LED on
80 #define COMM_LED_PIN_MASK 28 // Which pin to write to change LED 81 #define COMM_LED_PIN_MASK 28 // Which pin to write to change LED
81 #define COMM_FRAME_COUNT 32 // How many frames have elapse since beginning 82 #define COMM_FRAME_COUNT 32 // How many frames have elapse since beginning
82 #define COMM_USE_SPI 36 // Whether or not to use SPI ADC and DAC 83 #define COMM_USE_SPI 36 // Whether or not to use SPI ADC and DAC
83 #define COMM_NUM_CHANNELS 40 // Low 2 bits indicate 8 [0x3], 4 [0x1] or 2 [0x0] channels 84 #define COMM_NUM_CHANNELS 40 // Low 2 bits indicate 8 [0x3], 4 [0x1] or 2 [0x0] channels
84 85 #define COMM_USE_DIGITAL 44 // Whether or not to use DIGITAL
86
85 #define MCASP0_BASE 0x48038000 87 #define MCASP0_BASE 0x48038000
86 #define MCASP1_BASE 0x4803C000 88 #define MCASP1_BASE 0x4803C000
87 89
88 #define MCASP_PWRIDLESYSCONFIG 0x04 90 #define MCASP_PWRIDLESYSCONFIG 0x04
89 #define MCASP_PFUNC 0x10 91 #define MCASP_PFUNC 0x10
178 180
179 // Flags for the flags register 181 // Flags for the flags register
180 #define FLAG_BIT_BUFFER1 0 182 #define FLAG_BIT_BUFFER1 0
181 #define FLAG_BIT_USE_SPI 1 183 #define FLAG_BIT_USE_SPI 1
182 #define FLAG_BIT_MCASP_HWORD 2 // Whether we are on the high word for McASP transmission 184 #define FLAG_BIT_MCASP_HWORD 2 // Whether we are on the high word for McASP transmission
183 185 #define FLAG_BIT_USE_DIGITAL 3
184 // Registers used throughout 186 // Registers used throughout
185 187
186 // r1, r2, r3 are used for temporary storage 188 // r1, r2, r3 are used for temporary storage
189 #define MEM_DIGITAL_BASE 0x11000 //Base address for DIGITAL : Shared RAM + 0x400
190 #define MEM_DIGITAL_BUFFER1_OFFSET 0x400 //Start pointer to DIGITAL_BUFFER1, which is 256 words after.
191 // 256 is the maximum number of frames allowed
192
193 #define reg_digital_current r6 // Pointer to current storage location of DIGITAL
187 #define reg_num_channels r9 // Number of SPI ADC/DAC channels to use 194 #define reg_num_channels r9 // Number of SPI ADC/DAC channels to use
188 #define reg_frame_current r10 // Current frame count in SPI ADC/DAC transfer 195 #define reg_frame_current r10 // Current frame count in SPI ADC/DAC transfer
189 #define reg_frame_total r11 // Total frame count for SPI ADC/DAC 196 #define reg_frame_total r11 // Total frame count for SPI ADC/DAC
190 #define reg_dac_data r12 // Current dword for SPI DAC 197 #define reg_dac_data r12 // Current dword for SPI DAC
191 #define reg_adc_data r13 // Current dword for SPI ADC 198 #define reg_adc_data r13 // Current dword for SPI ADC
203 #define reg_comm_addr r25 // Memory address for communicating with ARM 210 #define reg_comm_addr r25 // Memory address for communicating with ARM
204 #define reg_spi_addr r26 // Base address for SPI 211 #define reg_spi_addr r26 // Base address for SPI
205 // r27, r28 used in macros 212 // r27, r28 used in macros
206 #define reg_mcasp_addr r29 // Base address for McASP 213 #define reg_mcasp_addr r29 // Base address for McASP
207 214
208 // Convert float to 16-bit int, multiplying by 32768 215 //0 P8_07 36 0x890/090 66 gpio2[2]
209 // Converts -1.0 to 1.0 to a full 16-bit range 216 //1 P8_08 37 0x894/094 67 gpio2[3]
210 // input and output can safely be the same register 217 //2 P8_09 39 0x89c/09c 69 gpio2[5]
211 .macro FLOAT_TO_INT16 218 //3 P8_10 38 0x898/098 68 gpio2[4]
212 .mparam input, output 219 //4 P8_11 13 0x834/034 45 gpio1[13]
213 // int exponent = ((input >> 23) & 0xFF) 220 //5 P8_12 12 0x830/030 44 gpio1[12]
214 LSR r27, input, 23 // exponent goes in r27 221 //6 P9_12 30 0x878/078 60 gpio1[28]
215 AND r27, r27, 0xFF 222 //7 P9_14 18 0x848/048 50 gpio1[18]
216 223 //8 P8_15 15 0x83c/03c 47 gpio1[15]
217 // Actual exponent is 127 less than the above; below -15 we 224 //9 P8_16 14 0x838/038 46 gpio1[14]
218 // should return 0. So check if it is less than 112. 225 //10 P9_16 19 0x84c/04c 51 gpio1[19]
219 QBLE EXPONENT_GREQ_MINUS15, r27, 112 226 //11 P8_18 35 0x88c/08c 65 gpio2[1]
220 LDI output, 0 227 //12 P8_27 56 0x8e0/0e0 86 gpio2[22]
221 QBA FLOAT_TO_INT16_DONE 228 //13 P8_28 58 0x8e8/0e8 88 gpio2[24]
222 EXPONENT_GREQ_MINUS15: 229 //14 P8_29 57 0x8e4/0e4 87 gpio2[23]
223 230 //15 P8_30 59 0x8ec/0ec 89 gpio2[25]
224 // Next check if exponent is greater than or equal to 0 (i.e. 231
225 // 127 in our adjusted version. If so we return the max. 232 //generic GPIOs constants
226 QBGT EXPONENT_LT_ZERO, r27, 127 233 //#define GPIO1 0x4804c000
227 QBBS NEGATIVE_MAX, input, 31 // Is sign negative? 234 #define GPIO2 0x481ac000
228 LDI output, 32767 // Max positive value 235 //#define GPIO_CLEARDATAOUT 0x190 //SETDATAOUT is CLEARDATAOUT+4
229 QBA FLOAT_TO_INT16_DONE 236 #define GPIO_OE 0x134
230 NEGATIVE_MAX: 237 #define GPIO_DATAIN 0x138
231 LDI output, 32768 // Actually will be -32768 in signed 238
232 QBA FLOAT_TO_INT16_DONE 239 .macro READ_GPIO_BITS
233 EXPONENT_LT_ZERO: 240 .mparam gpio_data, gpio_num_bit, digital_bit, digital
234 241 QBBC DONE, digital, digital_bit //if the pin is set as an output, nothing to do here
235 // Mask out the mantissa and shift 242 QBBC CLEAR, gpio_data, gpio_num_bit
236 // int mantissa = (input & 0x7FFFFF) | (1 << 23) 243 SET digital, digital_bit+16
237 MOV r28, 0x007FFFFF 244 QBA DONE
238 AND r28, r28, input 245 CLEAR:
239 SET r28, 23 246 CLR digital, digital_bit+16
240 247 QBA DONE
241 // Shift right by -(exponent - 127 - 8) to produce an int 248 DONE:
242 // after effectively multiplying by 2^15 249 .endm
243 // ---> (135 - exponent) 250
244 RSB r27, r27, 135 251 .macro SET_GPIO_BITS
245 LSR r28, r28, r27 252 .mparam gpio_oe, gpio_setdataout, gpio_cleardataout, gpio_num_bit, digital_bit, digital //sets the bits in GPIO_OE, GPIO_SETDATAOUT and GPIO_CLEARDATAOUT
246 253 //Remember that the GPIO_OE Output data enable register behaves as follows for each bit:
247 // Finally, check the sign bit and invert if needed 254 //0 = The corresponding GPIO pin is configured as an output.
248 QBBS NEGATIVE_RESULT, input, 31 255 //1 = The corresponding GPIO pin is configured as an input.
249 // Positive result: but might be 32768 so needs checking 256 QBBS SETINPUT, digital, digital_bit
250 LDI r27, 0x7FFF 257 CLR gpio_oe, gpio_num_bit //if it is an output, configure pin as output
251 MIN output, r27, r28 258 QBBC CLEARDATAOUT, digital, digital_bit+16 // check the output value. If it is 0, branch
252 QBA FLOAT_TO_INT16_DONE 259 SET gpio_setdataout, gpio_num_bit //if it is 1, set output to high
253 NEGATIVE_RESULT: 260 QBA DONE
254 // Take negative: invert the bits and add 1 261 CLEARDATAOUT:
255 LDI r27, 0xFFFF 262 SET gpio_cleardataout, gpio_num_bit // set output to low
256 XOR r28, r28, r27 263 QBA DONE
257 ADD r28, r28, 1 264 SETINPUT: //if it is an input, set the relevant bit
258 CLR output, r28, 16 // Clear carry bit if present 265 SET gpio_oe, gpio_num_bit
259 FLOAT_TO_INT16_DONE: 266 QBA DONE
260 .endm 267 DONE:
261 268 .endm
262 269
263 // Convert float to 16-bit unsigned int, multiplying by 65536 270 QBA START // when first starting, go to START, skipping this section.
264 // Converts 0.0 to 1.0 to a full 16-bit range 271
265 // input and output can safely be the same register 272 DIGITAL:
266 .macro FLOAT_TO_UINT16 273 //IMPORTANT: do NOT use r28 in this macro, as it contains the return address for JAL
267 .mparam input, output 274 //r27 is now the input word passed in render(), one word per frame
268 QBBC NONNEGATIVE, input, 31 // Is sign negative? 275 //[31:16]: data(1=high, 0=low), [15:0]: direction (0=output, 1=input) )
269 LDI output, 0 // All < 0 inputs produce 0 output 276
270 QBA FLOAT_TO_UINT16_DONE 277
271 NONNEGATIVE: 278 //Preparing the gpio_oe, gpio_cleardataout and gpio_setdataout for each module
272 // int exponent = ((input >> 23) & 0xFF) 279 //r2 will hold GPIO1_OE
273 LSR r27, input, 23 // exponent goes in r27 280 //load current status of GPIO_OE in r2
274 AND r27, r27, 0xFF 281 MOV r2, GPIO1 | GPIO_OE
275 282 //it takes 190ns to go through the next instruction
276 // Actual exponent is 127 less than the above; below -16 we 283 LBBO r2, r2, 0, 4
277 // should return 0. So check if it is less than 111. 284 //GPIO1-start
278 QBLE EXPONENT_GREQ_MINUS16, r27, 111 285 //process oe and datain and prepare dataout for GPIO1
279 LDI output, 0 286 //r7 will contain GPIO1_CLEARDATAOUT
280 QBA FLOAT_TO_UINT16_DONE 287 //r8 will contain GPIO1_SETDATAOUT
281 EXPONENT_GREQ_MINUS16: 288 MOV r8, 0
282 289 MOV r7, 0
283 // Next check if exponent is greater than or equal to 0 (i.e. 290 //map GPIO_ANALOG to gpio1 pins,
284 // 127 in our adjusted version. If so we return the max. 291 //r2 is gpio1_oe, r8 is gpio1_setdataout, r7 is gpio1_cleardataout, r27 is the input word
285 QBGT EXPONENT_LT_ZERO, r27, 127 292 //the following operations will read from r27 and update r2,r7,r8
286 LDI output, 65535 // Max positive value 293 SET_GPIO_BITS r2, r8, r7, 13, 4, r27
287 QBA FLOAT_TO_UINT16_DONE 294 SET_GPIO_BITS r2, r8, r7, 12, 5, r27
288 EXPONENT_LT_ZERO: 295 SET_GPIO_BITS r2, r8, r7, 28, 6, r27
289 296 SET_GPIO_BITS r2, r8, r7, 18, 7, r27
290 // Mask out the mantissa and shift 297 SET_GPIO_BITS r2, r8, r7, 15, 8, r27
291 // int mantissa = (input & 0x7FFFFF) | (1 << 23) 298 SET_GPIO_BITS r2, r8, r7, 14, 9, r27
292 MOV r28, 0x007FFFFF 299 SET_GPIO_BITS r2, r8, r7, 19, 10, r27
293 AND r28, r28, input 300 //set the output enable register for gpio1.
294 SET r28, 23 301 MOV r3, GPIO1 | GPIO_OE //use r3 as a temp register
295 302 SBBO r2, r3, 0, 4 //takes two cycles (10ns)
296 // Shift right by -(exponent - 127 - 7) to produce an int 303 //GPIO1-end
297 // after effectively multiplying by 2^16 304 // r2 is now unused
298 // ---> (134 - exponent) 305
299 RSB r27, r27, 134 306 //GPIO2-start
300 LSR r28, r28, r27 307 //r3 will hold GPIO1_OE
301 308 //load current status of GPIO_OE in r3
302 // Check for 65536 and clip at 65535 309 MOV r3, GPIO2 | GPIO_OE
303 LDI r27, 0xFFFF 310 //it takes 200ns to go through the next instructions
304 MIN output, r27, r28 311 LBBO r3, r3, 0, 4
305 FLOAT_TO_UINT16_DONE: 312 //process oe and datain and prepare dataout for GPIO2
306 .endm 313 //r4 will contain GPIO2_CLEARDATAOUT
307 314 //r5 will contain GPIO2_SETDATAOUT
308 315 MOV r5, 0
309 // Convert a 16-bit int to float. This macro assumes that the upper 316 MOV r4, 0
310 // 16 bits of input are 0 and may behave strangely if this is not the case. 317 //map GPIO_ANALOG to gpio2 pins
311 // input and output must be different registers 318 //r3 is gpio2_oe, r5 is gpio2_setdataout, r4 is gpio2_cleardataout, r27 is the input word
312 .macro INT16_TO_FLOAT 319 //the following operations will read from r27 and update r3,r4,r5
313 .mparam input, output 320 SET_GPIO_BITS r3, r5, r4, 2, 0, r27
314 // Check edge cases first: 0 and -32768 (= 32768 in unsigned) 321 SET_GPIO_BITS r3, r5, r4, 3, 1, r27
315 QBNE INPUT_NOT_ZERO, input, 0 322 SET_GPIO_BITS r3, r5, r4, 5, 2, r27
316 LDI output, 0 323 SET_GPIO_BITS r3, r5, r4, 4, 3, r27
317 QBA INT16_TO_FLOAT_DONE 324 SET_GPIO_BITS r3, r5, r4, 1, 11, r27
318 INPUT_NOT_ZERO: 325 SET_GPIO_BITS r3, r5, r4, 22, 12, r27
319 LDI r28, 32768 326 SET_GPIO_BITS r3, r5, r4, 24, 13, r27
320 QBNE INPUT_NOT_MIN, input, r28 327 SET_GPIO_BITS r3, r5, r4, 23, 14, r27
321 MOV output, 0xBF800000 // -1.0 328 SET_GPIO_BITS r3, r5, r4, 25, 15, r27
322 QBA INT16_TO_FLOAT_DONE 329 //set the output enable register for gpio2.
323 INPUT_NOT_MIN: 330 MOV r2, GPIO2 | GPIO_OE //use r2 as a temp registerp
324 // Check for negative values = values with bit 15 set 331 SBBO r3, r2, 0, 4 //takes two cycles (10ns)
325 MOV output, input 332 //GPIO2-end
326 QBBC NEGATIVE_DONE, output, 15 333 //r3 is now unused
327 LDI r28, 0xFFFF 334
328 XOR output, output, r28 335 //load current inputs in r2, r3
329 ADD output, output, 1 336 //r2 will contain GPIO1_DATAIN
330 CLR output, 16 // Clear any carry bit 337 //r3 will contain GPIO2_DATAIN
331 NEGATIVE_DONE: 338 //load the memory locations
332 // Now we need to find the highest bit that is 1 in order to determine 339 MOV r2, GPIO1 | GPIO_DATAIN
333 // the exponent 340 MOV r3, GPIO2 | GPIO_DATAIN
334 LMBD r28, output, 1 341 //takes 375 nns to go through the next two instructions
335 342 //read the datain
336 // Calculate exponent field: 127 + 8 + (r28 - 23) = 112 + r28 343 LBBO r2, r2, 0, 4
337 ADD r27, r28, 112 344 LBBO r3, r3, 0, 4
338 345 //now read from r2 and r3 only the channels that are set as input in the lower word of r27
339 // Take 23 minus the result to get the shift 346 // and set their value in the high word of r27
340 RSB r28, r28, 23 347 //GPIO1
341 LSL output, output, r28 348 READ_GPIO_BITS r2, 13, 4, r27
342 349 READ_GPIO_BITS r2, 12, 5, r27
343 // Now clear bit 23 (implicitly 1) and replace it with the exponent 350 READ_GPIO_BITS r2, 28, 6, r27
344 CLR output, output, 23 351 READ_GPIO_BITS r2, 18, 7, r27
345 LSL r27, r27, 23 352 READ_GPIO_BITS r2, 15, 8, r27
346 OR output, output, r27 353 READ_GPIO_BITS r2, 14, 9, r27
347 354 READ_GPIO_BITS r2, 19, 10, r27
348 // Put the sign bit back in place 355 //GPIO2
349 QBBC INT16_TO_FLOAT_DONE, input, 15 356 READ_GPIO_BITS r3, 2, 0, r27
350 SET output, 31 357 READ_GPIO_BITS r3, 3, 1, r27
351 INT16_TO_FLOAT_DONE: 358 READ_GPIO_BITS r3, 5, 2, r27
352 .endm 359 READ_GPIO_BITS r3, 4, 3, r27
353 360 READ_GPIO_BITS r3, 1, 11, r27
354 // Convert a 16-bit unsigned int to float. 361 READ_GPIO_BITS r3, 22, 12, r27
355 .macro UINT16_TO_FLOAT 362 READ_GPIO_BITS r3, 24, 13, r27
356 .mparam input, output 363 READ_GPIO_BITS r3, 23, 14, r27
357 MOV output, input 364 READ_GPIO_BITS r3, 25, 15, r27
358 365 //r2, r3 are now unused
359 // Clear upper 16 bits 366
360 LDI r27, 0xFFFF 367 //now all the setdataout and cleardataout are ready to be written to the GPIO register.
361 AND output, output, r27 368 //CLEARDATAOUT and SETDATAOUT are consecutive positions in memory, so we just write 8 bytes to CLEARDATAOUT.
362 369 //We can do this because we chose cleardata and setdata registers for a given GPIO to be consecutive
363 // If zero, we're done 370 //load the memory addresses to be written to
364 QBEQ UINT16_TO_FLOAT_DONE, output, 0 371 MOV r2, GPIO1 | GPIO_CLEARDATAOUT //use r2 as a temp register
365 372 MOV r3, GPIO2 | GPIO_CLEARDATAOUT //use r3 as a temp register
366 // Now we need to find the highest bit that is 1 in order to determine 373 //write 8 bytes for each GPIO
367 // the exponent 374 //takes 30ns in total to go through the following two instructions
368 LMBD r28, output, 1 375 SBBO r7, r2, 0, 8 //store r7 and r8 in GPIO1_CLEARDATAOUT and GPIO1_SETDATAOUT
369 376 //takes 145ns to be effective when going low, 185ns when going high
370 // Calculate exponent field: 127 + 7 + (r28 - 23) = 111 + r28 377 SBBO r4, r3, 0, 8 //store r4 and r5 in GPIO2_CLEARDATAOUT and GPIO2_SETDATAOUT
371 ADD r27, r28, 111 378 //takes 95ns to be effective when going low, 130ns when going high
372 379 //reversing the order of the two lines above will swap the performances between the GPIO modules
373 // Take 23 minus the result to get the shift 380 //i.e.: the first line will always take 145ns/185ns and the second one will always take 95ns/130ns,
374 RSB r28, r28, 23 381 //regardless of whether the order is gpio1-gpio2 or gpio2-gpio1
375 LSL output, output, r28 382 JMP r28.w0 // go back to ADC_WRITE_AND_PROCESS_GPIO
376 383
377 // Now clear bit 23 (implicitly 1) and replace it with the exponent 384 .macro HANG //useful for debugging
378 CLR output, output, 23 385 DALOOP:
379 LSL r27, r27, 23 386 set r30.t14
380 OR output, output, r27 387 clr r30.t14
381 UINT16_TO_FLOAT_DONE: 388 QBA DALOOP
382 .endm 389 .endm
383 390
384 // Bring CS line low to write to DAC 391 // Bring CS line low to write to DAC
385 .macro DAC_CS_ASSERT 392 .macro DAC_CS_ASSERT
386 MOV r27, DAC_CS_PIN 393 MOV r27, DAC_CS_PIN
387 MOV r28, DAC_GPIO + GPIO_CLEARDATAOUT 394 MOV r28, DAC_GPIO + GPIO_CLEARDATAOUT
388 SBBO r27, r28, 0, 4 395 SBBO r27, r28, 0, 4
459 // Complete ADC write+read with chip select 466 // Complete ADC write+read with chip select
460 .macro ADC_WRITE 467 .macro ADC_WRITE
461 .mparam in, out 468 .mparam in, out
462 ADC_CS_ASSERT 469 ADC_CS_ASSERT
463 ADC_TX in 470 ADC_TX in
471 ADC_WAIT_FOR_FINISH
472 ADC_RX out
473 ADC_CS_UNASSERT
474 .endm
475
476 // Complete ADC write+read with chip select and also performs IO for digital
477 .macro ADC_WRITE_GPIO
478 .mparam in, out, do_gpio
479 ADC_CS_ASSERT
480 ADC_TX in
481 QBBC GPIO_DONE, reg_flags, FLAG_BIT_USE_DIGITAL //skip if DIGITAL is disabled
482 AND r27, do_gpio, 0x3 // only do a DIGITAL every 2 SPI I/O
483 QBNE GPIO_DONE, r27, 0
484 //from here to GPIO_DONE takes 1.8us, while usually ADC_WAIT_FOR_FINISH only waits for 1.14us.
485 //TODO: it would be better to split the DIGITAL stuff in two parts:
486 //- one taking place during DAC_WRITE which sets the GPIO_OE
487 //- and the other during ADC_WRITE which actually reads DATAIN and writes CLEAR/SET DATAOUT
488 //r27 is actually r27, so do not use r27 from here to ...
489 LBBO r27, reg_digital_current, 0, 4
490 JAL r28.w0, DIGITAL // note that this is not called as a macro, but with JAL. r28 will contain the return address
491 SBBO r27, reg_digital_current, 0, 4
492 //..here you can start using r27 again
493 ADD reg_digital_current, reg_digital_current, 4 //increment pointer
494 GPIO_DONE:
464 ADC_WAIT_FOR_FINISH 495 ADC_WAIT_FOR_FINISH
465 ADC_RX out 496 ADC_RX out
466 ADC_CS_UNASSERT 497 ADC_CS_UNASSERT
467 .endm 498 .endm
468 499
535 MOV reg_flags, 0 566 MOV reg_flags, 0
536 567
537 // Default number of channels in case SPI disabled 568 // Default number of channels in case SPI disabled
538 LDI reg_num_channels, 8 569 LDI reg_num_channels, 8
539 570
571 // Find out whether we should use DIGITAL
572 LBBO r2, reg_comm_addr, COMM_USE_DIGITAL, 4
573 QBEQ DIGITAL_INIT_DONE, r2, 0 // if we use digital
574 SET reg_flags, reg_flags, FLAG_BIT_USE_DIGITAL
575 /* This block of code is not really needed, as the memory is initialized by ARM before the PRU is started.
576 Will leave it here for future reference
577 DIGITAL_INIT: //set the digital buffer to 0x0000ffff (all inputs), to prevent unwanted high outputs
578 //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
579 MOV r2, 0x0000ffff //value to store. 0x0000ffff means all inputs
580 MOV r3, MEM_DIGITAL_BASE //start of the digital buffer
581 MOV r4, MEM_DIGITAL_BASE+2*MEM_DIGITAL_BUFFER1_OFFSET //end of the digital buffer
582 DIGITAL_INIT_BUFFER_LOOP:
583 SBBO r2, r3, 0, 4
584 ADD r3, r3, 4 //increment pointer
585 QBGT DIGITAL_INIT_BUFFER_LOOP, r3, r4 //loop until we reach the end of the buffer
586 */
587 DIGITAL_INIT_DONE:
540 // Find out whether we should use SPI ADC and DAC 588 // Find out whether we should use SPI ADC and DAC
541 LBBO r2, reg_comm_addr, COMM_USE_SPI, 4 589 LBBO r2, reg_comm_addr, COMM_USE_SPI, 4
542 QBEQ SPI_FLAG_CHECK_DONE, r2, 0 590 QBEQ SPI_FLAG_CHECK_DONE, r2, 0
543 SET reg_flags, reg_flags, FLAG_BIT_USE_SPI 591 SET reg_flags, reg_flags, FLAG_BIT_USE_SPI
544
545 SPI_FLAG_CHECK_DONE: 592 SPI_FLAG_CHECK_DONE:
546 // If we don't use SPI, then skip all this init 593 // If we don't use SPI, then skip all this init
547 QBBC SPI_INIT_DONE, reg_flags, FLAG_BIT_USE_SPI 594 QBBC SPI_INIT_DONE, reg_flags, FLAG_BIT_USE_SPI
548 595
549 // Load the number of channels: valid values are 8, 4 or 2 596 // Load the number of channels: valid values are 8, 4 or 2
612 659
613 MOV r2, AD7699_CFG_MASK | (0x01 << AD7699_CHANNEL_OFFSET) 660 MOV r2, AD7699_CFG_MASK | (0x01 << AD7699_CHANNEL_OFFSET)
614 ADC_WRITE r2, r2 661 ADC_WRITE r2, r2
615 SPI_INIT_DONE: 662 SPI_INIT_DONE:
616 663
617 // Prepare McASP0 for audio 664 // Prepare McASP0 for audio
618 MCASP_REG_WRITE MCASP_GBLCTL, 0 // Disable McASP 665 MCASP_REG_WRITE MCASP_GBLCTL, 0 // Disable McASP
619 MCASP_REG_WRITE_EXT MCASP_SRCTL0, 0 // All serialisers off 666 MCASP_REG_WRITE_EXT MCASP_SRCTL0, 0 // All serialisers off
620 MCASP_REG_WRITE_EXT MCASP_SRCTL1, 0 667 MCASP_REG_WRITE_EXT MCASP_SRCTL1, 0
621 MCASP_REG_WRITE_EXT MCASP_SRCTL2, 0 668 MCASP_REG_WRITE_EXT MCASP_SRCTL2, 0
622 MCASP_REG_WRITE_EXT MCASP_SRCTL3, 0 669 MCASP_REG_WRITE_EXT MCASP_SRCTL3, 0
623 MCASP_REG_WRITE_EXT MCASP_SRCTL4, 0 670 MCASP_REG_WRITE_EXT MCASP_SRCTL4, 0
624 MCASP_REG_WRITE_EXT MCASP_SRCTL5, 0 671 MCASP_REG_WRITE_EXT MCASP_SRCTL5, 0
625 672
626 MCASP_REG_WRITE MCASP_PWRIDLESYSCONFIG, 0x02 // Power on 673 MCASP_REG_WRITE MCASP_PWRIDLESYSCONFIG, 0x02 // Power on
627 MCASP_REG_WRITE MCASP_PFUNC, 0x00 // All pins are McASP 674 MCASP_REG_WRITE MCASP_PFUNC, 0x00 // All pins are McASP
628 MCASP_REG_WRITE MCASP_PDIR, MCASP_OUTPUT_PINS // Set pin direction 675 MCASP_REG_WRITE MCASP_PDIR, MCASP_OUTPUT_PINS // Set pin direction
629 MCASP_REG_WRITE MCASP_DLBCTL, 0x00 676 MCASP_REG_WRITE MCASP_DLBCTL, 0x00
630 MCASP_REG_WRITE MCASP_DITCTL, 0x00 677 MCASP_REG_WRITE MCASP_DITCTL, 0x00
631 MCASP_REG_WRITE MCASP_RMASK, MCASP_DATA_MASK // 16 bit data receive 678 MCASP_REG_WRITE MCASP_RMASK, MCASP_DATA_MASK // 16 bit data receive
632 MCASP_REG_WRITE MCASP_RFMT, MCASP_DATA_FORMAT // Set data format 679 MCASP_REG_WRITE MCASP_RFMT, MCASP_DATA_FORMAT // Set data format
633 MCASP_REG_WRITE MCASP_AFSRCTL, 0x100 // I2S mode 680 MCASP_REG_WRITE MCASP_AFSRCTL, 0x100 // I2S mode
634 MCASP_REG_WRITE MCASP_ACLKRCTL, 0x80 // Sample on rising edge 681 MCASP_REG_WRITE MCASP_ACLKRCTL, 0x80 // Sample on rising edge
635 MCASP_REG_WRITE MCASP_AHCLKRCTL, 0x8001 // Internal clock, not inv, /2; irrelevant? 682 MCASP_REG_WRITE MCASP_AHCLKRCTL, 0x8001 // Internal clock, not inv, /2; irrelevant?
636 MCASP_REG_WRITE MCASP_RTDM, 0x03 // Enable TDM slots 0 and 1 683 MCASP_REG_WRITE MCASP_RTDM, 0x03 // Enable TDM slots 0 and 1
637 MCASP_REG_WRITE MCASP_RINTCTL, 0x00 // No interrupts 684 MCASP_REG_WRITE MCASP_RINTCTL, 0x00 // No interrupts
638 MCASP_REG_WRITE MCASP_XMASK, MCASP_DATA_MASK // 16 bit data transmit 685 MCASP_REG_WRITE MCASP_XMASK, MCASP_DATA_MASK // 16 bit data transmit
639 MCASP_REG_WRITE MCASP_XFMT, MCASP_DATA_FORMAT // Set data format 686 MCASP_REG_WRITE MCASP_XFMT, MCASP_DATA_FORMAT // Set data format
640 MCASP_REG_WRITE MCASP_AFSXCTL, 0x100 // I2S mode 687 MCASP_REG_WRITE MCASP_AFSXCTL, 0x100 // I2S mode
641 MCASP_REG_WRITE MCASP_ACLKXCTL, 0x00 // Transmit on rising edge, sync. xmit and recv 688 MCASP_REG_WRITE MCASP_ACLKXCTL, 0x00 // Transmit on rising edge, sync. xmit and recv
642 MCASP_REG_WRITE MCASP_AHCLKXCTL, 0x8001 // External clock from AHCLKX 689 MCASP_REG_WRITE MCASP_AHCLKXCTL, 0x8001 // External clock from AHCLKX
643 MCASP_REG_WRITE MCASP_XTDM, 0x03 // Enable TDM slots 0 and 1 690 MCASP_REG_WRITE MCASP_XTDM, 0x03 // Enable TDM slots 0 and 1
644 MCASP_REG_WRITE MCASP_XINTCTL, 0x00 // No interrupts 691 MCASP_REG_WRITE MCASP_XINTCTL, 0x00 // No interrupts
645 692
646 MCASP_REG_WRITE_EXT MCASP_SRCTL_R, 0x02 // Set up receive serialiser 693 MCASP_REG_WRITE_EXT MCASP_SRCTL_R, 0x02 // Set up receive serialiser
647 MCASP_REG_WRITE_EXT MCASP_SRCTL_X, 0x01 // Set up transmit serialiser 694 MCASP_REG_WRITE_EXT MCASP_SRCTL_X, 0x01 // Set up transmit serialiser
648 MCASP_REG_WRITE_EXT MCASP_WFIFOCTL, 0x00 // Disable FIFOs 695 MCASP_REG_WRITE_EXT MCASP_WFIFOCTL, 0x00 // Disable FIFOs
649 MCASP_REG_WRITE_EXT MCASP_RFIFOCTL, 0x00 696 MCASP_REG_WRITE_EXT MCASP_RFIFOCTL, 0x00
650 697
651 MCASP_REG_WRITE MCASP_XSTAT, 0xFF // Clear transmit errors 698 MCASP_REG_WRITE MCASP_XSTAT, 0xFF // Clear transmit errors
652 MCASP_REG_WRITE MCASP_RSTAT, 0xFF // Clear receive errors 699 MCASP_REG_WRITE MCASP_RSTAT, 0xFF // Clear receive errors
653 700
654 MCASP_REG_SET_BIT_AND_POLL MCASP_RGBLCTL, (1 << 1) // Set RHCLKRST 701 MCASP_REG_SET_BIT_AND_POLL MCASP_RGBLCTL, (1 << 1) // Set RHCLKRST
655 MCASP_REG_SET_BIT_AND_POLL MCASP_XGBLCTL, (1 << 9) // Set XHCLKRST 702 MCASP_REG_SET_BIT_AND_POLL MCASP_XGBLCTL, (1 << 9) // Set XHCLKRST
656 703
657 // The above write sequence will have temporarily changed the AHCLKX frequency 704 // The above write sequence will have temporarily changed the AHCLKX frequency
658 // The PLL needs time to settle or the sample rate will be unstable and possibly 705 // The PLL needs time to settle or the sample rate will be unstable and possibly
659 // cause an underrun. Give it ~1ms before going on. 706 // cause an underrun. Give it ~1ms before going on.
660 // 10ns per loop iteration = 10^-8s --> 10^5 iterations needed 707 // 10ns per loop iteration = 10^-8s --> 10^5 iterations needed
661 708
662 MOV r2, 1 << 28 709 MOV r2, 1 << 28
663 MOV r3, GPIO1 + GPIO_SETDATAOUT 710 MOV r3, GPIO1 + GPIO_SETDATAOUT
664 SBBO r2, r3, 0, 4 711 SBBO r2, r3, 0, 4
665 712
666 MOV r2, 100000 713 MOV r2, 100000
667 MCASP_INIT_WAIT: 714 MCASP_INIT_WAIT:
668 SUB r2, r2, 1 715 SUB r2, r2, 1
669 QBNE MCASP_INIT_WAIT, r2, 0 716 QBNE MCASP_INIT_WAIT, r2, 0
670 717
671 MOV r2, 1 << 28 718 MOV r2, 1 << 28
672 MOV r3, GPIO1 + GPIO_CLEARDATAOUT 719 MOV r3, GPIO1 + GPIO_CLEARDATAOUT
673 SBBO r2, r3, 0, 4 720 SBBO r2, r3, 0, 4
674 721
675 MCASP_REG_SET_BIT_AND_POLL MCASP_RGBLCTL, (1 << 0) // Set RCLKRST 722 MCASP_REG_SET_BIT_AND_POLL MCASP_RGBLCTL, (1 << 0) // Set RCLKRST
676 MCASP_REG_SET_BIT_AND_POLL MCASP_XGBLCTL, (1 << 8) // Set XCLKRST 723 MCASP_REG_SET_BIT_AND_POLL MCASP_XGBLCTL, (1 << 8) // Set XCLKRST
677 MCASP_REG_SET_BIT_AND_POLL MCASP_RGBLCTL, (1 << 2) // Set RSRCLR 724 MCASP_REG_SET_BIT_AND_POLL MCASP_RGBLCTL, (1 << 2) // Set RSRCLR
678 MCASP_REG_SET_BIT_AND_POLL MCASP_XGBLCTL, (1 << 10) // Set XSRCLR 725 MCASP_REG_SET_BIT_AND_POLL MCASP_XGBLCTL, (1 << 10) // Set XSRCLR
679 MCASP_REG_SET_BIT_AND_POLL MCASP_RGBLCTL, (1 << 3) // Set RSMRST 726 MCASP_REG_SET_BIT_AND_POLL MCASP_RGBLCTL, (1 << 3) // Set RSMRST
680 MCASP_REG_SET_BIT_AND_POLL MCASP_XGBLCTL, (1 << 11) // Set XSMRST 727 MCASP_REG_SET_BIT_AND_POLL MCASP_XGBLCTL, (1 << 11) // Set XSMRST
681 728
682 MCASP_REG_WRITE_EXT MCASP_XBUF, 0x00 // Write to the transmit buffer to prevent underflow 729 MCASP_REG_WRITE_EXT MCASP_XBUF, 0x00 // Write to the transmit buffer to prevent underflow
683 730
684 MCASP_REG_SET_BIT_AND_POLL MCASP_RGBLCTL, (1 << 4) // Set RFRST 731 MCASP_REG_SET_BIT_AND_POLL MCASP_RGBLCTL, (1 << 4) // Set RFRST
685 MCASP_REG_SET_BIT_AND_POLL MCASP_XGBLCTL, (1 << 12) // Set XFRST 732 MCASP_REG_SET_BIT_AND_POLL MCASP_XGBLCTL, (1 << 12) // Set XFRST
686 733
687 // Initialisation 734 // Initialisation
688 LBBO reg_frame_total, reg_comm_addr, COMM_BUFFER_FRAMES, 4 // Total frame count (SPI; 0.5x-2x for McASP) 735 LBBO reg_frame_total, reg_comm_addr, COMM_BUFFER_FRAMES, 4 // Total frame count (SPI; 0.5x-2x for McASP)
689 MOV reg_dac_buf0, 0 // DAC buffer 0 start pointer 736 MOV reg_dac_buf0, 0 // DAC buffer 0 start pointer
690 LSL reg_dac_buf1, reg_frame_total, 1 // DAC buffer 1 start pointer = N[ch]*2[bytes]*bufsize 737 LSL reg_dac_buf1, reg_frame_total, 1 // DAC buffer 1 start pointer = N[ch]*2[bytes]*bufsize
691 LMBD r2, reg_num_channels, 1 // Returns 1, 2 or 3 depending on the number of channels 738 LMBD r2, reg_num_channels, 1 // Returns 1, 2 or 3 depending on the number of channels
692 LSL reg_dac_buf1, reg_dac_buf1, r2 // Multiply by 2, 4 or 8 to get the N[ch] scaling above 739 LSL reg_dac_buf1, reg_dac_buf1, r2 // Multiply by 2, 4 or 8 to get the N[ch] scaling above
693 MOV reg_mcasp_buf0, 0 // McASP DAC buffer 0 start pointer 740 MOV reg_mcasp_buf0, 0 // McASP DAC buffer 0 start pointer
694 LSL reg_mcasp_buf1, reg_frame_total, r2 // McASP DAC buffer 1 start pointer = 2[ch]*2[bytes]*(N/4)[samples/spi]*bufsize 741 LSL reg_mcasp_buf1, reg_frame_total, r2 // McASP DAC buffer 1 start pointer = 2[ch]*2[bytes]*(N/4)[samples/spi]*bufsize
695 CLR reg_flags, reg_flags, FLAG_BIT_BUFFER1 // Bit 0 holds which buffer we are on 742 CLR reg_flags, reg_flags, FLAG_BIT_BUFFER1 // Bit 0 holds which buffer we are on
696 MOV r2, 0 743 MOV r2, 0
697 SBBO r2, reg_comm_addr, COMM_FRAME_COUNT, 4 // Start with frame count of 0 744 SBBO r2, reg_comm_addr, COMM_FRAME_COUNT, 4 // Start with frame count of 0
698 745 /* This block of code is not really needed, as the memory is initialized by ARM before the PRU is started.
746 Will leave it here for future reference
747 //Initialise all SPI and audio buffers (DAC0, DAC1, ADC0, ADC1) to zero.
748 //This is useful for analog outs so they do not have spikes during the first buffer.
749 //This is not very useful for audio, as you still hear the initial "tumpf" when the converter starts
750 //and each sample in the DAC buffer is reset to 0 after it is written to the DAC.
751
752 QBBC SPI_INIT_BUFFER_DONE, reg_flags, FLAG_BIT_USE_SPI
753 //Initialize SPI buffers
754 //compute the memory offset of the end of the audio buffer and store it in r4
755 SUB r4, reg_dac_buf1, reg_dac_buf0 // length of the buffer, assumes reg_dac_buf1>ref_dac_buf0
756 LSL r4, r4, 2 //length of four buffers (DAC0, DAC1, ADC0, ADC1)
757 ADD r4, reg_dac_buf0, r4 //total offset
758 MOV r2, 0// value to store
759 MOV r3, 0 // offset counter
760 SPI_INIT_BUFFER_LOOP:
761 SBCO r2, C_ADC_DAC_MEM, r3, 4
762 ADD r3, r3, 4
763 QBGT SPI_INIT_BUFFER_LOOP, r3, r4
764 SPI_INIT_BUFFER_DONE:
765
766 //Initialize audio buffers
767 //compute the memory offset of the end of the audio buffer and store it in r4
768 SUB r4, reg_mcasp_buf1, reg_mcasp_buf0 // length of the buffer, assumes reg_mcasp_buf1>ref_mcasp_buf0
769 LSL r4, r4, 2 //length of four buffers (DAC0, DAC1, ADC0, ADC1)
770 ADD r4, reg_mcasp_buf0, r4 //total offset
771 MOV r2, 0 // value to store
772 MOV r3, 0 // offset counter
773 MCASP_INIT_BUFFER_LOOP:
774 SBCO r2, C_MCASP_MEM, r3, 4
775 ADD r3, r3, 4
776 QBGT MCASP_INIT_BUFFER_LOOP, r3, r4
777 */
699 // Here we are out of sync by one TDM slot since the 0 word transmitted above will have occupied 778 // Here we are out of sync by one TDM slot since the 0 word transmitted above will have occupied
700 // the first output slot. Send one more word before jumping into the loop. 779 // the first output slot. Send one more word before jumping into the loop.
701 MCASP_DAC_WAIT_BEFORE_LOOP: 780 MCASP_DAC_WAIT_BEFORE_LOOP:
702 LBBO r2, reg_mcasp_addr, MCASP_XSTAT, 4 781 LBBO r2, reg_mcasp_addr, MCASP_XSTAT, 4
703 QBBC MCASP_DAC_WAIT_BEFORE_LOOP, r2, MCASP_XSTAT_XDATA_BIT 782 QBBC MCASP_DAC_WAIT_BEFORE_LOOP, r2, MCASP_XSTAT_XDATA_BIT
712 QBBC MCASP_ADC_WAIT_BEFORE_LOOP, r2, MCASP_RSTAT_RDATA_BIT 791 QBBC MCASP_ADC_WAIT_BEFORE_LOOP, r2, MCASP_RSTAT_RDATA_BIT
713 792
714 MCASP_REG_READ_EXT MCASP_RBUF, r2 793 MCASP_REG_READ_EXT MCASP_RBUF, r2
715 794
716 WRITE_ONE_BUFFER: 795 WRITE_ONE_BUFFER:
796
717 // Write a single buffer of DAC samples and read a buffer of ADC samples 797 // Write a single buffer of DAC samples and read a buffer of ADC samples
718 // Load starting positions 798 // Load starting positions
719 MOV reg_dac_current, reg_dac_buf0 // DAC: reg_dac_current is current pointer 799 MOV reg_dac_current, reg_dac_buf0 // DAC: reg_dac_current is current pointer
720 LMBD r2, reg_num_channels, 1 // 1, 2 or 3 for 2, 4 or 8 channels 800 LMBD r2, reg_num_channels, 1 // 1, 2 or 3 for 2, 4 or 8 channels
721 LSL reg_adc_current, reg_frame_total, r2 801 LSL reg_adc_current, reg_frame_total, r2
724 MOV reg_mcasp_dac_current, reg_mcasp_buf0 // McASP: set current DAC pointer 804 MOV reg_mcasp_dac_current, reg_mcasp_buf0 // McASP: set current DAC pointer
725 LSL reg_mcasp_adc_current, reg_frame_total, r2 // McASP ADC: starts (N/2)*2*2*bufsize beyond DAC 805 LSL reg_mcasp_adc_current, reg_frame_total, r2 // McASP ADC: starts (N/2)*2*2*bufsize beyond DAC
726 LSL reg_mcasp_adc_current, reg_mcasp_adc_current, 1 806 LSL reg_mcasp_adc_current, reg_mcasp_adc_current, 1
727 ADC reg_mcasp_adc_current, reg_mcasp_adc_current, reg_mcasp_dac_current 807 ADC reg_mcasp_adc_current, reg_mcasp_adc_current, reg_mcasp_dac_current
728 MOV reg_frame_current, 0 808 MOV reg_frame_current, 0
729 809 QBBS DIGITAL_BASE_CHECK_SET, reg_flags, FLAG_BIT_BUFFER1 //check which buffer we are using for DIGITAL
810 // if we are here, we are using buffer0
811 MOV reg_digital_current, MEM_DIGITAL_BASE
812 QBA DIGITAL_BASE_CHECK_DONE
813 DIGITAL_BASE_CHECK_SET: //if we are here, we are using buffer1
814 MOV reg_digital_current, MEM_DIGITAL_BASE+MEM_DIGITAL_BUFFER1_OFFSET //so adjust offset appropriately
815 DIGITAL_BASE_CHECK_DONE:
816
730 WRITE_LOOP: 817 WRITE_LOOP:
731 // Write N channels to DAC from successive values in memory 818 // Write N channels to DAC from successive values in memory
732 // At the same time, read N channels from ADC 819 // At the same time, read N channels from ADC
733 // Unrolled by a factor of 2 to get high and low words 820 // Unrolled by a factor of 2 to get high and low words
734 MOV r1, 0 821 MOV r1, 0
803 // Now store the result and increment the pointer 890 // Now store the result and increment the pointer
804 SBCO reg_mcasp_adc_data, C_MCASP_MEM, reg_mcasp_adc_current, 4 891 SBCO reg_mcasp_adc_data, C_MCASP_MEM, reg_mcasp_adc_current, 4
805 ADD reg_mcasp_adc_current, reg_mcasp_adc_current, 4 892 ADD reg_mcasp_adc_current, reg_mcasp_adc_current, 4
806 MCASP_ADC_DONE: 893 MCASP_ADC_DONE:
807 QBBC SPI_SKIP_WRITE, reg_flags, FLAG_BIT_USE_SPI 894 QBBC SPI_SKIP_WRITE, reg_flags, FLAG_BIT_USE_SPI
808 895
809 // DAC: transmit low word (first in little endian) 896 // DAC: transmit low word (first in little endian)
810 MOV r2, 0xFFFF 897 MOV r2, 0xFFFF
811 AND r7, reg_dac_data, r2 898 AND r7, reg_dac_data, r2
812 LSL r7, r7, AD5668_DATA_OFFSET 899 LSL r7, r7, AD5668_DATA_OFFSET
813 MOV r8, (0x03 << AD5668_COMMAND_OFFSET) 900 MOV r8, (0x03 << AD5668_COMMAND_OFFSET)
824 SUB r7, reg_num_channels, 1 911 SUB r7, reg_num_channels, 1
825 AND r8, r8, r7 912 AND r8, r8, r7
826 LSL r8, r8, AD7699_CHANNEL_OFFSET 913 LSL r8, r8, AD7699_CHANNEL_OFFSET
827 MOV r7, AD7699_CFG_MASK 914 MOV r7, AD7699_CFG_MASK
828 OR r7, r7, r8 915 OR r7, r7, r8
829 ADC_WRITE r7, r7 916
917 //ssssssssssssssssssssssssssss
918 ADC_WRITE_GPIO r7, r7, r1
830 919
831 // Mask out only the relevant 16 bits and store in reg_adc_data 920 // Mask out only the relevant 16 bits and store in reg_adc_data
832 MOV r2, 0xFFFF 921 MOV r2, 0xFFFF
833 AND reg_adc_data, r7, r2 922 AND reg_adc_data, r7, r2
834 923
870 // Repeat 4 times for 8 channels (2 samples per loop, r1 += 1 already happened) 959 // Repeat 4 times for 8 channels (2 samples per loop, r1 += 1 already happened)
871 // For 4 or 2 channels, repeat 2 or 1 times, according to flags 960 // For 4 or 2 channels, repeat 2 or 1 times, according to flags
872 ADD r1, r1, 1 961 ADD r1, r1, 1
873 QBNE ADC_DAC_LOOP, r1, reg_num_channels 962 QBNE ADC_DAC_LOOP, r1, reg_num_channels
874 QBA ADC_DAC_LOOP_DONE 963 QBA ADC_DAC_LOOP_DONE
875
876 SPI_SKIP_WRITE: 964 SPI_SKIP_WRITE:
877 // We get here only if the SPI ADC and DAC are disabled 965 // We get here only if the SPI ADC and DAC are disabled
878 // Just keep the loop going for McASP 966 // Just keep the loop going for McASP
879 967
880 // Toggle the high/low word for McASP control (since we send one word out of 968 // Toggle the high/low word for McASP control (since we send one word out of
896 MOV reg_dac_buf0, reg_dac_buf1 984 MOV reg_dac_buf0, reg_dac_buf1
897 MOV reg_dac_buf1, r2 985 MOV reg_dac_buf1, r2
898 MOV r2, reg_mcasp_buf0 986 MOV r2, reg_mcasp_buf0
899 MOV reg_mcasp_buf0, reg_mcasp_buf1 987 MOV reg_mcasp_buf0, reg_mcasp_buf1
900 MOV reg_mcasp_buf1, r2 988 MOV reg_mcasp_buf1, r2
989 XOR reg_flags, reg_flags, (1 << FLAG_BIT_BUFFER1) //flip the buffer flag
901 990
902 // Notify ARM of buffer swap 991 // Notify ARM of buffer swap
903 XOR reg_flags, reg_flags, (1 << FLAG_BIT_BUFFER1)
904 AND r2, reg_flags, (1 << FLAG_BIT_BUFFER1) // Mask out every but low bit 992 AND r2, reg_flags, (1 << FLAG_BIT_BUFFER1) // Mask out every but low bit
905 SBBO r2, reg_comm_addr, COMM_CURRENT_BUFFER, 4 993 SBBO r2, reg_comm_addr, COMM_CURRENT_BUFFER, 4
906 994 MOV R31.b0, PRU1_ARM_INTERRUPT + 16 // Interrupt to host loop
995
907 // Increment the frame count in the comm buffer (for status monitoring) 996 // Increment the frame count in the comm buffer (for status monitoring)
908 LBBO r2, reg_comm_addr, COMM_FRAME_COUNT, 4 997 LBBO r2, reg_comm_addr, COMM_FRAME_COUNT, 4
909 ADD r2, r2, reg_frame_total 998 ADD r2, r2, reg_frame_total
910 SBBO r2, reg_comm_addr, COMM_FRAME_COUNT, 4 999 SBBO r2, reg_comm_addr, COMM_FRAME_COUNT, 4
911 1000
924 LBBO r2, reg_comm_addr, COMM_LED_PIN_MASK, 4 1013 LBBO r2, reg_comm_addr, COMM_LED_PIN_MASK, 4
925 MOV r1, GPIO_CLEARDATAOUT 1014 MOV r1, GPIO_CLEARDATAOUT
926 ADD r3, r3, r1 // Address for GPIO clear register 1015 ADD r3, r3, r1 // Address for GPIO clear register
927 SBBO r2, r3, 0, 4 // Clear GPIO pin 1016 SBBO r2, r3, 0, 4 // Clear GPIO pin
928 LED_BLINK_DONE: 1017 LED_BLINK_DONE:
929
930 QBBC TESTLOW, reg_flags, FLAG_BIT_BUFFER1
931 MOV r2, 1 << 28
932 MOV r3, GPIO1 + GPIO_SETDATAOUT
933 SBBO r2, r3, 0, 4
934 QBA TESTDONE
935 TESTLOW:
936 MOV r2, 1 << 28
937 MOV r3, GPIO1 + GPIO_CLEARDATAOUT
938 SBBO r2, r3, 0, 4
939 TESTDONE:
940
941 // Check if we should finish: flag is zero as long as it should run 1018 // Check if we should finish: flag is zero as long as it should run
942 LBBO r2, reg_comm_addr, COMM_SHOULD_STOP, 4 1019 LBBO r2, reg_comm_addr, COMM_SHOULD_STOP, 4
943 QBEQ WRITE_ONE_BUFFER, r2, 0 1020 QBEQ WRITE_ONE_BUFFER, r2, 0
944 1021
945 CLEANUP: 1022 CLEANUP:
957 MOV r3, SPI_BASE + SPI_CH0CTRL 1034 MOV r3, SPI_BASE + SPI_CH0CTRL
958 LBBO r2, r3, 0, 4 1035 LBBO r2, r3, 0, 4
959 CLR r2, r2, 1 1036 CLR r2, r2, 1
960 SBBO r2, r3, 0, 4 1037 SBBO r2, r3, 0, 4
961 SPI_CLEANUP_DONE: 1038 SPI_CLEANUP_DONE:
962
963 // Signal the ARM that we have finished 1039 // Signal the ARM that we have finished
964 MOV R31.b0, PRU0_ARM_INTERRUPT + 16 1040 MOV R31.b0, PRU0_ARM_INTERRUPT + 16
965 HALT 1041 HALT