Mercurial > hg > beaglert
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 |