Shop Learn
NCO square-wave output using Smartpin — Parallax Forums

NCO square-wave output using Smartpin

I wanted a 12.375 MHz square wave to drive the clock on an FTDI EVE3 chip.
Was pretty easy to do using the NCO smartpin mode.

Basically like this in FlexProp C:
in FlexProp C using inline assembly to create NCO on pin #8 (12.375 MHz with 297 MHz P2 clock):
__asm {
wrpin ## 0b00000000000000000000000011001100, #8 //smartpin NCO
WXPIN #12, #8 //base period
WYPIN ##$8000_0000, #8 //add amount per clock
drvh #8
}

I've made some notes on the math and the Spin2 version here.

Comments

  • JonnyMacJonnyMac Posts: 7,419
    edited 2020-11-12 06:08
    For those using Spin2 in PNut and Propeller Tool, you can do it like this:
      org
                    wrpin   ##(P_OE | P_NCO_FREQ), #NCO_PIN
                    wxpin   #12, #NCO_PIN
                    wypin   ##$8000_0000, #NCO_PIN
                    drvh    #NCO_PIN
      end
    

  • evanhevanh Posts: 10,429
    I'm the last person to advise on how to use Spin2 but the built-in Pinstart() function should do the job.
    eg: PINSTART(NCO_PIN, (P_OE | P_NCO_FREQ), 12, $8000_0000)

  • Peter JakackiPeter Jakacki Posts: 10,051
    edited 2020-11-12 07:52
    For those using TAQOZ and much the same with Tachyon on the P1 you can use this (using pin 8):
    8 PIN 12,375 KHZ
    

    Try it yourself interactively via the serial console.
  • AribaAriba Posts: 2,440
    edited 2020-11-12 09:12
    evanh wrote: »
    I'm the last person to advise on how to use Spin2 but the built-in Pinstart() function should do the job.
    eg: PINSTART(NCO_PIN, (P_OE | P_NCO_FREQ), 12, $8000_0000)

    Exactly, and pinstart() works also in flex-C if you write it with a underscore at begin:
      _pinstart(8, P_NCO_FREQ+P_OE, 12, 0x8000_0000);
    
    Andy
  • RaymanRayman Posts: 11,844
    I did not know about pinstart!
    Thanks!
  • JonnyMacJonnyMac Posts: 7,419
    edited 2020-11-12 15:17
    evanh wrote: »
    I'm the last person to advise on how to use Spin2 but the built-in Pinstart() function should do the job.
    eg: PINSTART(NCO_PIN, (P_OE | P_NCO_FREQ), 12, $8000_0000)

    You're absolutely right. I have recently been porting P1 laser tag code to the P2, and have setup my IR modulation pins manually so that I can control when the oscillation starts. In this case, it is desired right away, so pinstart() is appropriate.
    pub set_freq(port, hz) 
    
    '' Sets output frequency for selected port(s), 1, 2, or 3 (both)
    '' -- application should check for not busy before changing frequency
    '' -- setting frequency to 0 disables port
    
      if (tx1p >= 0)                                                ' port 1 pin defined?
        if ((port == CMD_P1) || (port == CMD_P3))                   ' update port 1 frequency?
          pinclear(tx1p)                                            ' clear settings
          if (hz > 0)
            wrpin(tx1p, P_NCO_FREQ | P_OE)                          ' NCO with output
            wxpin(tx1p, 1)
            wypin(tx1p, hz frac clkfreq)                            ' set frequency
    
      if (tx2p >= 0)
        if ((port == CMD_P2) || (port == CMD_P3))
          pinclear(tx2p)
          if (hz > 0)
            wrpin(tx2p, P_NCO_FREQ | P_OE)
            wxpin(tx2p, 1)
            wypin(tx2p, hz frac clkfreq)
    

  • RaymanRayman Posts: 11,844
    I've added PINSTART and the predefined constant info to my webpage, thanks.
Sign In or Register to comment.