comparison pru_rtaudio.p @ 38:a9af130097e8 staging

GPIO pins are initialised as inputs by ARM to avoid spikes at startup, through gpio_set_dir. The buffers are set to 0x000ffff during initialisation. LastDigitalBuffer is initialized to 0x0000ffff.
author Giulio Moro <giuliomoro@yahoo.it>
date Tue, 12 May 2015 23:48:37 +0100
parents 6d64ee8c0754
children 638bc1ae2500
comparison
equal deleted inserted replaced
35:46571f8f04a1 38:a9af130097e8
180 // Flags for the flags register 180 // Flags for the flags register
181 #define FLAG_BIT_BUFFER1 0 181 #define FLAG_BIT_BUFFER1 0
182 #define FLAG_BIT_USE_SPI 1 182 #define FLAG_BIT_USE_SPI 1
183 #define FLAG_BIT_MCASP_HWORD 2 // Whether we are on the high word for McASP transmission 183 #define FLAG_BIT_MCASP_HWORD 2 // Whether we are on the high word for McASP transmission
184 #define FLAG_BIT_USE_DIGITAL 3 184 #define FLAG_BIT_USE_DIGITAL 3
185 /*#define FLAG_BIT_DIGITAL_BUFFER 4 //Whether we are using buffer located at
186 // 0: MEM_DIGITAL_BASE or
187 */ // 1: MEM_DIGITAL_BASE + 512
188 // Registers used throughout 185 // Registers used throughout
189 186
190 // r1, r2, r3 are used for temporary storage 187 // r1, r2, r3 are used for temporary storage
191 #define MEM_DIGITAL_BASE 0x11000 //Base address for DIGITAL : Shared RAM + 0x400 188 #define MEM_DIGITAL_BASE 0x11000 //Base address for DIGITAL : Shared RAM + 0x400
192 #define MEM_DIGITAL_BUFFER1_OFFSET 0x400 //Start pointer to DIGITAL_BUFFER1, which is 256 words after. 189 #define MEM_DIGITAL_BUFFER1_OFFSET 0x400 //Start pointer to DIGITAL_BUFFER1, which is 256 words after.
412 //regardless of whether the order is gpio1-gpio2 or gpio2-gpio1 409 //regardless of whether the order is gpio1-gpio2 or gpio2-gpio1
413 JMP r28.w0 // go back to ADC_WRITE_GPIO 410 JMP r28.w0 // go back to ADC_WRITE_GPIO
414 411
415 // DIGITAL new code ends here 412 // DIGITAL new code ends here
416 413
417 414
415 .macro HANG
416 DALOOP:
417 set r30.t14
418 clr r30.t14
419 QBA DALOOP
420 .endm
418 // Bring CS line low to write to DAC 421 // Bring CS line low to write to DAC
419 .macro DAC_CS_ASSERT 422 .macro DAC_CS_ASSERT
420 MOV r27, DAC_CS_PIN 423 MOV r27, DAC_CS_PIN
421 MOV r28, DAC_GPIO + GPIO_CLEARDATAOUT 424 MOV r28, DAC_GPIO + GPIO_CLEARDATAOUT
422 SBBO r27, r28, 0, 4 425 SBBO r27, r28, 0, 4
595 // Default number of channels in case SPI disabled 598 // Default number of channels in case SPI disabled
596 LDI reg_num_channels, 8 599 LDI reg_num_channels, 8
597 600
598 // Find out whether we should use DIGITAL 601 // Find out whether we should use DIGITAL
599 LBBO r2, reg_comm_addr, COMM_USE_DIGITAL, 4 602 LBBO r2, reg_comm_addr, COMM_USE_DIGITAL, 4
600 QBEQ DIGITAL_FLAG_CHECK_DONE, r2, 0 603 QBEQ DIGITAL_INIT_DONE, r2, 0 // if we use digital
601 SET reg_flags, reg_flags, FLAG_BIT_USE_DIGITAL 604 SET reg_flags, reg_flags, FLAG_BIT_USE_DIGITAL
602 // SET reg_flags, reg_flags, FLAG_BIT_DIGITAL_BUFFER //set the flag, so that in WRITE_ONE_BUFFER we will start from buffer0 605 /* This block of code is not really needed, as the memory is initialized by ARM before the PRU is started.
603 DIGITAL_FLAG_CHECK_DONE: 606 Will leave it here for future reference
607 DIGITAL_INIT: //set the digital buffer to 0x0000ffff (all inputs), to prevent unwanted high outputs
608 //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
609 MOV r2, 0x0000ffff //value to store. 0x0000ffff means all inputs
610 MOV r3, MEM_DIGITAL_BASE //start of the digital buffer
611 MOV r4, MEM_DIGITAL_BASE+2*MEM_DIGITAL_BUFFER1_OFFSET //end of the digital buffer
612 DIGITAL_INIT_BUFFER_LOOP:
613 SBBO r2, r3, 0, 4
614 ADD r3, r3, 4 //increment pointer
615 QBGT DIGITAL_INIT_BUFFER_LOOP, r3, r4 //loop until we reach the end of the buffer
616 */
617 DIGITAL_INIT_DONE:
604 // Find out whether we should use SPI ADC and DAC 618 // Find out whether we should use SPI ADC and DAC
605 LBBO r2, reg_comm_addr, COMM_USE_SPI, 4 619 LBBO r2, reg_comm_addr, COMM_USE_SPI, 4
606 QBEQ SPI_FLAG_CHECK_DONE, r2, 0 620 QBEQ SPI_FLAG_CHECK_DONE, r2, 0
607 SET reg_flags, reg_flags, FLAG_BIT_USE_SPI 621 SET reg_flags, reg_flags, FLAG_BIT_USE_SPI
608
609 SPI_FLAG_CHECK_DONE: 622 SPI_FLAG_CHECK_DONE:
610 // If we don't use SPI, then skip all this init 623 // If we don't use SPI, then skip all this init
611 QBBC SPI_INIT_DONE, reg_flags, FLAG_BIT_USE_SPI 624 QBBC SPI_INIT_DONE, reg_flags, FLAG_BIT_USE_SPI
612 625
613 // Load the number of channels: valid values are 8, 4 or 2 626 // Load the number of channels: valid values are 8, 4 or 2
747 760
748 MCASP_REG_SET_BIT_AND_POLL MCASP_RGBLCTL, (1 << 4) // Set RFRST 761 MCASP_REG_SET_BIT_AND_POLL MCASP_RGBLCTL, (1 << 4) // Set RFRST
749 MCASP_REG_SET_BIT_AND_POLL MCASP_XGBLCTL, (1 << 12) // Set XFRST 762 MCASP_REG_SET_BIT_AND_POLL MCASP_XGBLCTL, (1 << 12) // Set XFRST
750 763
751 // Initialisation 764 // Initialisation
752 LBBO reg_frame_total, reg_comm_addr, COMM_BUFFER_FRAMES, 4 // Total frame count (SPI; 0.5x-2x for McASP) 765 LBBO reg_frame_total, reg_comm_addr, COMM_BUFFER_FRAMES, 4 // Total frame count (SPI; 0.5x-2x for McASP)
753 MOV reg_dac_buf0, 0 // DAC buffer 0 start pointer 766 MOV reg_dac_buf0, 0 // DAC buffer 0 start pointer
754 LSL reg_dac_buf1, reg_frame_total, 1 // DAC buffer 1 start pointer = N[ch]*2[bytes]*bufsize 767 LSL reg_dac_buf1, reg_frame_total, 1 // DAC buffer 1 start pointer = N[ch]*2[bytes]*bufsize
755 LMBD r2, reg_num_channels, 1 // Returns 1, 2 or 3 depending on the number of channels 768 LMBD r2, reg_num_channels, 1 // Returns 1, 2 or 3 depending on the number of channels
756 LSL reg_dac_buf1, reg_dac_buf1, r2 // Multiply by 2, 4 or 8 to get the N[ch] scaling above 769 LSL reg_dac_buf1, reg_dac_buf1, r2 // Multiply by 2, 4 or 8 to get the N[ch] scaling above
757 MOV reg_mcasp_buf0, 0 // McASP DAC buffer 0 start pointer 770 MOV reg_mcasp_buf0, 0 // McASP DAC buffer 0 start pointer
758 LSL reg_mcasp_buf1, reg_frame_total, r2 // McASP DAC buffer 1 start pointer = 2[ch]*2[bytes]*(N/4)[samples/spi]*bufsize 771 LSL reg_mcasp_buf1, reg_frame_total, r2 // McASP DAC buffer 1 start pointer = 2[ch]*2[bytes]*(N/4)[samples/spi]*bufsize
759 CLR reg_flags, reg_flags, FLAG_BIT_BUFFER1 // Bit 0 holds which buffer we are on 772 CLR reg_flags, reg_flags, FLAG_BIT_BUFFER1 // Bit 0 holds which buffer we are on
760 MOV r2, 0 773 MOV r2, 0
761 SBBO r2, reg_comm_addr, COMM_FRAME_COUNT, 4 // Start with frame count of 0 774 SBBO r2, reg_comm_addr, COMM_FRAME_COUNT, 4 // Start with frame count of 0
762 775 /* This block of code is not really needed, as the memory is initialized by ARM before the PRU is started.
776 Will leave it here for future reference
777 //Initialise all SPI and audio buffers (DAC0, DAC1, ADC0, ADC1) to zero.
778 //This is useful for analog outs so they do not have spikes during the first buffer.
779 //This is not very useful for audio, as you still hear the initial "tumpf" when the converter starts
780 //and each sample in the DAC buffer is reset to 0 after it is written to the DAC.
781
782 QBBC SPI_INIT_BUFFER_DONE, reg_flags, FLAG_BIT_USE_SPI
783 //Initialize SPI buffers
784 //compute the memory offset of the end of the audio buffer and store it in r4
785 SUB r4, reg_dac_buf1, reg_dac_buf0 // length of the buffer, assumes reg_dac_buf1>ref_dac_buf0
786 LSL r4, r4, 2 //length of four buffers (DAC0, DAC1, ADC0, ADC1)
787 ADD r4, reg_dac_buf0, r4 //total offset
788 MOV r2, 0// value to store
789 MOV r3, 0 // offset counter
790 SPI_INIT_BUFFER_LOOP:
791 SBCO r2, C_ADC_DAC_MEM, r3, 4
792 ADD r3, r3, 4
793 QBGT SPI_INIT_BUFFER_LOOP, r3, r4
794 SPI_INIT_BUFFER_DONE:
795
796 //Initialize audio buffers
797 //compute the memory offset of the end of the audio buffer and store it in r4
798 SUB r4, reg_mcasp_buf1, reg_mcasp_buf0 // length of the buffer, assumes reg_mcasp_buf1>ref_mcasp_buf0
799 LSL r4, r4, 2 //length of four buffers (DAC0, DAC1, ADC0, ADC1)
800 ADD r4, reg_mcasp_buf0, r4 //total offset
801 MOV r2, 0 // value to store
802 MOV r3, 0 // offset counter
803 MCASP_INIT_BUFFER_LOOP:
804 SBCO r2, C_MCASP_MEM, r3, 4
805 ADD r3, r3, 4
806 QBGT MCASP_INIT_BUFFER_LOOP, r3, r4
807 */
763 // Here we are out of sync by one TDM slot since the 0 word transmitted above will have occupied 808 // Here we are out of sync by one TDM slot since the 0 word transmitted above will have occupied
764 // the first output slot. Send one more word before jumping into the loop. 809 // the first output slot. Send one more word before jumping into the loop.
765 MCASP_DAC_WAIT_BEFORE_LOOP: 810 MCASP_DAC_WAIT_BEFORE_LOOP:
766 LBBO r2, reg_mcasp_addr, MCASP_XSTAT, 4 811 LBBO r2, reg_mcasp_addr, MCASP_XSTAT, 4
767 QBBC MCASP_DAC_WAIT_BEFORE_LOOP, r2, MCASP_XSTAT_XDATA_BIT 812 QBBC MCASP_DAC_WAIT_BEFORE_LOOP, r2, MCASP_XSTAT_XDATA_BIT
776 QBBC MCASP_ADC_WAIT_BEFORE_LOOP, r2, MCASP_RSTAT_RDATA_BIT 821 QBBC MCASP_ADC_WAIT_BEFORE_LOOP, r2, MCASP_RSTAT_RDATA_BIT
777 822
778 MCASP_REG_READ_EXT MCASP_RBUF, r2 823 MCASP_REG_READ_EXT MCASP_RBUF, r2
779 824
780 WRITE_ONE_BUFFER: 825 WRITE_ONE_BUFFER:
826
781 // Write a single buffer of DAC samples and read a buffer of ADC samples 827 // Write a single buffer of DAC samples and read a buffer of ADC samples
782 // Load starting positions 828 // Load starting positions
783 MOV reg_dac_current, reg_dac_buf0 // DAC: reg_dac_current is current pointer 829 MOV reg_dac_current, reg_dac_buf0 // DAC: reg_dac_current is current pointer
784 LMBD r2, reg_num_channels, 1 // 1, 2 or 3 for 2, 4 or 8 channels 830 LMBD r2, reg_num_channels, 1 // 1, 2 or 3 for 2, 4 or 8 channels
785 LSL reg_adc_current, reg_frame_total, r2 831 LSL reg_adc_current, reg_frame_total, r2
790 LSL reg_mcasp_adc_current, reg_mcasp_adc_current, 1 836 LSL reg_mcasp_adc_current, reg_mcasp_adc_current, 1
791 ADC reg_mcasp_adc_current, reg_mcasp_adc_current, reg_mcasp_dac_current 837 ADC reg_mcasp_adc_current, reg_mcasp_adc_current, reg_mcasp_dac_current
792 MOV reg_frame_current, 0 838 MOV reg_frame_current, 0
793 QBBS DIGITAL_BASE_CHECK_SET, reg_flags, FLAG_BIT_BUFFER1 //check which buffer we are using for DIGITAL 839 QBBS DIGITAL_BASE_CHECK_SET, reg_flags, FLAG_BIT_BUFFER1 //check which buffer we are using for DIGITAL
794 // if we are here, we are using buffer0 840 // if we are here, we are using buffer0
795 MOV r2, 0 //so adjust offset appropriately 841 MOV reg_digital_current, MEM_DIGITAL_BASE
796 QBA DIGITAL_BASE_CHECK_DONE 842 QBA DIGITAL_BASE_CHECK_DONE
797 DIGITAL_BASE_CHECK_SET: //if we are here, we are using buffer1 843 DIGITAL_BASE_CHECK_SET: //if we are here, we are using buffer1
798 MOV r2, MEM_DIGITAL_BUFFER1_OFFSET //so adjust offset appropriately 844 MOV reg_digital_current, MEM_DIGITAL_BASE+MEM_DIGITAL_BUFFER1_OFFSET //so adjust offset appropriately
799 DIGITAL_BASE_CHECK_DONE: 845 DIGITAL_BASE_CHECK_DONE:
800 MOV reg_digital_current, MEM_DIGITAL_BASE
801 ADD reg_digital_current, reg_digital_current, r2
802 846
803 WRITE_LOOP: 847 WRITE_LOOP:
804 // Write N channels to DAC from successive values in memory 848 // Write N channels to DAC from successive values in memory
805 // At the same time, read N channels from ADC 849 // At the same time, read N channels from ADC
806 // Unrolled by a factor of 2 to get high and low words 850 // Unrolled by a factor of 2 to get high and low words
897 SUB r7, reg_num_channels, 1 941 SUB r7, reg_num_channels, 1
898 AND r8, r8, r7 942 AND r8, r8, r7
899 LSL r8, r8, AD7699_CHANNEL_OFFSET 943 LSL r8, r8, AD7699_CHANNEL_OFFSET
900 MOV r7, AD7699_CFG_MASK 944 MOV r7, AD7699_CFG_MASK
901 OR r7, r7, r8 945 OR r7, r7, r8
946
902 //ssssssssssssssssssssssssssss 947 //ssssssssssssssssssssssssssss
903 ADC_WRITE_GPIO r7, r7, r1 948 ADC_WRITE_GPIO r7, r7, r1
904 949
905 // Mask out only the relevant 16 bits and store in reg_adc_data 950 // Mask out only the relevant 16 bits and store in reg_adc_data
906 MOV r2, 0xFFFF 951 MOV r2, 0xFFFF