MQTT-controlled 4-channel DDS signal generator using Urukul, Humpback and STM32 NUCLEO
Go to file
occheung b75c83be61 mqtt: changeable root topic name 2020-09-29 17:02:15 +08:00
.cargo scpi: add switch ctrl command 2020-09-03 17:41:27 +08:00
fpga fpga_config: fix tab/space 2020-09-25 14:29:33 +08:00
gdb_config scpi: adopt rust standard on result/option handling 2020-09-14 15:36:03 +08:00
nix update rust/cargo 2020-09-25 17:05:40 +08:00
openocd openocd: clean cfg 2020-09-25 11:11:08 +08:00
src mqtt: changeable root topic name 2020-09-29 17:02:15 +08:00
.gitignore cargo.lock: commit 2020-09-16 17:45:14 +08:00
Cargo.lock cargo: include ryu 2020-09-28 14:13:02 +08:00
Cargo.toml cargo: include ryu 2020-09-28 14:13:02 +08:00
README.md readme: fix topic prefix 2020-09-29 10:30:05 +08:00
build.rs rename migen to fpga 2020-09-25 14:26:28 +08:00
cargosha256.nix cargosha256: update 2020-09-29 12:37:23 +08:00
memory.x scpi: introduce master clock setup 2020-09-07 14:07:39 +08:00
shell.nix nix: simplify 2020-09-25 11:24:45 +08:00

README.md

Humpback DDS

RF signal generator using Urukul, Humpback and STM32 NUCLEO-H743ZI2

Nix commands

Start nix shell before anything.

nix-shell

Flash firmware onto STM32 NUCLEO-H743ZI2 using OpenOCD.

openocd -f openocd/openocd.cfg -f openocd/main.cfg

Alternatively, an equivalent Nix command can also do the work

openocd-flash main

Networking Setup

At the moment, both IP addresses of the STM32 board and MQTT broker are hardcoded. MAC address of the STM32 board is also hardcoded.

STM32 IP Address

IP address is hardcoded in the file src/main.rs, line 171.

store.ip_addrs[0] = net::wire::IpCidr::new(net::wire::IpAddress::v4(192, 168, 1, 200), 24);

The IP address shown above corresponds to 192.168.1.200, in a /24 address block. Modify this line to the change the IP address of STM32 board.

STM32 MAC Address

IP address is hardcoded in the file src/main.rs, line 156.

let mac_addr = net::wire::EthernetAddress([0xAC, 0x6F, 0x7A, 0xDE, 0xD6, 0xC8]);

The MAC address shown above corresponds to AC::6F::7A::DE::D6::C8. Modify this line to the change the MAC address of STM32 board.

Broker IP Address

IP address is hardcoded in the file src/main.rs, line 241.

    IpAddr::V4(Ipv4Addr::new(192, 168, 1, 125)),

This program will try attempt to connect to 192.168.1.125:1883. Modify this line to the change the IP address of MQTT broker. Note that the broker must accept TCP connection at port 1883.

MQTT Broker

Mosquitto is within the Nix package. Starting a Mosquitto MQTT broker can be as simple as the following line.

mosquitto

The MQTT broker will be started locally, at port 1883.

To enable feedback from the device, subscribe to all subtopics under Urukul/Feedback on a separate terminal.

mosquitto_sub -h <broker ip address> -t Urukul/Feedback/#

Note that subscription to the feedback topic is completely optional.

Publishing MQTT messages through Mosquitto

Controlling Humpback-DDS can be achieved by sending specific MQTT commands through Mosquitto. The device will listen to all publishes that are under the Urukul/Control or /Urukul/Control topic. A MQTT message can be published by the following command.

mosquitto_pub -h <broker ip address> -t <topic> -m <message>

For example, to publish a local MQTT broker, with the topic of Foo/Bar and Baz as the message, enter this command.

mosquitto_pub -h localhost -t Foo/Bar -m "Baz"

