Shop OBEX P1 Docs P2 Docs Learn Events
Goertzel Board Demo for P2 Rev B — Parallax Forums

Goertzel Board Demo for P2 Rev B

cgraceycgracey Posts: 14,153
edited 2019-11-19 21:11 in Propeller 2
Here is something to try out your P2 Eval RevB with the accessory boards. (Note that I'm using a RevA board, but I have a RevB glob-top chip installed.)

This demo uses the Goertzel board to input finger movements above its square pattern, then it outputs a 256-sample persistent trail via HDMI at 640x480.

The Goertzel board connects to P40..P47, while the HDMI board connects to P8..P15. Those placements can be changed in the top few lines of the source file:
'********************************************
'*  Use Goertzel board to drive HDMI board  *
'********************************************

CON		gtzl_base	= 48		'must be a multiple of 8
		hdmi_base	= 8		'must be a multiple of 8

		hdmi_color	= %110		'rgb enables for luma8 mode (%000 = orange)

		freq	= 250_000_000.0		'system clock frequency must be 250 MHz for HDMI
		buffer	= $400			'sample buffer start (1 KB)		
		bitmap	= $800			'bitmap buffer start (300 KB)

DAT		org

                hubset  ##%1_000001_0000011000_1111_10_00       'config PLL, 20MHz/2*25*1 = 250MHz
                waitx   ##20_000_000 / 200                      'allow crystal+PLL 5ms to stabilize
                hubset  ##%1_000001_0000011000_1111_10_11       'switch to PLL

		setq	##($7FFFF - @end_of_pgm)/4		'clear hub RAM
		wrlong	#0,##@end_of_pgm

		coginit	#1,##@pgm_gtzl		'launch Goertzel
		coginit	#0,##@pgm_hdmi		'launch HDMI


'**************
'*  Goertzel  *
'**************

CON		gtzl_freq	= 1_200_000.0	'goertzel frequency is multiple of both 50 and 60 Hz
		cycles		= 1200		'number of cycles to measure
		shifts		= 12		'right-shifts for acc's


DAT		org

pgm_gtzl	wrpin	adcmode,#gtzl_base+7	'init ADC pin

		cogid	x			'init DAC pins for this cog's DAC channels
		setnib	dacmode,x,#2
		wrpin	dacmode,#3<<6+gtzl_base
		dirh	#3<<6+gtzl_base

		setxfrq	xfreq			'set streamer NCO frequency

		mov	ptra,##buffer
		rdfast	#$100*2*2/64,ptra	'set rdfast to wrap of $100-sample circular buffer of (x,y) words

' Make sine and cosine tables in LUT bytes 3 and 2

		mov	z,#$1FF			'make 512-sample sin/cos table in LUT
sincos		shl	z,#32-9			'get angle into top 9 bits of z
		qrotate	#127,z			'rotate (127,0) by z
		shr	z,#32-9			'restore z
		getqx	x			'get x
		getqy	y			'get y
		rolbyte	y,x,#0			'make 0:0:y:x
		rolword	y,y,#0			'make y:x:y:x
		wrlut	y,z			'write sin:cos:sin:cos into LUT
		djnf	z,#sincos		'loop until 512 samples

' Take Goertzel measurements and plot in bitmap

loop		xcont	dds_d,dds_s		'issue Goertzel command
		getxacc	x			'get prior Goertzel acc's, cos first
		mov	y,0			'..then sin

		cmpsub	calwait,#1	wc	'initially calibrate
	if_c	mov	xcal,x
	if_c	mov	ycal,y

		sub	x,xcal			'get calibrated/shifted x
		sar	x,#shifts

		sub	y,ycal			'get calibrated/shifted y
		sar	y,#shifts

		add	x,#640/2		'constrain x to 0..639
		fges	x,#0
		fles	x,##640-1

		add	y,#480/2		'constrain y to 0..479
		fges	y,#0
		fles	y,#480-1

		wrword	x,ptra++		'enter (x,y) into circular buffer
		wrword	y,ptra++
		cmp	ptra,##buffer+$400 wz
	if_z	mov	ptra,##buffer

		rflong	z			'skip over new (x,y), so it gets plotted last

		mov	z,#0			'plot oldest to newest sample into bitmap, dark to light
plot		rfword	x			'get (x,y) sample from circular buffer
		rfword	y
		mul	y,##640			'get pixel address into y
		add	y,##bitmap + 640-1
		sub	y,x
		wrbyte	z,y			'plot pixel (z is the intensity 0..$FF)
		incmod	z,#$FF		wc
	if_nc	jmp	#plot

		jmp	#loop			'loop

' Data

adcmode		long	%0000_0000_000_100111_0000000_00_00000_0		'ADC mode
dacmode		long	%0000_0000_000_10110_00000000_01_00000_0		'DAC mode, cog DAC channels

xfreq		long	round(gtzl_freq/freq * 65536.0 * 32768.0)		'streamer frequency value

dds_d		long	%1111_1110_0000_1111<<16 + gtzl_base<<17 + cycles	'Goertzel mode, input from pin +4..7
dds_s		long	%0000_1000_000_000000000				'input from pin +3

calwait		long	100			'initial calibration cycles

x		res	1
y		res	1
z		res	1
xcal		res	1
ycal		res	1


'*********************************
'*  HDMI 640 x 480 x 8bpp luma8  *
'*********************************

DAT             org

pgm_hdmi        setcmod #$100                   'enable HDMI mode
                drvl    #7<<6 + hdmi_base       'enable HDMI pins
                wrpin   ##%001001<<8,#7<<6 + hdmi_base  'set 1 mA drive on HDMI pins

                setxfrq ##$0CCCCCCC+1           'set streamer freq to 1/10th clk (25 MHz)

                rdfast  ##640*480/64,##bitmap   'set rdfast to wrap on 300KB bitmap

' Field loop

field           mov     hsync0,sync_000         'vsync off
                mov     hsync1,sync_001

                callpa  #10,#blank              'top blanks

                mov     i,#480                  'set visible lines
line            call    #hsync                  'do horizontal sync
                xcont   m_rf,#hdmi_color        'do visible line
                djnz    i,#line                 'another line?

                callpa  #33,#blank              'bottom blanks

                mov     hsync0,sync_222         'vsync on
                mov     hsync1,sync_223

                callpa  #2,#blank               'vertical sync blanks

                jmp     #field                  'loop

' Subroutines

blank           call    #hsync                  'blank lines
                xcont   m_vi,hsync0
        _ret_   djnz    pa,#blank

hsync           xcont   m_bs,hsync0             'horizontal sync
                xzero   m_sn,hsync1
        _ret_   xcont   m_bv,hsync0

' Data

sync_000        long    %1101010100_1101010100_1101010100_10    '
sync_001        long    %1101010100_1101010100_0010101011_10    '        hsync
sync_222        long    %0101010100_0101010100_0101010100_10    'vsync
sync_223        long    %0101010100_0101010100_1010101011_10    'vsync + hsync

m_bs            long    $70810000 + hdmi_base<<17 + 16          'before sync
m_sn            long    $70810000 + hdmi_base<<17 + 96          'sync
m_bv            long    $70810000 + hdmi_base<<17 + 48          'before visible
m_vi            long    $70810000 + hdmi_base<<17 + 640         'visible
m_rf            long    $B0820000 + hdmi_base<<17 + 640         'visible rfbyte luma8

i               res     1
hsync0          res     1
hsync1          res     1

end_of_pgm

I think the Goertzel board's square pattern needs to be modified to be circular, since it couples unevenly and is very persnickety.

Here is a video of it operating and a picture of the setup:

Comments

  • Jeff MartinJeff Martin Posts: 758
    edited 2019-11-19 13:52
    It works on my PS-ES Rev B too.

    Currently I have it connected to my monitor through a DVI connection. The monitor has a hard time syncing to the signal; random horizontal red lines, alternating vertical dark/red bars, and blank-then-resync.

    735 x 443 - 34K
  • Ahle2Ahle2 Posts: 1,179
    Sadly, my Samsung Syncmaster F2380 doesn't seem to like the signal at all and is completely blank. I tried Raymans modified HDMI code (based on Chips code) and it is blank as well.

    Rogloh, when will you release your driver?
  • @Ahle2, I've answered in my other thread.
  • Ahle2Ahle2 Posts: 1,179
    Okey, I will wait then! :smile:
  • I forgot to set my VIO to 5V. Darn, that didn't solve it.

    Here's my results:
    * LG DVI monitor - Works, but red horizontal lines (random) and vertical alternating red/black bars plus sync problems (blanks, then reappears)
    * Phillips HDTV - Just blank screen
    * Vizio HTDT - Works pretty well; very rare horizontal red lines
  • cgraceycgracey Posts: 14,153
    edited 2019-11-19 16:34
    Maybe comment out this line:
    wrpin   ##%100100<<8,#7<<6 + hdmi_base  'set 1 mA drive on HDMI pins
    

    I don't know if my numbers of pre- and post-visible blank lines are correct, either.

    You should see just one little cyan squiggle that moves around with your finger.
  • Ahle2Ahle2 Posts: 1,179
    edited 2019-11-19 17:36
    Chip,

    It works when I uncomment that line. It seems 1mA is not enough to drive my monitor. When I run without that line my other DVI input stops working.
    I changed the smartpin mode to "1.5 kohm" and now I can see the picture AND use my other DVI input at the same time... :)
  • RaymanRayman Posts: 14,646
    It probably doesn't matter, but I think this:
    callpa  #25,#blank              'top blanks
    
    should be this:
    callpa  #10,#blank              'top blanks
    

    and this:
    callpa  #18,#blank              'bottom blanks
    
    should be this:
    callpa  #33,#blank              'bottom blanks
    

    I say it might not matter because I have these wrong in a code I posted (HDMI_Test1c) and it worked anyway...
  • cgraceycgracey Posts: 14,153
    Ahle2 wrote: »
    Chip,

    It works when I uncomment that line. It seems 1mA is not enough to drive my monitor. When I run without that line my other DVI input stops working.
    I changed the smartpin mode to "1.5 kohm" and now I can see the picture AND use my other DVI input at the same time... :)

    It might also be that the current steering is too slow to change states much in 4ns. I was kind of surprised it worked. The resistive drive mode is much faster. We could also use the bit DAC mode.
  • cgraceycgracey Posts: 14,153
    Rayman wrote: »
    It probably doesn't matter, but I think this:
    callpa  #25,#blank              'top blanks
    
    should be this:
    callpa  #10,#blank              'top blanks
    

    and this:
    callpa  #18,#blank              'bottom blanks
    
    should be this:
    callpa  #33,#blank              'bottom blanks
    

    I say it might not matter because I have these wrong in a code I posted (HDMI_Test1c) and it worked anyway...

    Thanks. I changed the code in the top post to reflect this. I also changed 1mA drive to 1k-ohm drive.
  • RaymanRayman Posts: 14,646
    I just tried on my board and seems to work...
    Just changed hdmi base to 48 and gtzl base to 0.

    It seems very sensitive, will probably take some training to control with precision...
    It is very neat though.
  • The latest code in the first post now works great for me on my DVI monitor. I'll try again with other displays when I can.
  • I'll try this with our TCL too that used to give trouble. It would be neat if this is all thats wrong
  • cgraceycgracey Posts: 14,153
    Rayman wrote: »
    I just tried on my board and seems to work...
    Just changed hdmi base to 48 and gtzl base to 0.

    It seems very sensitive, will probably take some training to control with precision...
    It is very neat though.

    We need more of a four-piece-annular-ring approach, instead of the big four-piece square.
  • cgracey wrote: »
    It might also be that the current steering is too slow to change states much in 4ns. I was kind of surprised it worked. The resistive drive mode is much faster. We could also use the bit DAC mode.

    It will be good for us to learn the best/safest setting to use for DVI/HDMI signalling levels. I had troubles with your earlier BIT DAC settings Chip and in my testing simply disabled this line below and ran directly at 3.3V, but I'm not sure that is advisable. I wonder what I should use in the driver? When I did some quick computation it seemed the current levels would be pretty low compared to what CML would normally drive but perhaps the differential signal swing is more important anyway.

    I'd quite like to know what to put in the code I hope to release today...

    ' wrpin ##%10110_0011_0000_10_00000_0, a '123 ohm BITDAC for pins
  • potatoheadpotatohead Posts: 10,261
    edited 2019-11-20 05:44
    Tektronix has this to say about it in the documentation for their spiffy HDMI compliance scope.

    Typed in from the PDF, which I will link below ----

    Minimum differential voltage swings are 150mV

    A TDMS signal generator with the ability to change amplitude is employed for this test. Any Sink-supported 27 MHz video format is generated that repeats the RGB gray ramp signals from 0 to 255 during each video period.

    Testing starts from 170MV Vdiff on all pairs and the differential swing is reduced in steps of 20MV until the Sink device reports error. If the minimum Vdiff to which the Sink responds without error is < 150mV, the device has passed the test. The Test stops when minimum Vdiff reaches 70mV.

    Another important element of this test is that it is performed at two different Vicm (common-mode voltage) settings, which are 3.0 and 3.3V. The CTS ask for the signal to be tested with a differential swing of 1.2V.

    [later]

    4. Differential Impedance
    Differential transmission lines used in achieving fast data rates are very sensitive to impedance matching. Consequently, impedance characterization is a very crucial test in compliance testing of HDMI. The through-connection impedance has a limit of 15% variance to its 100 Ω specification. The impedance at termination needs to be tighter as the margins are only 10% of its characteristic value of 100 Ω.

    This test is performed with the Sink device switched off. The measurement distance to DUT input connector is first measured. This is best determined using a TDR method where the impedance curve rises sharply to >200 ‰ denoting the distance to the connector.

    Next, differential impedance values, ZDIFF, are determined for each pair from the input connector until the point where the impedance curve stabilizes to termination impedance. The other non-tested pairs are terminated to 50 Ω. ZDIFF values should fall within 85 Ω to 115 Ω for a device to pass the test.

    https://download.tek.com/document/61W_17974_6_HR_Letter_0.pdf

  • Got this working with my Phillips 288P monitor, but the TCL still doesn't like it

    Put the goertzel board on base pin 48 to match what the code is (the photo below shows the goertzel board on a different base pin)
  • That is so amazing...I have no idea how that works. However, what happens if you use multiple fingers...will it track more than one object?
  • cgraceycgracey Posts: 14,153
    ti85 wrote: »
    That is so amazing...I have no idea how that works. However, what happens if you use multiple fingers...will it track more than one object?

    You would have to create an array of input nodes to discern multiple fingers. It can be done.
  • According to the DVI spec, red and green channels should only be sync0.
  • cgraceycgracey Posts: 14,153
    According to the DVI spec, red and green channels should only be sync0.

    That's good to know. Maybe that's why there's been some compatibility issues.
Sign In or Register to comment.