Run microphone_to_headphone in two (2) cogs
stephenwagner
Posts: 147
I woukld like to run the microphone to headphone in two cogs on the demo board. I understand I will need to adjust the I/O pins, duty differential to single end DAC and provide two inputs using resistors and capacitors. I am still having trouble with the Prop Spin syntax. The purpose is to pass a 10 bit stereo signal through the propeller. I understand I may have issues with lead length at the ADC inputs. I have managed to do line level audio with one input successfully.
Comments
You essentially have to duplicate the single channel ADC and DAC on another set of I/O pins, then duplicate the assembly code that does the work and substitute the 2nd set of I/O pin numbers and bit masks for the 1st channel's and start both copies.
Lead length is very important for good results. 10-bit accuracy is difficult to achieve with any technique. Don't count on being able to get anywhere near that. Lead length and noise become very significant, even lead length and noise on the chip itself. EFX-TEK's new AP-16+ audio player uses specific I/O pins for audio output to minimize these effects.
If you're having trouble with Spin syntax and understanding Spin, spend some time going through the Propeller Education Kit's tutorials. They'll be helpful with some basic concepts.
I am having problems with the Spin syntax. I also understand the limitation of the ADC on the demo board. The point is to get the code to work and then reduce the hardware down to SMT technology. The hardware technology I have access to.
Here is my first attempt at the code as best I understand it.
CON
_clkmode = xtal1 + pll16x
_xinfreq = 5_000_000
' At 80MHz the ADC/DAC sample resolutions and rates are as follows:
'
' sample sample
' bits rate
'
' 5 2.5 MHz
' 6 1.25 MHz
' 7 625 KHz
' 8 313 KHz
' 9 156 KHz
' 10 78 KHz
' 11 39 KHz
' 12 19.5 KHz
' 13 9.77 KHz
' 14 4.88 KHz
bits1 = 10 'try different values from table here
bits2=10
PUB go
cognew(@asm_entry1, 0) 'launch assembly program into a COG
cognew(@asm_entry2, 10
DAT
'
'
' Assembly program
'
org
asm_entry1 mov dira,asm_dira1 'make pins 8 (ADC) and 0 (DAC) outputs
movs ctra,#8 'POS W/FEEDBACK mode for CTRA
movd ctra,#9
movi ctra,#%01001_000
mov frqa,#1
movs ctrb,#10 'DUTY DIFFERENTIAL mode for CTRB
movd ctrb,#12
movi ctrb,#%00111_000
mov asm_cnt1,cnt 'prepare for WAITCNT loop
add asm_cnt1,asm_cycles1
:loop1 waitcnt asm_cnt1,asm_cycles1 'wait for next CNT value (timing is determinant after WAITCNT)
mov asm_sample1,phsa 'capture PHSA and get difference
sub asm_sample1,asm_old1
add asm_old1,asm_sample1
shl asm_sample1,#32-bits1 'justify sample and output to FRQB
mov frqb,asm_sample1
jmp #:loop1 'wait for next sample period
'
'
' Data
'
asm_cycles1 long |< bits1 - 1 'sample time
asm_dira1 long $00000E00 'output mask
asm_cnt1 res 1
asm_old1 res 1
asm_sample1 res 1
asm_entry2 mov dira,asm_dira2 'make pins 8 (ADC) and 0 (DAC) outputs
movs ctra,#6 'POS W/FEEDBACK mode for CTRA
movd ctra,#7
movi ctra,#%01001_000
mov frqa,#1
movs ctrb,#11 'DUTY DIFFERENTIAL mode for CTRB
movd ctrb,#13
movi ctrb,#%00111_000
mov asm_cnt2,cnt 'prepare for WAITCNT loop
add asm_cnt2,asm_cycles2
:loop2 waitcnt asm_cnt2,asm_cycles2 'wait for next CNT value (timing is determinant after WAITCNT)
mov asm_sample2,phsa 'capture PHSA and get difference
sub asm_sample2,asm_old2
add asm_old2,asm_sample2
shl asm_sample2,#32-bits2 'justify sample and output to FRQB
mov frqb,asm_sample2
jmp #:loop2 'wait for next sample period
'
'
' Data
'
asm_cycles2 long |< bits2 - 1 'sample time
asm_dira2 long $00000E00 'output mask
asm_cnt2 res 1
asm_old2 res 1
asm_sample2 res 1
Any help, pointers, references and or examples would be appreciated.
SJW
Second, start with the two "sticky threads" at the top of the Propeller Forum thread list. These are permanent threads that contain links to all sorts of "getting started" information. In particular, go through the Propeller Education Kit tutorials and DeSilva's threads on getting started with assembly language.
Remember that forums are not a very good structure for just posting a big hunk of code and asking for "help, pointers, references ...". It works best for specific questions. Sometimes it helps to post a hunk of code as an attachment, then asking specific questions about parts of that code. In your case, I would start with the monaural microphone to headphones demo, then add a 2nd copy of the assembly code, each assembly section having its own "DAT" and "ORG 0" statement. Change the pin numbers and I/O masks for the 2nd copy to match the I/O pins you're using and try them one at a time. First have the original COGNEW for the 1st assembly section, then change the COGNEW to use the 2nd copy and make sure it works. Then you can try using two COGNEW statements, one for each assembly section.
Thanks for the tips and the links to the sticky threads. I am having the hardest time understanding how inputs and outputs from methods, cogs and objects are passed around. I have a Demo Board, PE Kit text, Propeller Manual and Programming The Propeller with SPIN. I have two projects that I am working that involve audio delay: 1: Stereo image expander that I have completed. The summing work is done in the analog world, the delay is done in the propeller. I would like to make it all work in the Propeller. 2: A VOX where the mike is opened but the audio is delayed to the transmitter by 0.25 seconds. I see where the PackPack has an application with a keying circuit applicable to an FSR radio. I also found the Microphone to Headphone with Delay and Echo on this forum. I have my Sigma Delta ADCs working on the demo board. I used the tricks from the BackPack setting a pin high and or low to minimize my lead length at my summing junction. I understand the Demo Board audio output is limited to 1.59KHz. 10nF and 10Kohm. Its a good starting platform to work the software for my applications. As I work through my projects and questions surface, I can count on this forum for the necessary support.
SJW