lneuhaus / pyrpl

pyrpl turns your RedPitaya into a powerful DSP device, especially suitable as a lockbox in quantum optics experiments.
http://lneuhaus.github.io/pyrpl/
MIT License
137 stars 107 forks source link

Acessing DIOs and asg module in parallel #441

Open dermahax opened 3 years ago

dermahax commented 3 years ago

Hi pyrpl community. I am rather new to pyrpl, thus this may be "beginner question" ;-)

I want to synchronize an asg output that I get out of the fast analgues without a problem. Having a fixed phase to this, I want to use the slow DIOs to create a square function in order to trigger an external device. I need the DIOs as these have a 3.3V output.# Still in parallel I am running another thread - reading in some data using the scope module.

So far I have tried:

In both setups, my script runs for a while perfectly. After typically a minute or so I get an error that begins with: ERROR:pyrpl.redpitaya_client:Wrong control sequence from server: b'\xb8\x06(8w\x00\x01\x00' ....... scp.SCPException: scp: //opt//pyrpl//monitor_server: Text file busy

I don't understand what causes the error. Also I feel there is an easier way to create a square function on the DIOs (as I am currently setting high and low "manually").

I would be very happy about any hints or ideas. Thanks

SamuelDeleglise commented 3 years ago

In principle, you should avoid using multithreading, as the communication with the redpitaya is intrisically a single threaded process.

The short answer is to use QTimers if you really need very slow --software controlled-- operations. But really the point of having a FPGA is to have precise timings that don't rely on software and network communication by doing the signal processing directly onboard. I am not sure I understand exactly what you want to do... You have a square 0-5 V signal on in1, and you want to reproduce it with minimum delay on DIO0 ? is that correct ?

dermahax commented 3 years ago

Hi Samuel, thanks for your help :-) Sorry for the bad description. Thus again, in more detail:

I want to have two output signal with a constant phase offset. As one of them needs to have an 3.3V amplitude, one of those signals is generated by the slow DIOs (lets call it "A"). The other one using the arbritary signal generator and thus the fast analgoue output (lets call it "B"), having an amplitude of +- 1 V which is fine.

Signal B is easily generated and works perfectly. Signal A, I currently try reading in signal B, then on rising edge I do:

    r = pyrpl.Pyrpl(config='my_config.yml').rp
    ......
   while True:
        r.hk.expansion_P3 = True
        time.sleep(...)
        r.hk.expansion_P3 = False
        time.sleep(...)

This worked fine, as long as everything ran in the main thread. Now as I additionally need to read in another signal on one of the inputs, I created threads to do so. However, this leads to the above described crash.

As you say Samuel, I also feel like this is not a very good approach as I am not using any of the advantages of the RP. However, I can't yet think of a better solution (except of using the other asg output and use a hardware DC-DC converter....).

Hope that made more sense, Max

dermahax commented 3 years ago

Hey guys, hi Samuel.

I gave this another try - and it is still not working. Thus one last try in this forum here:

Goal: Create a TTL Signal (~100 Hz), using the (slow) DIOs of the RedPitaya. (Hint: The CPU already runs a task in the main thread).

Approaches tested yet:

  1. Using threading with timers. -> Yields problems that socket, to access RP features from different threads, is blocked (as Samuel warned).

  2. Using QTimers: a) Using QTimers in main thread won't help, as far as I understand them, as the task that the main thread currently does, takes too long to not interrupt the TTL signal. b) Create the QTimer and moved it in a QThread. If doing so, once trying to access the RP, the following errors occur. It seems that accessing the RP kills the QThread? (As long as I do "testing work" which does not access the RP, the problem does not occur).

    QObject::killTimer: Timers cannot be stopped from another thread
    QObject::startTimer: Timers cannot be started from another thread

Ideal, of course, would be if I could use the FPGA to do this task...

I would be happy about any hint. Cheers, Max.

ThibaultCapelle commented 3 years ago

Hi,

There is an easy solution to your problem using not the Slow DIO but the GPIOs (extension connector 1), since you want to implement a square wave. It requires to change slightly the verilog code, and to recompile it. To do that you will need to have ubuntu with Vivado 2015.4 installed. You can get a free license for this software. It would also be convenient if you could change the frequency of your signal by changing a register on the redpitaya (i.e. via a python code on your computer) What I did was to transfer the handling of the the GPIOS from the hk module to the asg module (changing the code of red_pitaya_top.v, red_pitaya_asg.v, red_pitaya_hk.v, all three in pyrpl/pyrpl/fpga/rtl/) and to use for the frequency (i.e. the number of clock cycles between a change in your output signal) the address 0x40200240, which is an unused address from the asg module. You set for exemple exp_n_dir_o to a constant, let us say 8'b1 if your want to use the first pin, and play around with the value of exp_n_dat_o, implementing for exemple a counter of clock cycles that will use the value set by the register 0x40200240 or another one of your choice.
Expanding this trick, you can generate up to 16 different square waveforms. You can also do some PWM modulation like that, or use some of the GPIOS as inputs to trigger certain behaviors on the other.

A simpler solution, since you want to generate a low frequency square wave, is to do change the current registers for those GPIOS (they are in the housekeeping module, starting at 0x40000000: http://www.gtronic.it/test/wp-content/uploads/2017/01/Red-Pitaya-register-map.pdf) according to timings from another repitaya python script that would be running in the linux kernel of the redpitaya. This would be less efficient, but would save you the (very small) pain of compiling some verilog code.

Hope this will help you !