PRI vs PUB using Frequency Synthesizer object
My project uses two Props; Prop#1 generates a 5 MHz signal for Prop#2 X1 input.
Recently I cleaned up my sources and thought it would be better to have all the COGNEWs in PUB rather spread in both PRI and PUB the way it had grown. Made a number of 'small' changes to the source, actually for both Props, and then NOTHING worked.
Finally today I used a ProtoBoard rather than the 2 Prop pcb to scope if the FreqSynth worked on that board. NOPE. So tried it with Fsynth.synth moved after the first PRI. And then it worked. Yet FDS and Display (TV_text) worked OK in PUB.
Is there a rule for where cogs get init'ed? Wasted many man hours tracking why Prop#2 didn't work right. It received a 5 MHz timing from Prop#1 via Fsynth.
Nice to see things working properly again. But don't understand why it had to be this way. Can someone enlighten me?
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Harley Shanko
Recently I cleaned up my sources and thought it would be better to have all the COGNEWs in PUB rather spread in both PRI and PUB the way it had grown. Made a number of 'small' changes to the source, actually for both Props, and then NOTHING worked.
Finally today I used a ProtoBoard rather than the 2 Prop pcb to scope if the FreqSynth worked on that board. NOPE. So tried it with Fsynth.synth moved after the first PRI. And then it worked. Yet FDS and Display (TV_text) worked OK in PUB.
Is there a rule for where cogs get init'ed? Wasted many man hours tracking why Prop#2 didn't work right. It received a 5 MHz timing from Prop#1 via Fsynth.
Nice to see things working properly again. But don't understand why it had to be this way. Can someone enlighten me?
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Harley Shanko

