How to enable NCO_FREQ on pin?

I'm trying to generate a 3.7 MHz clock on a P2 SmartPin, for an external device. I've set my _clkfreq to 40x that value, and have Spin2 functions in my main module that call PINSTART and PINCLEAR, plus some support. My crystal is 5 MHZ. Nothing happens when I call PINSTART.
CON
'142,848,000 Hz is the SAM 3.5712 MHZ clock times 40
_clkfreq = 142_848_000 'sets clock PLL. Compilation fails with impossible numbers > 500 MHz.
'SAM
pLLIOSamRst = 43
pLLIOSamClk = 42
pLLIOSamIo1 = 40
pLLIOSamIo2 = 39
pLLIOSamIo3 = 41
PUB SamStart() : RESULT | mode
'Start clock on PIO42 at 3.5712 MHz
'See SmartPin Supplement, search "%00110: Numerically Controlled Oscillator (NCO)"
DIRb.[pLLIOSamRst-32] ~~ 'RST PIO 43. dirA[42] does not work. dirB[0] is PIO32. dirB[11] is PIO43.
OUTb.[pLLIOSamRst-32] ~ 'RST low
DIRb.[pLLIOSamClk-32] ~
'PINSTART(PinField, Mode, Xval, Yval)
' ASSUME _clkfreq is 40X the desired SAM clock.
'mode := %0000_0000_000_0000_000000000_01_00110_0
PINSTART(pLLIOSamClk, P_OE | P_NCO_FREQ, 40, 0)
'PINH(pLLIOSamClk)
{{
ORG
NCO_Config long %0000_0000_000_0000_000000000_01_00110_0
dirl #42
wrpin NCO_Config,#42
wxpin #40,#42
wypin #0,#42
dirh #42
END
}}
RESULT ~
OUTb.[pLLIOSamRst-32] ~~ 'RST high
fourrdrs.str(k4RdrHost, string("SamStart complete",13,10))
PUB SamStop() : RESULT
OUTb.[pLLIOSamRst-32] ~ 'RST low
'Stop clock on PIO42 and ground it
PINCLEAR(pLLIOSamClk)
DIRb.[pLLIOSamClk-32] ~~
OUTb.[pLLIOSamClk-32] ~~
RESULT ~
fourrdrs.str(k4RdrHost, string("SamStop complete",13,10))
After calling SamStart(), the clock pin is steady 0V. After calling SamStop, it is steady 3V3. So I have control of the pins as I/O points, and proof that the line is not shorted to ground, but I can't get the function to generate.
I tried it in assembly in case that was necessary - didn't help. I thought my problem might be in the main module, but @Wuerfel_21's example https://forums.parallax.com/discussion/175884/e-guitar-synthesizer-in-50-lines-of-spin-2 has the PINSTART call right in main. I tried PINH after PINSTART. I included the Output Enable constant. And of course I'm using the serial port examples with PINSTART. I've tried different X and Y values to try and make something happen. But nothing happens.
Can someone spot my mistake? Thanks!
Comments
Well that's certainly not how it works.
For an exact divider, you'd use P_PULSE. Something like
pinstart(..., P_PULSE|P_OE,40 + (20<<16),1234)
where the Y value (1234) is the number of pulses you want. You can keep writing large numbers into Y if you want to pulse indefinitely.This works -- but I may be missing something
Here's the logic analyzer capture:
My P2 projects run at 200MHz.
Edit: I just noticed that you're running at 142_848_000. The smart pin code above still produces the correct output. Hat tip to @Ariba to showing me how to use the smart pin to generate a specific frequency using NCO mode.
It's working now, of course:
I took JonnyMac's answer so I wouldn't have to learn about pulses right now. Thanks again, both of you.
For the record, the SmartPin Supplement says:
Which led me to put a divisor in X and 0 in Y.
It'd be nice if there were a web based tool for smartpin type stuff, where you just select what you want and it spits out the code...
But, maybe AI will take care of that for us?
That "supplement" should probably be removed. It has many errors. Read Chip's original Silicon Doc instead - https://docs.google.com/document/d/1gn6oaT5Ib7CytvlZHacmrSbVBJsD9t_-kmvjd7nUR6o