comparison pru_rtaudio.p @ 12:a6beeba3a648

Initial support for higher matrix sample rates by reducing the number of channels. Input not tested yet, and not all examples updated to new format.
author andrewm
date Thu, 22 Jan 2015 19:00:22 +0000
parents 8a575ba3ab52
children 6adb088196a7
comparison
equal deleted inserted replaced
11:517715b23df0 12:a6beeba3a648
78 #define COMM_SYNC_PIN_MASK 20 // Which pin to read for the sync 78 #define COMM_SYNC_PIN_MASK 20 // Which pin to read for the sync
79 #define COMM_LED_ADDRESS 24 // Which memory address to find the status LED on 79 #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 80 #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 81 #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 82 #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
83 84
84 #define MCASP0_BASE 0x48038000 85 #define MCASP0_BASE 0x48038000
85 #define MCASP1_BASE 0x4803C000 86 #define MCASP1_BASE 0x4803C000
86 87
87 #define MCASP_PWRIDLESYSCONFIG 0x04 88 #define MCASP_PWRIDLESYSCONFIG 0x04
171 #endif 172 #endif
172 173
173 #define MCASP_DATA_MASK 0xFFFF // 16 bit data 174 #define MCASP_DATA_MASK 0xFFFF // 16 bit data
174 #define MCASP_DATA_FORMAT 0x807C // MSB first, 0 bit delay, 16 bits, CFG bus, ROR 16bits 175 #define MCASP_DATA_FORMAT 0x807C // MSB first, 0 bit delay, 16 bits, CFG bus, ROR 16bits
175 176
176 #define C_MCASP_MEM C28 // Shared PRU mem 177 #define C_MCASP_MEM C28 // Shared PRU mem
177 178
178 // Flags for the flags register 179 // Flags for the flags register
179 #define FLAG_BIT_BUFFER1 0 180 #define FLAG_BIT_BUFFER1 0
180 #define FLAG_BIT_USE_SPI 1 181 #define FLAG_BIT_USE_SPI 1
182 #define FLAG_BIT_MCASP_HWORD 2 // Whether we are on the high word for McASP transmission
181 183
182 // Registers used throughout 184 // Registers used throughout
183 185
184 // r1, r2, r3 are used for temporary storage 186 // r1, r2, r3 are used for temporary storage
187 #define reg_num_channels r9 // Number of SPI ADC/DAC channels to use
185 #define reg_frame_current r10 // Current frame count in SPI ADC/DAC transfer 188 #define reg_frame_current r10 // Current frame count in SPI ADC/DAC transfer
186 #define reg_frame_total r11 // Total frame count for SPI ADC/DAC 189 #define reg_frame_total r11 // Total frame count for SPI ADC/DAC
187 #define reg_dac_data r12 // Current dword for SPI DAC 190 #define reg_dac_data r12 // Current dword for SPI DAC
188 #define reg_adc_data r13 // Current dword for SPI ADC 191 #define reg_adc_data r13 // Current dword for SPI ADC
189 #define reg_mcasp_dac_data r14 // Current dword for McASP DAC 192 #define reg_mcasp_dac_data r14 // Current dword for McASP DAC
354 SBCO r0, C4, 4, 4 357 SBCO r0, C4, 4, 4
355 358
356 // Clear flags 359 // Clear flags
357 MOV reg_flags, 0 360 MOV reg_flags, 0
358 361
362 // Default number of channels in case SPI disabled
363 LDI reg_num_channels, 8
364
359 // Find out whether we should use SPI ADC and DAC 365 // Find out whether we should use SPI ADC and DAC
360 LBBO r2, reg_comm_addr, COMM_USE_SPI, 4 366 LBBO r2, reg_comm_addr, COMM_USE_SPI, 4
361 QBEQ SPI_FLAG_CHECK_DONE, r2, 0 367 QBEQ SPI_FLAG_CHECK_DONE, r2, 0
362 SET reg_flags, reg_flags, FLAG_BIT_USE_SPI 368 SET reg_flags, reg_flags, FLAG_BIT_USE_SPI
363 369
364 SPI_FLAG_CHECK_DONE: 370 SPI_FLAG_CHECK_DONE:
365 // If we don't use SPI, then skip all this init 371 // If we don't use SPI, then skip all this init
366 QBBC SPI_INIT_DONE, reg_flags, FLAG_BIT_USE_SPI 372 QBBC SPI_INIT_DONE, reg_flags, FLAG_BIT_USE_SPI
373
374 // Load the number of channels: valid values are 8, 4 or 2
375 LBBO reg_num_channels, reg_comm_addr, COMM_NUM_CHANNELS, 4
376 QBGT SPI_NUM_CHANNELS_LT8, reg_num_channels, 8 // 8 > num_channels ?
377 LDI reg_num_channels, 8 // If N >= 8, N = 8
378 QBA SPI_NUM_CHANNELS_DONE
379 SPI_NUM_CHANNELS_LT8:
380 QBGT SPI_NUM_CHANNELS_LT4, reg_num_channels, 4 // 4 > num_channels ?
381 LDI reg_num_channels, 4 // If N >= 4, N = 4
382 QBA SPI_NUM_CHANNELS_DONE
383 SPI_NUM_CHANNELS_LT4:
384 LDI reg_num_channels, 2 // else N = 2
385 SPI_NUM_CHANNELS_DONE:
367 386
368 // Init SPI clock 387 // Init SPI clock
369 MOV r2, 0x02 388 MOV r2, 0x02
370 MOV r3, CLOCK_BASE + CLOCK_SPI0 389 MOV r3, CLOCK_BASE + CLOCK_SPI0
371 SBBO r2, r3, 0, 4 390 SBBO r2, r3, 0, 4
489 508
490 MCASP_REG_SET_BIT_AND_POLL MCASP_RGBLCTL, (1 << 4) // Set RFRST 509 MCASP_REG_SET_BIT_AND_POLL MCASP_RGBLCTL, (1 << 4) // Set RFRST
491 MCASP_REG_SET_BIT_AND_POLL MCASP_XGBLCTL, (1 << 12) // Set XFRST 510 MCASP_REG_SET_BIT_AND_POLL MCASP_XGBLCTL, (1 << 12) // Set XFRST
492 511
493 // Initialisation 512 // Initialisation
494 LBBO reg_frame_total, reg_comm_addr, COMM_BUFFER_FRAMES, 4 // Total frame count (SPI; 2x for McASP) 513 LBBO reg_frame_total, reg_comm_addr, COMM_BUFFER_FRAMES, 4 // Total frame count (SPI; 0.5x-2x for McASP)
495 MOV reg_dac_buf0, 0 // DAC buffer 0 start pointer 514 MOV reg_dac_buf0, 0 // DAC buffer 0 start pointer
496 LSL reg_dac_buf1, reg_frame_total, 4 // DAC buffer 1 start pointer = 8[ch]*2[bytes]*bufsize 515 LSL reg_dac_buf1, reg_frame_total, 1 // DAC buffer 1 start pointer = N[ch]*2[bytes]*bufsize
516 LMBD r2, reg_num_channels, 1 // Returns 1, 2 or 3 depending on the number of channels
517 LSL reg_dac_buf1, reg_dac_buf1, r2 // Multiply by 2, 4 or 8 to get the N[ch] scaling above
497 MOV reg_mcasp_buf0, 0 // McASP DAC buffer 0 start pointer 518 MOV reg_mcasp_buf0, 0 // McASP DAC buffer 0 start pointer
498 LSL reg_mcasp_buf1, reg_frame_total, 3 // McASP DAC buffer 1 start pointer = 2[ch]*2[bytes]*2[samples/spi]*bufsize 519 LSL reg_mcasp_buf1, reg_frame_total, r2 // McASP DAC buffer 1 start pointer = 2[ch]*2[bytes]*(N/4)[samples/spi]*bufsize
499 CLR reg_flags, reg_flags, FLAG_BIT_BUFFER1 // Bit 0 holds which buffer we are on 520 CLR reg_flags, reg_flags, FLAG_BIT_BUFFER1 // Bit 0 holds which buffer we are on
500 MOV r2, 0 521 MOV r2, 0
501 SBBO r2, reg_comm_addr, COMM_FRAME_COUNT, 4 // Start with frame count of 0 522 SBBO r2, reg_comm_addr, COMM_FRAME_COUNT, 4 // Start with frame count of 0
502 523
503 // Here we are out of sync by one TDM slot since the 0 word transmitted above will have occupied 524 // Here we are out of sync by one TDM slot since the 0 word transmitted above will have occupied
519 540
520 WRITE_ONE_BUFFER: 541 WRITE_ONE_BUFFER:
521 // Write a single buffer of DAC samples and read a buffer of ADC samples 542 // Write a single buffer of DAC samples and read a buffer of ADC samples
522 // Load starting positions 543 // Load starting positions
523 MOV reg_dac_current, reg_dac_buf0 // DAC: reg_dac_current is current pointer 544 MOV reg_dac_current, reg_dac_buf0 // DAC: reg_dac_current is current pointer
524 LSL reg_adc_current, reg_frame_total, 5 // 16 * 2 * bufsize 545 LMBD r2, reg_num_channels, 1 // 1, 2 or 3 for 2, 4 or 8 channels
525 ADD reg_adc_current, reg_adc_current, reg_dac_current // ADC: starts 16 * 2 * bufsize beyond DAC 546 LSL reg_adc_current, reg_frame_total, r2
547 LSL reg_adc_current, reg_adc_current, 2 // N * 2 * 2 * bufsize
548 ADD reg_adc_current, reg_adc_current, reg_dac_current // ADC: starts N * 2 * 2 * bufsize beyond DAC
526 MOV reg_mcasp_dac_current, reg_mcasp_buf0 // McASP: set current DAC pointer 549 MOV reg_mcasp_dac_current, reg_mcasp_buf0 // McASP: set current DAC pointer
527 LSL reg_mcasp_adc_current, reg_frame_total, 4 // McASP ADC: starts 4*2*2*bufsize beyond DAC 550 LSL reg_mcasp_adc_current, reg_frame_total, r2 // McASP ADC: starts (N/2)*2*2*bufsize beyond DAC
551 LSL reg_mcasp_adc_current, reg_mcasp_adc_current, 1
528 ADC reg_mcasp_adc_current, reg_mcasp_adc_current, reg_mcasp_dac_current 552 ADC reg_mcasp_adc_current, reg_mcasp_adc_current, reg_mcasp_dac_current
529 MOV reg_frame_current, 0 553 MOV reg_frame_current, 0
530 554
531 WRITE_LOOP: 555 WRITE_LOOP:
532 // Write 8 channels to DAC from successive values in memory 556 // Write N channels to DAC from successive values in memory
533 // At the same time, read 8 channels from ADC 557 // At the same time, read N channels from ADC
534 // Unrolled by a factor of 2 to get high and low words 558 // Unrolled by a factor of 2 to get high and low words
535 MOV r1, 0 559 MOV r1, 0
536 ADC_DAC_LOOP: 560 ADC_DAC_LOOP:
537 QBBC SPI_DAC_LOAD_DONE, reg_flags, FLAG_BIT_USE_SPI 561 QBBC SPI_DAC_LOAD_DONE, reg_flags, FLAG_BIT_USE_SPI
538 // Load next 2 SPI DAC samples and store zero in their place 562 // Load next 2 SPI DAC samples and store zero in their place
542 ADD reg_dac_current, reg_dac_current, 4 566 ADD reg_dac_current, reg_dac_current, 4
543 SPI_DAC_LOAD_DONE: 567 SPI_DAC_LOAD_DONE:
544 568
545 // On even iterations, load two more samples and choose the first one 569 // On even iterations, load two more samples and choose the first one
546 // On odd iterations, transmit the second of the samples already loaded 570 // On odd iterations, transmit the second of the samples already loaded
547 QBBS MCASP_DAC_HIGH_WORD, r1, 1 571 // QBBS MCASP_DAC_HIGH_WORD, r1, 1
572 QBBS MCASP_DAC_HIGH_WORD, reg_flags, FLAG_BIT_MCASP_HWORD
548 MCASP_DAC_LOW_WORD: 573 MCASP_DAC_LOW_WORD:
549 // Load next 2 Audio DAC samples and store zero in their place 574 // Load next 2 Audio DAC samples and store zero in their place
550 LBCO reg_mcasp_dac_data, C_MCASP_MEM, reg_mcasp_dac_current, 4 575 LBCO reg_mcasp_dac_data, C_MCASP_MEM, reg_mcasp_dac_current, 4
551 MOV r2, 0 576 MOV r2, 0
552 SBCO r2, C_MCASP_MEM, reg_mcasp_dac_current, 4 577 SBCO r2, C_MCASP_MEM, reg_mcasp_dac_current, 4
559 QBA MCASP_WAIT_XSTAT 584 QBA MCASP_WAIT_XSTAT
560 MCASP_DAC_HIGH_WORD: 585 MCASP_DAC_HIGH_WORD:
561 // Take the high word of the previously loaded data 586 // Take the high word of the previously loaded data
562 LSR r7, reg_mcasp_dac_data, 16 587 LSR r7, reg_mcasp_dac_data, 16
563 588
564 // Two audio frames per SPI frame = 4 audio samples per SPI frame 589 // Every 2 channels we send one audio sample; this loop already
565 // Therefore every 2 channels we send one audio sample; this loop already
566 // sends exactly two SPI channels. 590 // sends exactly two SPI channels.
567 // Wait for McASP XSTAT[XDATA] to set indicating we can write more data 591 // Wait for McASP XSTAT[XDATA] to set indicating we can write more data
568 MCASP_WAIT_XSTAT: 592 MCASP_WAIT_XSTAT:
569 LBBO r2, reg_mcasp_addr, MCASP_XSTAT, 4 593 LBBO r2, reg_mcasp_addr, MCASP_XSTAT, 4
570 QBBC MCASP_WAIT_XSTAT, r2, MCASP_XSTAT_XDATA_BIT 594 QBBC MCASP_WAIT_XSTAT, r2, MCASP_XSTAT_XDATA_BIT
571 595
572 MCASP_REG_WRITE_EXT MCASP_XBUF, r7 596 MCASP_REG_WRITE_EXT MCASP_XBUF, r7
573 597
574 // Same idea with ADC: even iterations, load the sample into the low word, odd 598 // Same idea with ADC: even iterations, load the sample into the low word, odd
575 // iterations, load the sample into the high word and store 599 // iterations, load the sample into the high word and store
576 QBBS MCASP_ADC_HIGH_WORD, r1, 1 600 // QBBS MCASP_ADC_HIGH_WORD, r1, 1
601 QBBS MCASP_ADC_HIGH_WORD, reg_flags, FLAG_BIT_MCASP_HWORD
577 MCASP_ADC_LOW_WORD: 602 MCASP_ADC_LOW_WORD:
578 // Start ADC data at 0 603 // Start ADC data at 0
579 LDI reg_mcasp_adc_data, 0 604 LDI reg_mcasp_adc_data, 0
580 605
581 // Now wait for a received word to become available from the audio ADC 606 // Now wait for a received word to become available from the audio ADC
616 OR r7, r7, r8 641 OR r7, r7, r8
617 DAC_WRITE r7 642 DAC_WRITE r7
618 643
619 // Read ADC channels: result is always 2 commands behind 644 // Read ADC channels: result is always 2 commands behind
620 // Start by reading channel 2 (result is channel 0) and go 645 // Start by reading channel 2 (result is channel 0) and go
621 // to 10, but masking the channel number to be between 0 and 7 646 // to N+2, but masking the channel number to be between 0 and N-1
622 LDI reg_adc_data, 0 647 LDI reg_adc_data, 0
648 ADD r8, r1, 2
649 SUB r7, reg_num_channels, 1
650 AND r8, r8, r7
651 LSL r8, r8, AD7699_CHANNEL_OFFSET
623 MOV r7, AD7699_CFG_MASK 652 MOV r7, AD7699_CFG_MASK
624 ADD r8, r1, 2
625 AND r8, r8, 7
626 LSL r8, r8, AD7699_CHANNEL_OFFSET
627 OR r7, r7, r8 653 OR r7, r7, r8
628 ADC_WRITE r7, r7 654 ADC_WRITE r7, r7
629 655
630 // Mask out only the relevant 16 bits and store in reg_adc_data 656 // Mask out only the relevant 16 bits and store in reg_adc_data
631 MOV r2, 0xFFFF 657 MOV r2, 0xFFFF
643 OR r7, r7, r8 669 OR r7, r7, r8
644 DAC_WRITE r7 670 DAC_WRITE r7
645 671
646 // Read ADC channels: result is always 2 commands behind 672 // Read ADC channels: result is always 2 commands behind
647 // Start by reading channel 2 (result is channel 0) and go 673 // Start by reading channel 2 (result is channel 0) and go
648 // to 10, but masking the channel number to be between 0 and 7 674 // to N+2, but masking the channel number to be between 0 and N-1
675 LDI reg_adc_data, 0
676 ADD r8, r1, 2
677 SUB r7, reg_num_channels, 1
678 AND r8, r8, r7
679 LSL r8, r8, AD7699_CHANNEL_OFFSET
649 MOV r7, AD7699_CFG_MASK 680 MOV r7, AD7699_CFG_MASK
650 ADD r8, r1, 2
651 AND r8, r8, 7
652 LSL r8, r8, AD7699_CHANNEL_OFFSET
653 OR r7, r7, r8 681 OR r7, r7, r8
654 ADC_WRITE r7, r7 682 ADC_WRITE r7, r7
655 683
656 // Move this result up to the 16 high bits 684 // Move this result up to the 16 high bits
657 LSL r7, r7, 16 685 LSL r7, r7, 16
659 687
660 // Store 2 ADC words in memory 688 // Store 2 ADC words in memory
661 SBCO reg_adc_data, C_ADC_DAC_MEM, reg_adc_current, 4 689 SBCO reg_adc_data, C_ADC_DAC_MEM, reg_adc_current, 4
662 ADD reg_adc_current, reg_adc_current, 4 690 ADD reg_adc_current, reg_adc_current, 4
663 691
664 // Repeat 4 times (2 samples per loop, r1 += 1 already happened) 692 // Toggle the high/low word for McASP control (since we send one word out of
693 // 32 bits for each pair of SPI channels)
694 XOR reg_flags, reg_flags, (1 << FLAG_BIT_MCASP_HWORD)
695
696 // Repeat 4 times for 8 channels (2 samples per loop, r1 += 1 already happened)
697 // For 4 or 2 channels, repeat 2 or 1 times, according to flags
665 ADD r1, r1, 1 698 ADD r1, r1, 1
666 QBNE ADC_DAC_LOOP, r1, 8 699 QBNE ADC_DAC_LOOP, r1, reg_num_channels
667 QBA ADC_DAC_LOOP_DONE 700 QBA ADC_DAC_LOOP_DONE
668 701
669 SPI_SKIP_WRITE: 702 SPI_SKIP_WRITE:
670 // We get here only if the SPI ADC and DAC are disabled 703 // We get here only if the SPI ADC and DAC are disabled
671 // Just keep the loop going for McASP 704 // Just keep the loop going for McASP
705
706 // Toggle the high/low word for McASP control (since we send one word out of
707 // 32 bits for each pair of SPI channels)
708 XOR reg_flags, reg_flags, (1 << FLAG_BIT_MCASP_HWORD)
709
672 ADD r1, r1, 2 710 ADD r1, r1, 2
673 QBNE ADC_DAC_LOOP, r1, 8 711 QBNE ADC_DAC_LOOP, r1, reg_num_channels
674 712
675 ADC_DAC_LOOP_DONE: 713 ADC_DAC_LOOP_DONE:
676 // Increment number of frames, see if we have more to write 714 // Increment number of frames, see if we have more to write
677 ADD reg_frame_current, reg_frame_current, 1 715 ADD reg_frame_current, reg_frame_current, 1
678 QBNE WRITE_LOOP, reg_frame_current, reg_frame_total 716 QBNE WRITE_LOOP, reg_frame_current, reg_frame_total