PDA

View Full Version : Assembly Counter Square Wave gen and edge read



electric550
07-17-2009, 02:16 PM
So I wrote some code to see if my prop with an 8MHz and PLLX 16 crystal could output a 4MHz square wave from one pin to another then read it in with a counter in a different cog. The program was supposed to output 4000000 from the serial port if everything was working properly but it is not, I just get a bunch of letters....they do look consistent but... I am tired, and I can't figure out whats wrong with the code yet, so I figured I would see if anyone could see what was wrong. Any help is appreciated thanks!
I am sure will love the comments...Which might be wrong...just my thoughts on what is going on. Thanks again.





'This program is supposed to output 4MHz from pin 19 through a wire to pin 18
CON
_clkmode = xtal1 + pll16x
_xinfreq = 8_000_000

OBJ

serial : "fullduplexserialplus"

Var
long FourMHzGeneratorShare1 'This variable is used to pass the desired square wave frequency to the assembly routine
long FourMHzReaderShare1 'This variable is used to return the measured frequency from the assembly routine back to spin to send out serially to the terminal
Long Time 'Delay for Serial UpdateLOOP


Pub main

'Launch cogs to test the ability of Prop to generate and read 4 MHz square wave using counters @ 8MHz X 16

FourMHzGeneratorShare1 := 134217728 'This Value is used to generate the 4MHz square wave that is desired from formula on P137 PeLabsFunbook
cognew(@FourMHzGenerator,@FourMHzGeneratorShare1)' Start Cog to generate 4 MHz Square Wave, Also Pass in FourMHZGeneratorShare1 to share address of frequency value with assembly
cognew(@FourMHzReader,@FourMHzReaderShare1) 'Start Cog to Read Square Wave using counterA edge detection, Also Pass in FourMHzReaderShare1 to share value with spin
serial.start(31,30,0,1152000) 'Start Serial terminal to send back the value read by the counter use tx and RX pins that are connected to USB

repeat 'Repeatedly send the counted value out the serial port

serial.dec(FourMHzReaderShare1) 'FourMHzReaderShare1 is the variable that reads the value from the memory address of the frequency value returned by the counting Cog
waitcnt(Time += 1000000) '!!!THIS IS NOT PRINTing out 4million like I was hopeing:(

DAT
'-----------------------FourMHzGenerator------------------Derived from spin version from PElabFunbook v1.1 Page 140
org 0 'Begin at Cog RAM addr 0
FourMHzGenerator 'begining of 4Mhz Generator Assembly Routine
mov G0, Par 'Mov the hub address at which the desired frequency is stored from par into G0, Par comes from the second value that is passed in on Cog Init
rdlong FO, G0 'Reads the value from hub memory location for desired oscillator Frequency and puts the long value in FO
or dira, Pin19out 'Set Pin 19 to be an output, for the square wave generator output
mov ctra, CtraNCO 'set CounterA to NCO/PWM single-ended MOVI controls pins Page 207 PM
mov frqa, FO 'Pass in the Frequency to generate 4MHz from calculation from page 137 in FunBook


:LoopGen 'Infinite loop to continuously generate 4MHz square wave
jmp #:LoopGen 'Continue to loop the 4Mhz Square Wave

FIT
'---------------------FourMHzReader-----------------------------------------------------------------
org 0 'Begin at Cog RAM addr 0
FourMHzReader mov G1, PAR 'First Line of FourMHzReader, Pass Global address int G0 from Par for Sharing Later P283
and dira, Pin18in 'Make Pin 18 an input
mov ctra, CtraNegEdge 'CounterA to NegEDGE detector, PLL divide by 1, Pin 18 as input Page10 Prop Data sheet

mov frqa, #1 'Start counting clock edges in increments of one
:LoopReader mov phsa, #0 'Make sure clock tick accumulator starts at zero before looping
mov R0, SecDelay 'store value to create a one second delay into R0 4cycles per instruction 128MHz 128/4 = 32M cycles
:Delay1s DJNZ R0, #:Delay1s 'loop onto itself untill 32M has decrimented to 0 then fall through this should take approximately one second
mov FV, phsa 'move the accumulated clock ticks into FV
wrLong FV, G1 'Move FV value to Shared Memory Global mem assembly commands are backward
jmp #:LoopReader 'Jmp back to LoopReader to continue to measure the frequency


FIT

