Hi Steve,
In the background we've been trying to get some content together that we'll try to steadily release and post to a
nuand-papers repository. (Once we have a few items in there, we'll make a more public announcement.) As I think it'd be worthwhile to get a paper up there that details the entire process from start to finish, I've registered an
issue tracker item for this.
In the meantime, we can try to give you some high-level starting points...
First, you'll need to develop a block in the FPGA to implement your CW generator. Instead of having IQ samples come from the Cypress FX3's GPIF interface (via the fifo reader block), you'll want to supply samples from your custom block.
I would start out by working on and verifying only that, and using the host to load your custom FPGA and configure the device. (The point here is to isolate the scope of changes to a single area.) You can then just use the bladeRF-cli to transmit /dev/zero or something just to get libbladeRF to enable the TX module and let samples start flowing. You should be able to manually retune in the CLI and see your carrier change.
Next, I would look to modify the
NIOS II code to configure the device as you need, and to ignore requests coming from the USB interface (if desired). Specifically, you'll need to understand what libbladeRF is doing when you open a device, enable/disable a modules, and configure the sample rate, and bandwidth. I just pushed a
commit that adds some debug output for each access to the FPGA. An easy way to understand what's going on in libbladeRF is to enable verbose output in the bladeRF-cli, observe what's being written when you make a change, and then dive into the code. I'd even recommend using GDB to run the CLI, so that you could set breakpoints and use a backtrace to see how a particular line got called.
Currently the NIOS II code builds a subset of the lms.c functionality to support retuning. If you have fixed set of frequencies, you can use the verbose output of libbladeRF to determine the LMS6002 values (see the lms_freq structure in lms.h) computed for each frequency. You could put these into a table of in your modified NIOS II code, and then use the lms_set_precomputed_freq() function that's currently being compiled into the NIOS II code to change the frequency.
You could add a timer to the NIOS system and register an interrupt to set a flag once a second. In the main loop, you could check for that flag and update to the next frequency in your table. Don't call functions that interact with the device from an interrupt.
Currently, we don't have si5338 code being built into the NIOS II code. However, this won't be too bad and I can help make the minor changes needed for this.
You'll need to store the FPGA bitstream in flash, so that it can be loaded when the board is powered on. This is document here on the
wiki.
Note that the FX3 firmware is involved in enabling features in the FPGA, which it does via few I/O pins. You can modify the FX3 firmware to set these appropriately at boot, or modify the FPGA to ignore those pins and instead use internal logic. You might want to check how the PCLK from the FX3 is used by the FPGA -- I'm not sure if drives anything other than the GPIF handler, or perhaps other logic. bpadalino might be able to elaborate more on that.
This is a lot of information, and I suspect it'll take some time to get up to speed on the codebase and devices on the board. Let us know if you have further questions, and please do keep us all updated with your progress, if possible.
Cheers,
Jon