Note that MQTT topics are case-sensitive.
Alternatively, the following nix command provided by the shell simplify the syntax.

publish-mqtt <topic> <message>

This will send the MQTT message to a local MQTT broker at port 1883, with specified topic and message. The example above can be simplified into:

publish-mqtt Foo/Bar "baz"

List of Commands

All currently supported commands are listed below.
Note: The following table only lists the subtopic. To make a full topic, add Urukul/Control/ in front of all subtopics.
Example: Full topic of Reset command: Urukul/Control/Reset

Subtopic Message Functionality
Reset Reset the device
ChannelX/Switch <off/on> Turn off/on the RF switch at channel X.
ChannelX/Attenuation <atten> [dB] Set attenuation of channel X.
Clock/Source <clk_src> Select the clock source of Urukul.
Clock/Frequency <f_clk> [unit] Set the clock frequency of the clock source of Urukul.
Clock/Source <clk_div> Set the clock division of Urukul.
Clock frequency: <f_clk> [unit], source: <clk_src>, division: <clk_div> Setup the clock tree for Urukul.
ChannelX/SystemClock <f_sys_clk> [unit] Set the system clock frequency of channel X.
ChannelX/ProfileY/Singletone/Frequency <freq> [unit] Setup a single tone profile at channel X, profile Y, with frequency <freq> [unit].
ChannelX/ProfileY/Singletone/Amplitude <ampl> Setup a single tone profile at channel X, profile Y, with amplitude factor <ampl>.
ChannelX/ProfileY/Singletone/Phase <phase> [deg] Setup a single tone profile at channel X, profile Y, with phase <phase> [deg].
ChannelX/ProfileY/Singletone frequency: <freq> [unit], amplitude: <ampl>, phase: <phase> Setup a compelte single tone profile at channel X, profile Y.
Profile <pr_num> Switch to a DDS profile across all channels.