'Declare Temporary and Specialized Variable for Assembly Code
'R stands for register...similar to 8051 temporary registers
R0 res 1
R1 res 1
R2 res 1
'G stands for Global....This variable holds the address for global memory sharing
G0 res 1 'G0 is used to pass in the hub address that contains the desired frequency of oscillation into the assembly program
G1 res 1 'G1 is used to pass in the hub address to the pasm routine that will hold the measured frquency Value later the address is used to write the value to hub memory
'Below are specializer variables
FO res 1 'Frequency of Oscillation Value read from hub memory that sets the speed of the assemly routine square wave generator
FV res 1 'Frequency Value Returned from the counting assembly routine to the hub memory
'These values are for masking
Pin19out long %00000000_00000001_00000000_00000000
CtraNCO long %00010011_10000000_00000000_00010011
Pin18in long %11111111_11111111_01111111_11111111
CtraNegEdge long %00111011_10000000_00000000_00010010
'This is the value for looping
SecDelay long 32_000_000

Timmoore
07-17-2009, 02:27 PM
res must be after everything else in a cog - the longs in your case.

I am not sure how the asm variables will work with the 2 cogs the offsets are goign to be different for the 2 cogs. I think you need to split the variables and put them before the fit of each cog.

ericball
07-20-2009, 07:55 PM
First, RES must be the last entries in a cog routine.· RES is just a way to set a register # for a label without using any HUB RAM to do so.· Note - it will not be initialized and should not be accessed from SPIN code.

Second, any labels used in a cog routine must be before the next ORG (since the ORG resets the register #).



DAT
'-----------------------FourMHzGenerator------------------Derived from spin version from PElabFunbook v1.1 Page 140
org 0 'Begin at Cog RAM addr 0
FourMHzGenerator 'begining of 4Mhz Generator Assembly Routine
rdlong FRQA, PAR 'Reads the value from hub memory location for desired oscillator Frequency and puts the long value in FO
or dira, Pin19out 'Set Pin 19 to be an output, for the square wave generator output
mov ctra, CtraNCO 'set CounterA to NCO/PWM single-ended MOVI controls pins Page 207 PM
:LoopGen 'Infinite loop to continuously generate 4MHz square wave
jmp #:LoopGen 'Continue to loop the 4Mhz Square Wave
Pin19out long 1<<19
CtraNCO long %00100<<26+19
FIT
'---------------------FourMHzReader-----------------------------------------------------------------
org 0 'Begin at Cog RAM addr 0
FourMHzReader
andn dira, Pin18in 'Make Pin 18 an input
mov ctra, CtraNegEdge 'CounterA to NegEDGE detector, PLL divide by 1, Pin 18 as input Page10 Prop Data sheet

mov frqa, #1 'Start counting clock edges in increments of one
:LoopReader mov phsa, #0 'Make sure clock tick accumulator starts at zero before looping
mov R0, SecDelay 'store value to create a one second delay into R0 4cycles per instruction 128MHz 128/4 = 32M cycles
:Delay1s DJNZ R0, #:Delay1s 'loop onto itself untill 32M has decrimented to 0 then fall through this should take approximately one second
wrLong PHSA, PAR 'Move the accumulated clock ticks to Shared Memory Global mem assembly commands are backward
jmp #:LoopReader 'Jmp back to LoopReader to continue to measure the frequency
SecDelay long 32_000_000
Pin18in long 1<<18
CtraNegEdge long %01110<<26+18
R0 res 1
FIT

I have made some slight changes to remove unnecessary temporary variables and improve readability.· (Note: I don't think you had your pins set correctly.· I have matched the comments, not the values.)· You could, arguably, replace the MOV CTRA with MOVI CTRA, #CTRMODE·+ MOVS CTRA, #APIN for greater readability & no increase in code size.



▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Composite NTSC sprite driver: Forum (http://forums.parallax.com/showthread.php?p=800114)
NTSC & PAL driver templates: ObEx (http://obex.parallax.com/objects/483/) Forum (http://forums.parallax.com/showthread.php?p=803904)
OnePinTVText driver: ObEx (http://obex.parallax.com/objects/480/) Forum (http://forums.parallax.com/showthread.php?p=822453)

electric550
07-23-2009, 09:48 AM
Thanks I will have to give this a try! Oh and I ended up writting some code to test the counters with 8 Mhz clock and the counters seem to operate. I have not checked how accurately but the led blinkss welll.. Anyways I will check this code out and see how it goes.
Thanks again!

hinv
07-23-2009, 11:00 AM
That(the overclocking) was my first guess, without actually looking at the code. You might want to look at the posts bySapieha that describe the need for decoupling capacitors to handle the transient spikes, which will be much different in a visually perceivable LED blink.
Here it is http://forums.parallax.com/forums/default.aspx?f=25&m=361627