Shop OBEX P1 Docs P2 Docs Learn Events
Fastest DDS (128 MSPS) and FM Transmitter — Parallax Forums

Fastest DDS (128 MSPS) and FM Transmitter

Currently 3 bit output at 128 MHz sample rate. Available here: https://github.com/SaucySoliton/propeller-dds

The 3 bit output works well with the composite video DAC resistors on many Propeller boards. Signal purity is fairly poor, so keep your antenna wire short. I get enough leakage with just a coaxial cable to my scope. Sound quality has the potential to be very good once pre-emphasis is added as the DDS has tuning steps much smaller the 1 Hz. The high sampling rate should allow good signals below 20MHz with a simple RC lowpass filter.

While the counter PLL can generate any frequency from 500 kHz to 128+ MHz, the list of jitter-free frequencies can fit on one page. This is a frustrating limitation for RF projects. A little while ago I did some calculations for using the video generator to output a pre-calculated sine sequence. While this is useful for many more frequencies, it would not be usable for local oscillators for HF. The tuning steps were, for practical purposes, random, and could be as large as several kilohertz. One of the strengths of direct digital synthesis is very fine tuning resolution. So I began an investigation into the feasability of a proper DDS.

I decided to target the highest clock sample rate possible. This meant using the video generator to output pre-calculated groups of samples. 32 samples is the maximum, assuming each cog only outputs 1 bit. Also, it would be nice to access the hub every once in a while for frequency changes, for application like an FM transmitter. The video generators need to be synchronized exactly. It is necessary to fit the hub access between 2 WAITVIDs. Each cog's hub access is staggered by 2 clocks. This forces an additional trade-off between sample rate and number of bits. If the hub access was eliminated, it would be possible to synchronize any number of cogs together.
Other possible configurations for the DDS code, not yet implemented:
      loop clocks  bits/cog   bits total
128MS     20          1           3 (maybe 4)
 80MS     32          1           4+ ? 
 64MS     20          2           6 (maybe 8)
 40MS     32          2           8+ ?
 16MS     20          8           8+
  5MS     16         32          32+
Assumes a 256-step sine table

Why is the last one 5 MS instead of 4? Recall that the Nyquist theorem says signals exceeding half the sampling rate cannot be perfectly reconstructed. They will alias to a frequency less than half the sampling rate. So, there is no logical reason to program a frequency that exceeds half the sampling rate. We could extend the table to one and a half cycles and 384 steps and only need to mask the accumulator every other addition. For groups of samples we can't assume we will only advance half the wave at a time. We could still use this trick with 2 or more full tables of 128 steps. I chose not to use the shorter table at this time.
:inline1    mov   outa,0-0
            addx  accu,tw  wc
            andn  accu,#%1_0000_0000
            movs  :inline1,accu
:inline2    mov   outa,0-0
            addx  accu,tw  wc
            movs  :inline2,accu
            jmp   #:inline1

Some of the implementations previously published shift the accumulator to extract the MSBs with MOVS and then shift it back. We can save 2 instructions by leaving it in the shifted position. We have to use one of the instructions gained to clear the MSB carry bit so we stay in our table. But as noted above, it's possible to not need it every time. We can use ADDX to transfer the carry from LSBs to MSBs. A slight complication of this is that the carry is not added until the next addition. This would sometimes introduce an error of 1 step in the output. We could fix this by adding an offset to the accumulator so the carry happens one cycle sooner. That is simply adding a phase shift to our signal, which can be ignored for most applications.

The FM transmitter is nowhere near finished. I just it together to test the DDS. Sound quality is not so good without pre-emphasis. Signal purity is bad, but perhaps slightly better than Rasperry Pi before I fixed it. I wish the Propeller had PLLs like the Raspberry Pi. The fractional N PLLs in that chip have a clean signal AND a wide enough loop bandwidth to modulate FM stereo. I will probably make a version of the transmitter that uses the Propeller PLL just to test the signal quality.

3bits.jpg
1280 x 480 - 97K

