I am using No Os reference design for fmcomms1. I wrote functions for handling interrupts
from AXI DMA Controller based on informations that I found here FPGA Reference Designs: PCORE Register Map [Analog Devices Wiki] . Also I use this document to implement interrupt functions:
Two weeks ago Lars suggested me that I should send data on every SOT IRQ in order to make data
continuously flow from PS to PL. I am able to handle IRQ. But I have difficulties with loading new data.
I want to implement continuous streaming of data from PS to PL, to feed my Tx which is implemented on
PL with data. Interrupt handler is working, so probably I am close to make it work.
Here are questions:
1. What you consider as one transfer in this document FPGA Reference Designs: PCORE Register Map [Analog Devices Wiki]
Is one transfer just 64 bits (or 32 bits if we configure bus so), or transfer is complete chunk of X_LENGTH bytes (that we specify
in 0x0418 register) ??? I am confused with this. Because based on what I see from running current code. I see that I get interrupt
after I send 64 bits. So probably in interrupt handler function I should increase SRC_ADDRESS by 8 on every interrupt, to be able to send all X_LENGTH bytes?
2. Based on document CURRENT_SRC_ADDRESS is address from which next data sample is read. What you consider as
sample? Referring to first question, is sample 64 bits or something else?
If you have a sequence which I should follow, please write me. I know that first thing is to Initialize AXI DMA channel by
setting CONTROL on ENABLE... Then to set SRC adress of data, specify length of data (this one is a little bit confusing,
if I get interrupt on every 64 bits why this is important at all)...
Thank you in advance on answers,
I will try to create an example of how this can be done. I will let you know when it's ready.
I've just added an example of configuring the DMAC for multiple transfers using interrupts: https://github.com/analogdevicesinc/no-OS/commit/7a9ddb8a2bc212e26b582c04b6513de1b41aa997
If you are seeing one SOT IRQ for each 64-bits something is definitely wrong. For a SOT IRQ to occur you need to write a 1 to the START_TRANSFER register. The SOT interrupt is the confirmation that…
One transfer is all the full length specified in the X_LENGTH register. The end-of-transfer interrupt will be generated once all these bytes have been transferred. The DMA controller has a internal queue that allows to have multiple descriptors queued in hardware at the same time to allow zero-latency switching between two transfers to enable continuous streaming. If a new slot become available in that queue a start-of-transfer interrupt will be generated. What you are seeing is probably the start-of-transfer interrupt. If you get a start-of-transfer interrupt it means it is possible to program the next transfer into the DMA controller, it does not mean though that the current transfer has been completed.
Hi Dragos and Lars,
I hope Dragos will make example soon, till then I will keep exploring. I masked EOT IRQ, and yes I am seeing SOT IRQ. What I see in Vivado Anlayzer is that I get SOT IRQ after random number of 64bits transactions that I made, not after exact X_LENGTH bytes (so basically it is what you are saying, that EOT IRQ is raised after complete X_LENGTH transfer is finished). That is expected because probably it is not possible to determine exactly when we will be able to load another data. If I load another X_LENGTH bytes even if I do not care about EOT IRQ, that will not cause sort of overlap between transfers? If I understand there is sort of FIFO in DMAC which is capable of storing and scheduling transfers. If so how many bytes I am able to load without overlapping?
Or maybe I should take care of EOT IRQ too? To make some sort of nested if condition and to load just two X_LENGTH transfer at once (and when I get EOT IRQ to load another X_LENGTH transfer)?
Thank you guys, for support.
The example was created for the ADC (I will also add one for the DAC soon), but the process is similar: once the current transfer is started (the SOT interrupt takes place), a new one is queued (no-OS/adc_core.c at master · analogdevicesinc/no-OS · GitHub).
It's a normal queue and the DMA controller will fully process the transfers one by one in the order they have been submitted. So there will be no overlaps. And if the queue is kept filled no bytes are lost in between the transfers.
Since the control interface and the data transfer interface run asynchronously the delay between the start of transfer and the interrupt can differ from transfer to transfer.