Comments
'***************************** '* Control_2Prop1 v 0.1 * mod: 5:48 pm 10 Feb.2008 '* (C) 2007 h.a.s. designn * '***************************** ' Prop#1 connects to: a D/K board rx/tx pins, to a second Propeller via another pair ' of pins; both Props connect to a 'Pod' board; and displays debug info to a TV monitor. CON _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 Prop_Tx = 27 ' Prop1 data from Prop2 Prop_Rx = 26 ' Prop1 data to Prop2 Prop_Baud = 115200 ' for Prop1 <=> Prop2 communications PIC_Tx = 4 ' Data from D/K board PIC_Rx = 5 ' Data to D/K board PIC_Baud = 35714 ' D/K PIC16F871 with a 4 MHz xtal yields 35714 baud maskF0 = $000000F0 ' mask for upper nyble of a ls byte 'TV parameters ' (not enough pins left for VGA which uses 8 pins) #0, white, inverse, highlight, blue, magenta, green, orange, red ' text palette colors VAR long status, stack[noparse][[/noparse]50], rxpin, txpin, c, rxbyte, rxcheck, txbyte,frame[noparse][[/noparse]406] long addrReg, dataReg, statReg, keyReg, dirReg, id, LpTimer, SBPtReg, regReg long StatAsm, tempStat, tempLow, tempHigh, tempDat, CmdStatus, LEDreg, Prop2Reg word DisplayReg byte Lptest, key, CmdP2, INTRflg OBJ PICSer : "FullDuplexSerial" ' D/K comm PropSer : "FullDuplexSerial" ' Prop2 comm Display : "TV_text" ' debug w/monitor Fsynth : "Synth" ' for 5 MHz 'clock' for Prop#2 ' vp : "ViewportConduit_20" ' transfers data to/from PC - ver 2.0 ' vp : "ViewportConduit_12" ' transfers data to/from PC ' qs1 : "QuickSample_12" ' measures INA and variables, 1 cog ' dbg : "PASDebug" '<---- Add for PASD Debugger '************************************************************************************* '* Prop#1: - handles D/K, Prop#2, and p/o Pod i/f's, Command decoder, and 5 MHz synth clock '************************************************************************************* PUB Main PropSer.start(Prop_Rx, Prop_Tx, %0000, Prop_Baud) ' " Cog 1 PICSer.start(PIC_Rx, PIC_Tx, %0000, PIC_Baud) ' s/b Cog 2 Display.start(12) ' " Cog 3 ' Fsynth.synth("A", 24, 5_000_000) ' output 5MHz for Prop2; Cog 0 [b]AAA[/b] ' id := cognew(@DTbus,@StatAsm) ' this sets up the DTbus registers for the assembly cog ' id := cognew(@entry,@StatAsm) ' start cog for DTbus read/writes; Cog 4 PASD id := cognew(Control1,@stack) ' " Cog 5 ' id := dbg.start(31,30,@entry) ' " Cog 6; for PASD debugger' PRI Control1 Fsynth.synth("A", 24, 5_000_000) ' output 5MHz for Prop2; Cog 0 [b]BBB[/b] InitP1Can anyone explain why it shouldn't have worked at line marked AAA?
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Harley Shanko
That 'InitP1' is just a Call to a separate PRI for initialization of on-screen headings of Prop#1 and Prop#2 areas for the TV monitor debug screen.
This included communications to read and display version#, date and #cogs used by Prop#2. Each use about 1/2 of the screen. When the Fsynth wasn't working, Prop#2 wouldn't run therefore I had to temporariy comment out that communications source lines, so I could continue after hitting a brick wall on what wasn't working right. Had made too many changes at once and couldn't determine where all the problems were.
InitP1 begins with
Dispaysetcolors(@tv_palette)
Might that, setting the foreground/background colors table, have upset Fsynth?
Maybe it has more to do with being invoked after the
id := cognew(Control1,@stack) ' " Cog 5
line?
I'd like to know about this strange effect. I was dumbfounded when I moved the Fsynth init a few lines later and it worked; need to know the 'logic' behind this.
Thanks, anyone for clarification on this.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Harley Shanko
I was not able to locate somthing as "Synth", neither in the OBEX nor from this forum. May be Steven is right...
More likely you are shutting pin 24 dowm in your main COG after FSYNTH had been called. This will not disturb the COG5 you run CONTROL in, so it continues transmitting its signal...
The purpose of the 5 MHz signal is for 'clock' for Prop#2. I suppose I could generate it another way with less code, but probably still would need its own cog, no? Prop#1 uses a 5 MHz crystal, but over 3 inches from Prop#2 X1 pin. Are you implying the counter wouldn't have to be in another cog; that would be cool. Should be a square wave though.
@ deSilva
I've had 'Synth' for about 9 months. Don't recall if it came with the IDE originally, or ran across it elsewhere. But works well.
I'm constantly amazed how much Chip 'n crew incorporated in the Propeller. Looks like I need to reread that counter AN001 again (and again and again).
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Harley Shanko
Yes, I'd actually 'forgotten' about doing it that way. No timers used yet on this project (except for what Fsynth uses).
So much to learn, not enough time usually. LIFE!
Thank you deSilva and stevenmess2004.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Harley Shanko
·
Not sure why you are seeing this issue, but I suspect it's exactly what deSilva suggests... "More likely you are shutting pin 24 down in your main COG after FSYNTH had been called."
·
It's difficult to tell without all of your code (i.e. some of the OBJ definitions) to see what is happening.· The Synth.spin object is basically a passive object in that it uses the current COG it is called from and does not launch another COG.· So if another object does something similar and is also passive, it could be clobbering the CTR and FRQ settings.· Try using the Synth.spin object with the "B" counter rather than the "A" counter just to see if it might go away that way.
·
Object exchange Synth.spin reference:
http://obex.parallax.com/objects/47/
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Beau Schwabe
IC Layout Engineer
Parallax, Inc.
I'll try your suggestion. I'm also going to try using AN001 counter instead of Fsynth obj.
Hadn't looked into the counters except for scanning AN001 months ago. Lots available in just that part of the Propeller. Thanks for the suggestion.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Harley Shanko
If I put the Fsynth.synth("A", 24, 5_000_000) before the PRI it doesn't work, whether "A" or "B" is assigned.
But if after the PRI either "A" or "B" works.
To my knowledge I am not altering pin 33/A24 in the program in any manner either.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Harley Shanko
When you clear DIRA[noparse][[/noparse]24] "A" or "B" won't make any difference...
Before you post the complete code there is no chance to help you further. There just is a "bug" in your program.. somewhere
'***************************** '* Control_2Prop1 v 0.1 * mod: 9:15 am 14 Feb.2008 '* (C) 2007 h.a.s. designn * '***************************** ' Prop#1 connects to: a D/K board rx/tx pins, to a second Propeller via another pair ' of pins; both Props connect to a 'Pod' board; and displays debug info to a TV monitor. CON _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 Prop_Tx = 27 ' Prop1 data from Prop2 Prop_Rx = 26 ' Prop1 data to Prop2 Prop_Baud = 115200 ' for Prop1 <=> Prop2 communications PIC_Tx = 4 ' Data from D/K board PIC_Rx = 5 ' Data to D/K board PIC_Baud = 35714 ' D/K PIC16F871 with a 4 MHz xtal yields 35714 baud maskF0 = $000000F0 ' mask for upper nyble of a ls byte 'TV parameters ' (not enough pins left for VGA which uses 8 pins) #0, white, inverse, highlight, blue, magenta, green, orange, red ' text palette colors VAR long status, stack[noparse][[/noparse]50], rxpin, txpin, c, rxbyte, rxcheck, txbyte,frame[noparse][[/noparse]406] long addrReg, dataReg, statReg, keyReg, dirReg, id, LpTimer, SBPtReg, regReg long StatAsm, tempStat, tempLow, tempHigh, tempDat, CmdStatus, LEDreg, Prop2Reg word DisplayReg byte Lptest, key, CmdP2, INTRflg OBJ PICSer : "FullDuplexSerial" ' D/K comm PropSer : "FullDuplexSerial" ' Prop2 comm Display : "TV_text" ' debug w/monitor Fsynth : "Synth" ' for 5 MHz 'clock' for Prop#2 ' vp : "ViewportConduit_20" ' transfers data to/from PC - ver 2.0 ' vp : "ViewportConduit_12" ' transfers data to/from PC ' qs1 : "QuickSample_12" ' measures INA and variables, 1 cog ' dbg : "PASDebug" '<---- Add for PASD Debugger '************************************************************************************* '* Prop#1: - handles D/K, Prop#2, and p/o Pod i/f's, Command decoder, and 5 MHz synth clock '************************************************************************************* PUB Main PropSer.start(Prop_Rx, Prop_Tx, %0000, Prop_Baud) ' " Cog 1 PICSer.start(PIC_Rx, PIC_Tx, %0000, PIC_Baud) ' s/b Cog 2 Display.start(12) ' " Cog 3 ' Fsynth.synth("A", 24, 5_000_000) ' output 5MHz for Prop2; Cog 0 ' Fsynth.synth("B", 24, 5_000_000) ' output 5MHz for Prop2; Cog 0 ' id := cognew(@DTbus,@StatAsm) ' this sets up the DTbus registers for the assembly cog ' id := cognew(@entry,@StatAsm) ' start cog for DTbus read/writes; Cog 4 PASD id := cognew(Control1,@stack) ' " Cog 5 ' id := dbg.start(31,30,@entry) ' " Cog 6; for PASD debugger' ' Fsynth.synth("B", 24, 5_000_000) ' output 5MHz for Prop2; Cog 0 PRI Control1 Fsynth.synth("B", 24, 5_000_000) ' output 5MHz for Prop2; Cog 0 InitP1 ' vp.start(31,30,@rxpin,String("Control_2Prop1:50 ns/div:LSA:rxpin+,txpin+,c+,rxbyte+,rxcheck+,txbyte+,frame*+@0.7.0")) ' s/b Cog 6 ' Main Loop *********** deals with inputs from D/K, Prop#2 or Pod *********** repeat DKif P2if ' qs1.sampleINA(@frame) ' THIS, and next 2 lines, used with ViewPort ' rxpin++ ' txpin+=2 ' DIRA[noparse][[/noparse]8]~~ ' temp. 'pulser' (neg. ~8 microsec every ~80 microsec) ' OUTA[noparse][[/noparse]8]~ ' pulse Lo for ~ 8 microsec ' OUTA[noparse][[/noparse]8]~~ ' return to Hi level for ~ 80 microsec period if LpTimer == 0 ' test if times out; if so, reload value LpTimer := $2000 ' (maybe, 1 - 5 sec or min between Looptests) ??? Lptest++ ' increment each timeout if Lptest =< $70 ' ensure 'Lptest=' = 80h...FFh Lptest := $70 PICSer.tx(Lptest) ' send Lptest value to D/K LpTimer-- ' decrement timer each main loop pass ' gotoxy(20,11) ' THESE 3 lines for LoopTest: KEEP !! ' Display.str(string(" LpTmr.")) ' Display.hex(LpTimer,4) ' PropSer.tx($84) '************************************************************************************* PRI InitP1 ' Initialize Prop#1 display and comm Display.setcolors(@tv_palette) color(blue) ' color for Prop1 register heading gotoxy(2,0) Display.str(@titleP1) gotoxy(13,0) ' 11 positions + offset of 2 = 13 display.dec(CHIPVER) gotoxy(27,0) ' location for Prop#1 cog usage Display.str(@Cogs1) Display.dec(id + 1) '*** now read Prop#2 version and source file date color(red) ' color for Prop2 register heading gotoxy(2,7) repeat ' query Prop2's attention PropSer.tx($80) waitcnt(800000 + cnt) ' wait a moment for Prop#2 if (c := PropSer.rxcheck) <> -1 until c == $80 ' got back Prop#2 'echoed' $80 byte ' GetProp2info repeat while c <> $0D ' loop until Carriage Return seen if c <> $0D c := PropSer.rx Display.out(c) ' show received characters of string from Prop#2 gotoxy(37,7) ' location for Prop#2 cog usage repeat ' query Prop2's attention waitcnt(800000 + cnt) ' wait a moment for Prop#2 response until (c := PropSer.rxcheck) <> -1 ' wait until response Display.dec(c) ' show Prop#2 cog usage '*** done with Prop#2 'heading' color(white) ' white text for register name and values dirReg := 1 ' used to control addr/data for MEM(2), REG(3), others(1) DisplayRegs gotoxy(0,11) ' DISPLAYS VALUE SENT TO PROP2 'CntlFF' VARIABLE ' Display.str(string(" CmdP2.")) ' Display.hex(CmdP2,2) ' PropSer.tx(CmdP2) ' c := $11 ' DKif RegistersUpdate ' CommandDecoder '************************************************************************************* PRI DKif ' check for D/K transmissions (includes Loop test echos) if (c := PICSer.rxcheck) <> -1 ' process a byte from D/K key := c gotoxy(0,12) Display.hex(c,2) if key < $20 ' 00h..1Ch valid hex and command codes KeyDecode ' separate command from hex codes RegistersUpdate ' update first, before sending to D/K if key <> $13 ' for codes not $13 (Test key) TEMP ??? UpdateDK_LED ' output addr and data to D/K board if c => $70 ' cides $70 to $FF are for D/K looptest gotoxy(24,12) ' part of Looptest - displays PASS/FAIL if c == Lptest Display.str(string("Pass ")) ' show 'Pass' and Lptest value Display.hex(Lptest,2) Display.str(string(" ")) ' clears 'Fail' text else Display.str(string(" ")) ' clears "Pass' text Display.hex(Lptest,2) Display.str(string(" FAIL")) ' show 'Fail' text '************************************************************************************* PRI P2if ' check for Prop#2 transmissions if (c := PropSer.rxcheck) <> -1 ' process byte from the 2nd Propeller case c $90 : gotoxy(0,10) Display.str(string("RUN # ")) if (c := PropSer.rxcheck) <> -1 Display.hex(c,2) $84 : if (c := PropSer.rxcheck) <> -1 Prop2Reg := c ' 3-bit value indicating LOPEN, IOENA, PMENA states '************************************************************************************* ' The LEDreg uses the following bits to update the D/K LEDs ' nybl bits - 7/3 6/2 5/1 4/0 ' +---+---+---+---+-^-+-^-+-^-+-^-+ ' LEDreg | f |u/l| hi/lo | n y b l | ' +---+---+---+---+---+---+---+---+ ' 0 = LED info / | 0 0 = Data nybl.....(00..0F, 40..4F) ' 1 = other use | 0 1 = Addr lo nybl..(10..1F, 50..5F) ' 0 = low nybl / 1 0 = " hi hybl..(20..2F, 60..6F) ' 1 = hi nybl 1 1 = misc. use.....(30..3F, 70..7F) PRI UpdateDK_LED ' only called from 'DKif' routine if keyReg < $80 LEDreg := 0 | ((dataReg) & $F) ' Data LO nybl PICSer.tx(LEDreg) LEDreg := $00000040 | ((dataReg >> 4) & $F) ' Data HI nybl) PICSer.tx(LEDreg) LEDreg := $00000010 | ((addrReg >> 0) & $F) ' Addr LO nybl PICSer.tx(LEDreg) LEDreg := $00000050 | ((addrReg >> 4) & $F) ' Addr 2nd ls nybl PICSer.tx(LEDreg) LEDreg := $00000020 | ((addrReg >> 8) & $F) ' Addr 2nd ms nybl PICSer.tx(LEDreg) LEDreg := $00000060 | ((addrReg >> 12) & $F) ' Addr ms nybl PICSer.tx(LEDreg) '************************************************************************************* ' The following values are used for the following purposes: ' 0000_bbbb = hex values for Address, Data and Register settings ' 0001_bbbb = Command codes for Emulator control ' 0010_0000 \ ' thru > = not output by D/K ' 0111_1111 / (BUT, looptest would affect D/K LEDs w/these values) ' 1000_0000 \ ' thru > = Looptest values and pass/fail codes ' 1111_1111 / PRI KeyDecode if key < $10 ' ck if 'hex' key value if dirReg == $1 ' decode 3-cases; Addr=1, Data=2 (MEM), Reg=3 (REG) addrReg := (addrReg <<= 4) | key ' shift left 4 bits, OR in new value elseif (dirReg & ($1 << 1)) == $2 ' WRite key pressed dataReg := (dataReg <<= 4) | key ' shift left 4 bits, OR in new value elseif (dirReg & ($1 <<2)) == $4 ' REG key pressed ifnot key == $0C regReg := key addrReg := (regReg & maskF0) | key ' just LO nybl replaced else ' 'C'key toggles ALT flag for REG use if addrReg & ($1 << 4) ' test if ALT bit set addrReg := (addrReg & $0F) ' if so, clear it else addrReg := addrReg | ($1 << 4) ' if not, set it elseif key <$1C ' ck if 'command' key value statReg := key ' transfer for debug display CommandDecoder ' decode the 12 commands '************************************************************************************* ' The 'CmdStatus' bit assignments by the CommandDecoder ' +---+---+---+---+---+---+---+---+---+---+---+ ' CmdStatus 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | ' +---+---+---+---+---+---+---+---+---+---+---+ ' RUN TST ALT^SBP STP DEC INC HALT RD REG MEM^ ' (bits 7..0 go direct to 'tri-state' onto DTbus) PRI CommandDecoder | k ' Command key 'c' = code from D/K CmdP2 := (CmdP2 | $C0) k := 0 case c $10 : ' RUN operation k := 1 CmdP2 :=(CmdP2 | $1 | ($1 << 2)| ($1 << 4)) ' = $C4 PropSer.tx(CmdP2) CmdStatus := (CmdStatus | ($1 << 10)) ' set bit 10 PropSer.tx($90) ' $90 code causes Prop#2 to return an incremented count Prop2Reg := $3 ' value for LOPEN low, other two high $11 : ' CLeaR all registers, except dirReg->1 addrReg := 0 dataReg := 0 ' need to send RUN, STP, HLT info to Prop#2 statReg := 0 dirReg := 1 ' dirReg 1 = enter data hex into address reg CmdStatus := 0 ' clear all CmdStatus bits CmdP2 := $C0 ' = $C0 Prop2Reg := $5 ' value for IOENA low, other two high PICSer.tx($33) ' for HLT/STP DP $12 : ' HaLT k := 1 CmdP2 :=(CmdP2 | $1 | ($1 << 4)) ' = $D1 PropSer.tx(CmdP2) CmdStatus := (CmdStatus | ($1 << 3)) ' set bit 3 ' Prop2Reg := $6 ' value for PMENA low, other two high PICSer.tx($33) ' for HLT/STP DP $13 : ' TeST k := 1 CmdP2 :=(CmdP2 | $1 | ($1 << 4)) ' = $D1 CmdStatus := (CmdStatus | ($1 << 8)) ' set bit 8 k := Lptest // 16 ' TEMP for looptesting PICSer.tx($30 | k) k++ $14 : ' SetBreakPoint k := 1 CmdP2 :=(CmdP2 | $1 | ($1 << 4)) ' = $D1 CmdStatus := (CmdStatus | ($1 << 7)) ' set bit 7 ' SBPtreg := addrReg ' IS THIS Correct ??? PropSer.tx($83) ' outputs Address reg to Prop#2 for breakpoint c := ((SBPtreg >> 8) & $FF) waitcnt(8000000 + cnt) ' wait about 10 ms (or time := cnt, waitcnt(time + ms10) PropSer.tx(c) c := SBPtreg & $FF waitcnt(8000000 + cnt) ' wait about 10 ms (or time := cnt, waitcnt(time + ms10) PropSer.tx(c) 'this for DEBUGGING only gotoxy(0,12) Display.str(string("BP2...")) repeat c := PropSer.rxcheck while c == -1 Display.hex(c,2) ' FOR SOME REASON, DOESN'T WORK RIGHT repeat c := PropSer.rxcheck while c == -1 Display.hex(c,2) Display.str(string("_")) repeat c := PropSer.rxcheck while c == -1 Display.hex(c,2) repeat c := PropSer.rxcheck while c == -1 Display.hex(c,2) PICSer.tx($32) ' for SBP DP $15 : ' STeP k := 1 CmdP2 := (CmdP2 | $1 | ($1 << 4) | ($1 << 1) | ($1 << 3)) ' = $DB PropSer.tx(CmdP2) CmdStatus := (CmdStatus | ($1 << 6)) ' set bit 6 ' PICSer.tx($33) ' for HLT/STP DP $16 : ' MEMory ' = $C1 dirReg := 1 CmdStatus := (CmdStatus | $1) ' set bit 0 for $C1 PICSer.tx($34) ' for MEM DP $17 : ' REGister dirReg := 4 CmdStatus := (CmdStatus | ($1 << 1)) ' set bit 1 for $C2 ' PICSer.tx($35) ' for REG DP $18 : ' ReaD dirReg := dirReg & !($1 << 1) CmdStatus := (CmdStatus | ($1 << 2)) ' set bit 2 for RD ' PICSer.tx($3B) ' for 'r' segments $19 : ' WRite dirReg := dirReg | ($1 << 1) CmdStatus := (CmdStatus & !($1 << 2)) ' clear bit 2 if WR ' $1A : ' INCrement Address k := 1 addrReg += 1 CmdP2 :=(CmdP2 | $1 | ($1 << 4)) ' = $D1 CmdStatus := (CmdStatus | ($1 << 4)) ' set bit 4 ' PICSer.tx($36) ' for INC/DEC DP $1B : ' DECrement Address k := 1 addrReg -= 1 CmdP2 :=(CmdP2 | $1 | ($1 << 4)) ' = $D1 CmdStatus := (CmdStatus | ($1 << 5)) ' set bit 5 ' PICSer.tx($36) ' for INC/DEC DP StatAsm := CmdStatus ' get full Status,and position if c <> $11 tempStat := (StatAsm & $FF) << 16 'status' byte at DTbus tempLow := (addrReg & $FF) << 16 ' position Addr LO byte tempHigh := ((addrReg >> 8) & $FF) << 16 ' position Addr HI byte tempDat := (dataReg & $FF) << 16 ' position Data byte if k == 1 PropSer.tx($91) ' send code for Prop#2 to pulse INTR line low/high gotoxy(0,11) ' DISPLAYS VALUE SENT TO PROP2 'CntlFF' VARIABLE Display.str(string(" CmdP2.")) Display.hex(CmdP2,2) PropSer.tx(CmdP2) ' to Prop#2 to set/reset CntlFF, Control 'pg 2' stuff '************************************************************************************* PRI DisplayRegs gotoxy(0,1) Display.str(string("Address.")) gotoxy(15,1) Display.str(string("Data.")) gotoxy(24,1) Display.str(string("Status.")) gotoxy(0,2) Display.str(string(" D/K tx.")) gotoxy(15,2) Display.str(string(" Reg.")) gotoxy(24,2) Display.str(string(" Dir.")) ' gotoxy(0,3) ' Display.str(string("Lptest..")) 'KEEP FOR LOOP TESTING !!! gotoxy(13,3) Display.str(string("LEDreg.")) gotoxy(24,3) Display.str(string("CmdStatus.")) gotoxy(0,8) Display.str(string("BrkPt.")) gotoxy(16,8) Display.str(string("/LOPEN,IOENA,PMENA.")) gotoxy(14,10) Display.str(@grafix) '************************************************************************************* PRI RegistersUpdate gotoxy(8,1) Display.hex(addrReg,4) gotoxy(20,1) Display.hex(dataReg,2) gotoxy(31,1) Display.hex(statReg,2) gotoxy(8,2) Display.hex(key,2) gotoxy(20,2) Display.hex(regReg,2) gotoxy(31,2) Display.hex(dirReg,2) ' gotoxy(8,3) ' Display.hex(Lptest,2) 'KEEP FOR LOOP TESTING !!! gotoxy(20,3) Display.hex(LEDreg,2) gotoxy(34,3) Display.hex(CmdStatus,4) gotoxy(6,8) Display.hex(SBPtreg,4) gotoxy(35,8) Display.bin(Prop2Reg,3) ' THIS REG MAY CHANGE NAMES !!! gotoxy(0,5) Display.str(string("Status.")) Display.hex((tempStat >>16),2) Display.str(string(", LoAdd.")) Display.hex((tempLow >>16),2) Display.str(string(", HiAdd.")) Display.hex((tempHigh >>16),2) Display.str(string(", Data.")) Display.hex((tempDat >>16),2) '************************************************************************************* PRI gotoxy(x,y) ' used to set TV_text screen location x,y Display.out($0A) Display.out(x) Display.out($0B) Display.out(y) '************************************************************************************* PRI color(x) ' used to set TV_text fore-/back-ground color Display.out($0C) Display.out(x) '************************************************************************************* DAT '**************************************** '* DT bus controller '**************************************** ' -+---+---+---+---+---+---+---+---+ THIS DOESN"T APPEAR TO BE USED YET ' Port pin | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | ' -+---+---+---+---+---+---+---+---+ Decode ' BRDn / | | 0 0 0 = LO Address ' BIORQn --/ WRDATn -/ 0 0 1 = HI Address ' 0 1 0 = Status ' 0 1 1 = Data ' +---+---+ +---+---+---+ ' STmask | | | | | | | ' ---+ + +---+---+---+ + + +--- ' org 0 ' for PASD entry entry ' --------- Debugger Kernel add this at Entry (Addr 0) --------- long $34FC1202,$6CE81201,$83C120B,$8BC0E0A,$E87C0E03,$8BC0E0A long $EC7C0E05,$A0BC1207,$5C7C0003,$5C7C0003,$7FFC,$7FF8 ' -------------------------------------------------------------- ' org 0 ' for VP entry DTbus andn DIRA,DTbusMask ' make DTbus tri-state (input state) DTbusRW mov ptr,PAR ' get address of variable 'temp' rdlong temp,ptr wz ' get value passed from Spin (='StatAsm') if_z jmp #DTbusRW ' otherwise wait in loop ' Get/test Status byte add ptr,#4 ' incr to 'tempSt' position rdlong tempSt,ptr ' get Status byte passed from Spin xor tempSt,OUTA ' combine status and Output state xor OUTA,tempSt ' and set proper Status output levels ' waitpeq STstate,STmask ' wait for Status reg request or DIRA,DTbusMask ' make DTbus pins output waitpne STstate,STmask ' wait until request terminates andn DIRA,DTbusMask ' make DTbus tri-state (input state) shr temp,#1 wc,nr ' ck if MEM command if_nc jmp #tryREG ' wasn't ' MAYBE AFTER 'tempLo' ??? ' do MEM tasks - first LO byte tranfer, then HI byte add ptr,#4 ' incr to 'tempLo' position rdlong tempLo,ptr ' get LO addr byte passed from Spin xor tempLo,OUTA ' combine with Output state xor OUTA,tempLo ' to set proper output levels ' waitpeq LOstate,STmask ' wait for LO addr request or DIRA,DTbusMask ' make DTbus pins output waitpne LOstate,STmask ' wait until request ends andn DIRA,DTbusMask ' make bus tri-state add ptr,#4 'incr to 'tempHi' position rdlong tempHi,ptr ' get HI addr byte passed from Spin xor tempHi,OUTA ' combine with Output state xor OUTA,tempHi ' to set proper output levels ' waitpeq HIstate,STmask ' wait for HI addr request or DIRA,DTbusMask ' make DTbus pins output waitpne HIstate,STmask ' wait until request ends andn DIRA,DTbusMask ' make bus tri-state and temp,#4 wz,nr ' check if is ReaD command ??? RD/WR if_nz jmp #RDdata ' was WRITE ' WRdata add ptr,#4 ' incr to 'tempLo' position rdlong templO,ptr ' get Data byte passed from Spin xor templO,OUTA ' combine with Output state xor OUTA,templO ' to set proper output levels ' waitpeq DAstate,STmask ' wait for Data request or DIRA,DTbusMask ' make DTbus pins output waitpne DAstate,STmask ' wait until request ends andn DIRA,DTbusMask ' make bus tri-state jmp #DTbusRW ' MAYBE NOT USE,, IF READBACK TO D/K ??? RDdata add ptr,#4 ' incr to 'tempDa' position rdlong tempDa,ptr ' ' waitpeq DAstate,WRmask ' wait for data write request to Prop mov tempDa,INA ' get value from DTbus to reg and tempDA,DTbusMask ' only preserve data byte waitpne DAstate,WRmask ' wait until request ends add ptr,#4 ' set ptr to Data address wrlong tempDa,ptr ' put Data byte there for Spin jmp #DTbusRW tryREG and temp,#2 wz,nr ' ck if REG command if_z jmp #tryHLT ' ' do REG stuff and temp,#4 wz,nr ' check if is WRite command ??? RD/WR if_nz jmp #RDreg ' ' WRreg add ptr,#4 ' incr to 'tempDa' position rdlong tempDa,ptr ' get Data byte to pass to Spin xor tempDa,OUTA ' combine with Output state xor OUTA,tempDa ' to set proper output levels ' waitpeq STstate,STmask ' wait until request enda or DIRA,DTbusMask ' make DTbus pins output waitpne STstate,STmask ' wait until request enda andn DIRA,DTbusMask ' make bus tri-state jmp #DTbusRW ' RDreg add ptr,#4 ' incr to 'tempDa' position rdlong tempDa,ptr ' ' waitpeq DAstate,WRmask ' wait for data write request to Prop mov tempDa,INA ' get value from DTbus and tempDA,DTbusMask ' only preserve data byte's 8-bits waitpne DAstate,WRmask ' wait until request ends add ptr,#4 ' set ptr to Data address wrlong tempDa,ptr ' store Data byte for Spin jmp #DTbusRW tryHLT and temp,#$F8 wz,nr ' ck if is HLT, INC, DEC, STP or SBP if_nz jmp #RDreg ' was one of above doTST ' MAY NEED TO TRANSFER A DATA BYTE FOR POD LOOPTESTING jmp #RDreg ' ' Initialized data 'byteMask LONG $0000_00FF DTbusMask LONG $00FF_0000 WRmask LONG $0000_0008 ' A4 active LO 'WrDTbusMsk LONG $0000_0008 ' A4 active LO STmask LONG $0000_00C7 ' LOstate LONG 0 ' A0..A2 low ' WHERE'S CODE FOR THESE FOUR??? HIstate LONG 1 ' A0 HI, A1 LO STstate LONG 2 ' A0 LO, A1 HI + A6 and A7 LO (BIORQn, BRDn) DAstate LONG 3 ' A0, A1 HI ' Uninitialized data ptr RES 1 ' holds pointer IN PAr temp RES 1 ' get Status in low-byte position tempSt RES 1 ' Status in 2nd-ms byte position tempLo RES 1 ' Lo addr " " " tempHi RES 1 ' Hi addr " " " tempDa RES 1 ' Data " " " FIT 496 '************************************************************************************* DAT ' moved here for PASD operations; else point to wrong variable on debug ' org 0 titleP1 byte "Prop#1 ver. ; 14 Feb.2008",0 Cogs1 byte "; #cogs = ",0 ' foregnd backgnd tv_palette byte $07, $02 '0 white / black (white) byte $02, $07 '1 black / white (inverse) byte $07, $04 '2 red / pink (highlight) byte $0C, $02 '3 blue / black (blue) byte $5D, $02 '4 green / black (green) byte $ED, $02 '5 magenta / black (magenta) byte $BD, $02 '6 orange / black (orange) byte $CC, $02 '7 red / black (red) grafix byte " tsp Z80 Emulator",0 '************************************************************************************* ' 'DTbus' info exchange/direction table ' |<--------- D/K to POD -------->|<-- POD to D/K ' STATUS LO ADDR HI ADDR DATA DATA ' +--------+-------+--------+--------+-----+--------------+ ' MEM (RD) Y Y Y Y ' MEM (WR) Y Y Y Y Y ' REG (RD) Y (reg) Y ' REG (WR) Y (reg) Y Y ' HLT Y Y ' INC Y Y ??? ' DEC Y Y ??? ' STP Y Y ??? ' SBP Y Y ??? ' TST Y Y ' (02) (00) (01) (03) where (0n) = I/O code from Pod '************************************************************************************* ' Prop1 items to be developed Description Status ' 1. Serial i/f w/ D/K for D/K <=> Prop#1 comm done ' 2. Serial i/f w/ Prop2 for Prop1 <=> Prop2 comm done ' 3. 5 MHz output for Prop2 clock done ' 4. Tv-text i/f for visual debugging done ' 5. PropPlug i/f for programming Prop1 done ' 6. EEPROM i/f to store programs done ' 7. /RST to reset hdwr/Props done ' 8. DTbus i/f to Pod tri-state bus in process ' 9. /INTR tbd tbd '10.▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Harley Shanko
but it doesn't seem to work as I understand AN001. I'm using the DIP40 Props.
Am I interpreting things incorrectly?
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Harley Shanko
You are trying to output 40 MHz..... And feeding the PLL with this
I think your major misunderstanding comes from "PLL/16". When using the PLL you multiply with 16 in the first place. A divison happens AFTERWARDA. So PLL/16 gives no change in frequency (but a better pulse shape). The PLL works best around 8 MHz yielding 128 MHz which you can divide as you wish.... Though there is no special need to use the PLL in the first place for your application...
Sorry, it escaped my attention yesterday: Your main program TERMINATES just after calling FSYNTH.
Re: post 1:
You say main program terminates, must imply that FSynth is all SPIN, but the others, PICSer, PropSer and Display are separate assembly cogs for them to continue running properly?
Re: oost 2:
OK, now I guess I should have used NCO mode; skipped it when I saw PWM. But tried it and, after providing the proper value for the 'division' now have nice 5 MHz square wave on the scope. Some nice ringing; scope is only 100 MHz Tektronix 2247A.
I was hoping to get into the 'counters' some day; didn't think I'd need them yet. So, now have just this 3 SPIN vs Fsynth of about 25 SPIN lines:
I like this better. Would have been a matter of time as AN001 use was high on the list AFTER this project. Glad it came up now. Thanks for the 'nudge' and help.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Harley Shanko
ad2: Glad you made is with the counters. AFter understanding them you have to admit it is SIMPLE
BTW: don't write %011000 - that's confusing! Write 24!
re: 1 If, as I've used it, with the FDS and TV_text in Main, why does that work if the Main cog has terminated?
re: 2 They mean the same (re '24), but YES, it is much more clear for our 'decimal' brains. Thanks for the clarity. I suppose after teaching such points stand out.
I was able to use a ProtoBoard for verifying the 5 MHz counter; was a good platform for the scope probe, as I had a terminal for ground on it in the VGA connector area (I don't yet have a VGA monitor). Very handy boards; haven't used all 6 but fell for the deal of $100 a six-pack when first released.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Harley Shanko
Your routine CONTROL is not running in the main COG but in its own...