Reset the device

  • Topic: Urukul/Control/Reset
  • Message: (Don't care)

The Reset command resets the device. The effects are:

  • Turn off all RF switches.
  • Set attenuations to be 31.5 dB for all attenuators.
  • Set Urukul clock source to be the internal oscillator, with 100MHz.
  • Set Urukul clock divider to 4.
  • Reset all 4 DDS chips.

Example

publish-mqtt Urukul/Control/Reset

This resets the device.

RF Switch

  • Topic: Urukul/Control/Channel<ch_num>/Switch
    • ch_num: The channel number, from 0 to 3.
  • Message: <off/on>

This command turns off/on an RF switch of a channel.

Example

publish-mqtt Urukul/Control/Channel0/Switch "on"

This turns on the channel 0 RF switch.

Attenuator

  • Topic: Urukul/Control/Channel<ch_num>/Attenuator
    • ch_num: The channel number, from 0 to 3.
  • Message: <atten> [dB]
    • atten: Attenuation of the attenuator of the specified channel. The unit dB is optional. Valid attenuation is within [0, 31.5] (inclusive) in decibel.

Example

publish-mqtt Urukul/Control/Channel0/Attenuator "20 dB"

This sets the attenuation of the channel 0 attenuator to be 20 dB.

Urukul Clock Tree

  1. Clock Frequency

    • Topic: Urukul/Control/Clock/Frequency
    • Message: <f_clk> [unit]
      • f_clk: Clock frequency of the Urukul clock source.
      • unit: (Optional) Unit of f_clk, supports Hz, kHz, MHz, GHz. Hz if unspecified.

    Example

    publish-mqtt Urukul/Control/Clock/Frequency "100 MHz"
    

    This sets the clock frequency of Urukul to be 100 MHz.

  2. Clock Source

    • Topic: Urukul/Control/Clock/Source
    • Message: <clk_src>
      • clk_src: Clock source of Urukul. It can only be OSC, MMCX and SMA.

    Example

    publish-mqtt Urukul/Control/Clock/Source "OSC"
    

    This sets the clock source of Urukul to be the internal oscillator.
    (Note: The internal oscillator should have a frequency of 100MHz, though this command does not setup the clock frequency.)

  3. Clock Frequency Division

    • Topic: Urukul/Control/Clock/Division
    • Message: <clk_div>
      • clk_div: Clock frequency division of Urukul. It can only be 1, 2, or 4.

    Example

    publish-mqtt Urukul/Control/Clock/Division "4"
    

    This divides the clock frequency of Urukul by a factor of 4.

  4. Clock Overall Setup

    • Topic: Urukul/Control/Clock
    • Message: frequency: <f_clk> [unit], source: <clk_src>, division: <clk_div>
      • f_clk, unit, clk_src, clk_div: Same as above.
      • Argument can be permutated.

    Example

    publish-mqtt Urukul/Control/Clock "source: OSC, frequency: 100 MHz, division: 4"
    

    This is identical to the 3 examples above.

DDS System Clock Frequency

  • Topic: Channel<ch_num>/SystemClock
  • Message: <f_sys_clk> [unit]
    • f_sys_clk: DDS System Clock frequency a channel.
    • unit: (Optional) Unit of f_clk, supports Hz, kHz, MHz, GHz. Hz if unspecified.

Example

publish-mqtt Urukul/Control/Chammel1/SystemClock "1 GHz"

This sets the system clock frequency of channel 1 to 1 GHz.

Single Tone Profile

  1. Single Tone Frequency

    • Topic: Urukul/Control/Channel<ch_num>/Profile<pr_num>/Singletone/Frequency
      • ch_num: Channel number.
      • pr_num: Profile number.
    • Message: <freq> [unit]
      • freq: Output frequency of the DDS single tone profile.
      • unit: (Optional) Unit of freq, supports Hz, kHz, MHz, GHz. Hz if unspecified.

    Example

    publish-mqtt Urukul/Control/Channel1/Profile2/Singletone/Frequency "3 MHz"
    

    This sets the output frequency of the single tone profile at channel 1, profile 2 to be 3 MHz.

  2. Single Tone Amplitude

    • Topic: Urukul/Control/Channel<ch_num>/Profile<pr_num>/Singletone/Amplitude
      • ch_num: Channel number.
      • pr_num: Profile number.
    • Message: <ampl>
      • ampl: Amplitude factor of the single tone profile. It ranges from 0 to 1 inclusive.

    Example

    publish-mqtt Urukul/Control/Channel1/Profile2/Singletone/Amplitude "0.5"
    

    This sets the output amplitude factor of the single tone profile at channel 1, profile 2 to be 0.5.

  3. Single Tone Phase

    • Topic: Urukul/Control/Channel<ch_num>/Profile<pr_num>/Singletone/Phase
      • ch_num: Channel number.
      • pr_num: Profile number.
    • Message: <phase>
      • phase: Phase of the single tone profile. The unit is in degree.
      • deg: Optional Specifies the unit of phase to be degree.

    Example

    publish-mqtt Urukul/Control/Channel1/Profile2/Singletone/Degree "0.0 deg"
    

    This sets the phase of the single tone profile at channel 1, profile 2 to be 0 degree.

  4. Single Tone Overall Setup

    • Topic: Urukul/Control/Channel<ch_num>/Profile<pr_num>/Singletone
    • Message: frequency: <freq> [unit], amplitude: <ampl>, phase: <phase>
      • All parameters are the same as above commands.
      • Argument can be permutated.

    Example

    publish-mqtt Urukul/Control/Clock "frequency: 3 MHz, phase: 0.0 deg, amplitude: 0.5"
    

    This is identical to the 3 examples above.

Switching DDS Profile

  • Topic: Urukul/Control/Profile
  • Message: <profile>

Example

publish-mqtt Urukul/Control/Profile "5"

This is selects profile 5 for all DDS channels.