Doe Read TIming

I'll admit I'm new to Arduino, so maybe this is a silly question.

A little background; I needed to greatly decrease my read and write cycle times, as I found the standard library functions (i.e.digitalRead() & digitalWrite()) took way too much time for my application. After much reading of the blogs I finally found that the Due has direct port read and write capability that is (sort of) supported by the IDE and compiler which greatly decrease the overhead. Unfortunately I've not found any complete listing of the compiler keywords that the compiler understands for this purpose, I've only found a few of these and some other hints on figuring out the rest. However I can now read and write to any of the ports with minimum delays using these keywords.
So for example to set bit PC21;
iREG_PIOC_SODR = 0x00200000;
or to reset the same bit:
REG_PIOC_CODR = 0x00200000;
To read an entire port, for example to read port C:
PortC = REG_PIOC_PDSR;

The fact that the Due has redefined the definition of an "int" as a 32-bit value didn't help, until I discovered this fact. :-/

That said, now that I can read and write bits or entire ports values quickly, I need to synchronize my reads and writes. In my case I'm reading a 12-bit bus from a high speed ADC and need to properly time and write a short (~50nS) pulse to trigger a sensor, then read a returned signal that's also ~50nS but some number of nS later. I can time this pulse I'm outputting fairly well by using these direct write commands and NOP's to control the fine timing and duration of the output pulse. But to properly read the return signal I really need to look at it on an oscilloscope and adjust the timing relative to my sensors return signal and the read cycle.

The issue is I don't know exactly when the read is occuring, which makes it a little difficult to time it to within 10's of nS to my return pulse. The only way I've come up with so far is to temporarily replace the read instructions with write instructions to create simulated read timing pulses that I can look at on my scope. I'd imagine this gets me fairly close to the correct timing, and I can add or subtract NOP's until these pulses I'm creating look just right. Once timed using this method I replace the writes with a read of my ADC bus, then hope, but I don't know for sure, that I'm critically timing this read cycle.

I've looked at the Arduino Due schematic and the SAM3X / SAM3A Series datasheet, but have not found any signals that I can look at that would show me the timing of these port read cycles. Any suggestions?

I am not sure to fully understand your incoming signal description, however note that with the default frequency of the DUE, 84 MHz, a clock cycle duration is 11.9ns. Because of this timing, any solution with an interrupt would be irrelevant to read an 50ns incoming signal.

Remains a blocking code solution: the uc waits in an infinite "while" loop for an incoming signal in order to:

1/ Read the 12-bit ADC
2/ trigger an output pulse.

The incoming signal might be a signal indicating that an ADC conversion is ready to be read.

The external ADC datasheet would be useful.

Have you looked into utilizing the External Bus interface for this? You might be able to utilize the SRAM configuration for reading the parallel data with exact timings and without adjusting NOP chains.

Thanks much for the replies.

The ADC is the LTC2293 (https://www.analog.com/media/en/technical-documentation/data-sheets/229321fa.pdf).

I'm not so much worried about adjusting the time I write and read to the precision required, I can do this, just observing the results of my adjustments. I am generating a 50nS pulse within the Due to a (proprietary) sensor that responds with a signal some number of nS after the pulse. I can adjust the timing of the pulse without difficulty, and I can adjust the timing of my subsequent ADC read in the same way, I just haven't found a way to observe exactly when I'm reading relative to the sensors returned pulse other than temporarily replacing the read with an output pulse. In the old days, I'd just clip onto the chip select and the processor read strobe, but since everything is internal in this uC (ATSAM3X8EAU) I've got nothing to hook onto.

The LTC2293 begins a new ADC conversion (sample and hold) on an external clock edge (CLKA or CLKB). Somewhere in the datsheet you should find the time taken by the ADC to output the conversion once the CLK edge is detected.

If you connect the ADC external clock to an input pin of the DUE and read this pin with a PIO_PDSR into a while loop until the correct edge is detected e.g. High, then wait with NOPs or SysTick timer the required time to read the new conversion with another PIO_PDSR.

Eventhough PIO_PDSR is the fastest way to read input pins, there are obviously some limitations to the maximum reading frequency of PIO_PDSR.

BTW you can also provide the external clock to LTC2293 with the DUE via a timer.

Thanks again for the reply.

Yes, the ADC is a bit complicated. I'm generating my own clock pulses (to both multiplexed ADC channels) from the Due with a couple of FOR loops and a few extra clock cycles manually to time my pulse output and to time the reads of the ADC bus. This is at close to the minimum clock rate allowed by the LTC2293; about 1.25MHz. Although this clock signal is a little ragged, this acceptable since I'm using the ADC's internal duty cycle stabilizer circuit and allowing its PLL to lock on to my clock to insure a 50% duty cycle. This works out nicely because since I'm timing the clock output with NOP's, I can insert my output pulse to my sensor wherever I need it to be and then read the ADC at exactly the right time. Since this is a pipelined converter I need to generate five more clocks after the clock edge that clocks in my sample of interest to allow it to progress through the remaining pipeline stages.

Again, this all seems to work, it's just getting the first positive edge of the last six clocks into the ADC timed such that it's coincident with my sensors return signal. And since this is only going to be 50-90nS I need to be sure this edge is in the middle of my signal. Even this I can visualize on my scope since the clocks and the sensor signal are all external, so no real problem there. It's the subsequent two sequential reads of the ADC channels that need to be done very quickly and at the exact right time - just after the final positive edge clock edge of the five cycles after the clock that captured my sample of interest. I just can't see these reads, there's no signals I can connect my scope probe to, so just need to take it on faith that the reads are done fast enough after that final edge, not something I'm generally good at.

Alright, sometimes just describing the problem to someone and talking about it presents solutions.

I've solved my problem practically. Although I still can't "see" my reads, what I can see is the clock pulses and know where they need to be relative to it and my sensor pulses. So, I just set a test output bit true just before I do my ADC reads, then set is false when finished. If this pulse starts just before I need to read the ADC, and ends just before it's too late to finish reading, then I'm golden. And I am.

Thanks.