Comments

  • MIchael_MichalskiMIchael_Michalski Posts: 138
    edited 2018-01-04 17:28
    Could you pass instructions to the cog through IO pins? that way the communications could be deterministic (and only 4 cycles to read instead of 8)
  • Could you pass commands to the cog through IO pins? that way the communications could be deterministic (and only 4 cycles to read instead of 8)

  • Could you pass instructions to the cog through IO pins? that way the communications could be deterministic (and only 4 cycles to read instead of 8)
    Yes, of course. The update rate would probably decrease unless we used a whole bunch of pins. It's currently 500kHz. Or one could restrict the tuning range to need fewer bits.

    I currently need to allow 12+ cycles for hub access because the hub windows are staggered but the waitvids are not.
  • Would this enable the Prop to be used as an FPV video transmitter for robots or drones? Or maybe a mini-FM radio station if video isn't completely feasible?
  • DrPop wrote: »
    Would this enable the Prop to be used as an FPV video transmitter for robots or drones? Or maybe a mini-FM radio station if video isn't completely feasible?
    I wouldn't recommend it. The first problem is getting video into the Propeller. Without adding an ADC this is about the best you'll get: http://forums.parallax.com/discussion/135244/propeller-backpack-color-ntsc-capture The transmission frequency will be limited to low VHF without lots of additional hardware. It would be difficult to modulate the signal fast enough for analog video. It might be possible to have a digital FSK system. The Propeller 1 just isn't fast enough to do serious video compression.

    The FM transmitter is in progress. I'm not eager to write the filtering and pre-emphasis code since the Propeller has no floating point or hardware multiplier. Both the DDS and the Propeller PLL have enough bandwidth for FM stereo with RDS.

    Other applications I had in mind were QRP transmitters, WSPR beacons, and local oscillators for receivers. Whether this code generates a cleaner signal than the PLL is yet to be determined. Also, I just realized that the counters connected to a DAC will generate a sawtooth signal at an 80 MHz sample rate.


  • I made an FM transmitter using the PLL for comparison.

    dds-pll-100M.jpg
    It's not looking good for the DDS. Why did I do this? >:(


    dds-pll-20M.jpg
    PLL jitter is starting to become more visible.

    dds-pll-2M.jpg
    This is why we don't use the Propeller as a transmitter. A bandpass filter would not be able to clean the PLL output unless it had a very high Q, such as a cavity filter or crystal filter. An external PLL would work, as Phil has done.

    The sidebands on the DDS signal might be due to the low 3 bit resolution or too much error at the end of the 32 sample tables at peak modulation. Other possibilities include the zero order hold in the modulator cog, changing the output frequency in a stair-step pattern. It could also be caused by a lack of low-pass filtering on the modulator's input. Capturing the DUTY output of one counter with another counter may introduce some high frequency noise. I'll be doing some tests without modulation to help narrow down the cause.
    1298 x 579 - 136K
    1294 x 566 - 139K
    1280 x 560 - 139K
  • SaucySoliton,

    You never know these things until you try.
  • The primary metric I'm using to judge performance is Spurious-Free Dynamic Range (SFDR.) When transmitters are tested for FCC certification, the transmitter output is compared with a spectrum mask. The mask specifies how much undesired signals must be reduced compared to the desired signal. The amount of attenuation is typically specified in decibels. It's basically an SFDR measurement, but mask requirements can vary with frequency. The SFDR is also important for receivers as it's one of the factors that affect a receiver's ability to ignore undesired signals.

    vidclk128M.jpg
    In a previous post the FM transmitter SFDR was about 27dB.
    The 128MHz video clock SFDR is 25dB. It appears that all of the noise at 200-300kHz from the carrier is from the video clock.
    The peaks near 500kHz might be worse with the DDS, but keep in mind that the DDS runs 3 PLLs together.

    40m.jpg
    The triangular sidebands appear to be VCO noise. While disappointing, this is not surprising as the Propeller PLLs do not have the circular inductors commonly seen on RF VCOs. Cascading 2 PLLs seems to make things worse by 10dB. There are 2 ways to avoid this: 1.We could use an external crystal oscillator. 2.Don't use the video generator. Unfortunately the video generator can only be driven with the counter in PLL mode. The counters can output a 2-bit signal, more on that later. With interleaved cogs writing OUTA we are limited to 20MSPS although in this region the PLL phase noise isn't so bad. If we avoid using either PLL, the signal should be very clean.

    xtal.jpg
    The Propeller's crystal oscillator looks good.
    640 x 561 - 71K
    1280 x 551 - 139K
    1280 x 561 - 136K
  • The Propeller's crystal oscillator looks good.
    Yes, and you can "pull" the oscillator's frequency by applying a DUTY-mode output to a varactor diode connected to the crystal. Perhaps a way of creating FM?

    -Phil
  • The Propeller's crystal oscillator looks good.
    Yes, and you can "pull" the oscillator's frequency by applying a DUTY-mode output to a varactor diode connected to the crystal. Perhaps a way of creating FM?

    -Phil

    Interesting idea! Sounds great for HF frequencies. I don't see how it helps for wideband FM. With a low frequency crystal we would still need a PLL to get the frequency up. The output should be close to acceptable though. With a high frequency crystal we probably couldn't get enough deviation.

    Has anyone connected the oscillator pins to a tank circuit instead of a crystal?


    It might be possible to clean up the phase noise by using an external register driven by an external crystal oscillator. That register could be part of a DAC chip. ;) The Propeller could run off the same oscillator. But then why not just use a dedicated DDS chip?
  • It might be possible to clean up the phase noise by using an external register driven by an external crystal oscillator. That register could be part of a DAC chip. ;)

    Never mind. The registers are built into the Propeller. 8) They're part of the counter feedback circuit. We need to waste some pins for the register inputs. The could also be issues with the delay from routing signals to a pin and back. The output sampling rate must match the system clock, but the external register has the same limitation.

    registered-pll.jpg
    The narrowband SFDR is 34dB. Previous version was 27dB. This is reasonable considering the previously measured difference between 1 PLL and 2 cascaded PLLs. For both tests I was using the system PLL for convenience. If the Propeller was clocked by an 80MHz crystal oscillator the VCO noise should vanish. The other spurious signals should decrease as more bits are added. That will be easier now with the relaxed timing at 80MSPS compared to 128MSPS. Code will be uploaded after some cleanup. Stay tuned! :D Sorry, I couldn't resist.
    640 x 560 - 48K
  • A long time ago I had grand thoughts making some sort of HF-VHF Rx by "varying the 5MHz (a vfo), and keeping the multiplication constant at one of the non-fractional sweet spots" . It was going to be used with one of the "just become redundant analog TV tuner modules" so the pull of the 5MHz muliplied up to the 40MHz region for the would interpolate the 50KHz synth jumps that it would allow. It's all a bit hazy to me now but I remember that I needed something like a 28MHz Xtal osc for it all. Moving house - and loosing my little workshop area killed all those dabblings, for years now.

    I will see if I can figure it out again ... or if it was one of my weird ideas that was never going anywhere .. again

    And then I find these -
    https://www.banggood.com/35M-4_4GHz-PLL-RF-Signal-Source-Frequency-Synthesizer-ADF4351-Development-Board-p-1129041.html?rmmds=search&cur_warehouse=CN

    Makes all all the experimenting seem a bit pointless - Use the Prop for the control/display stuff and leave the spectral purity to faster DDSs

  • Some memories of what I was trying to acheive came through - the 28MHz was to feed a frequency counter running in the Prop so that that gave the "known" freq - so that the 5MHz could be variable.

    It was either going to be pure genius ... or ....

    Any way I do not have any of the analog TV tuners anymore
  • jmgjmg Posts: 15,140
    edited 2018-02-24 23:49
    Interesting idea! Sounds great for HF frequencies. I don't see how it helps for wideband FM. With a low frequency crystal we would still need a PLL to get the frequency up. The output should be close to acceptable though. With a high frequency crystal we probably couldn't get enough deviation.

    Yes, HF Xtals have quite narrow pull range, but Ceramic Resonators can be used for more pull range than a Crystal.

    Checking MEMS VCTCXO's I see they offer :
    Pull Range PR ±12.5, ±25, ±50 ppm
    Control Voltage -3dB Bandwidth V_BW – – 8 kHz

    So still quite small pull range.
    Has anyone connected the oscillator pins to a tank circuit instead of a crystal?
    Any CMOS inverter oscillator can use a LC just fine, however, you need to find a high Q inductor, which is no easy task.

    The triangular sidebands appear to be VCO noise. While disappointing, this is not surprising as the Propeller PLLs do not have the circular inductors commonly seen on RF VCOs.
    The Propeller's crystal oscillator looks good.

    For direct 80MHz clocking experiments, to skip Prop PLL noise, you could look at the Si5351 ? - Adafruit have a $8 breakout module for this part.
    The VCO version of this part specs 10kHz bandwidth, and 30 ~ 340ppm pull range user selectable.

    Some of the SiLabs parts allow small continual steps, Si514/544/549 indicate within ~ +-950ppm as being ok.
    Not sure how the cheaper Si5351 stacks up, but an alternative could be to update just the fine-trim registers via i2c for narrow FM modulation ?


    Addit: checking Digikey, and https://www.silabs.com/products/timing/lookup-customize
    gives these stock items

    Part Number: 514CBB000112AAG Product Si514 Description Any Frequency I2C Programmable XO
    Frequency A 10 MHz I2C Address (Hex Format) 55 Format CMOS
    Supply Voltage 3.3 V Temperature Stability / Total Stability 25 ppm / 50 ppm
    Package Option 5x7 mm

    Part Number: 514FAA000115BAG Product Si514 Description Any Frequency I2C Programmable XO
    Frequency A 125 MHz I2C Address (Hex Format) 55 Format LVDS
    Supply Voltage 2.5 V Temperature Stability / Total Stability 50 ppm / 100 ppm
    Frequency Range 100 kHz - 250 MHz
    Package Option 3.2x5 mm

    Part Number: 514BBC000932AAG Product Si514 Description Any Frequency I2C Programmable XO
    Frequency A 70.656 MHz I2C Address (Hex Format) 1D Format LVDS
    Supply Voltage 3.3 V Temperature Stability / Total Stability 25 ppm / 50 ppm
    Frequency Range 100 kHz - 125 MHz
    Package Option 5x7 mm

    The 514CBB000112AAG looks Prop-useful (3.3v, CMOS drive, 10MHz default)
  • This work will soon be obsolete with the release of Propeller 2. It will be able to do this in hardware using the Goertzel hardware or the chroma modulator.

    The Propeller 1 PLLs have a significant amount of jitter. It's a big problem for radio transmitters. Thankfully it's easy enough to use an external oscillator for the system clock. The oscillator I used was the MXO45HS-3C-80M0000 It's a 5v part, but is seems to work fine at 3.3v. :naughty:

    Another minor problem is that the video generator can only be clocked from a PLL. We can work around that by following the video generator output with a flip-flop, as long as that flip-flop is clocked by a clean clock source that's phase locked to the video generator clock. Some counters in feedback mode will do the trick. They are clocked by the system clock, and the video generator clock is phase locked to it. We just have to waste pins to route the video generator output through the counters.

    Each cog generates 1 bit of data. So the 3 bit output uses 3 cogs and 6 pins. But you can have an 80MSPS direct digital synthesizer using only through-hole parts!

    registered-xo-comparison.jpg
    SFDR has improved from 34dB to 40dB. The signal shown is being modulated for an FM transmitter. The remaining noise could be from having only a 3 bit D/A converter, or as a result of the modulation. The audio is acquired by counting the duty cycle of the audio output pin driven by another cog. From this discussion on the P2 we've found that using a rectangular window is far from optimal. forums.parallax.com/discussion/comment/1457413/#Comment_1457413 The signal quality could likely be improved more by adding more bits to the DAC and by using a triangular or quadratic window on the audio input. I'm probably not going to test more bits due to lack of enthusiasm. The window function is easy to adjust. Or I could just turn off modulation to check the carrier itself.
    1279 x 560 - 161K
Sign In or Register to comment.