Thought I’d share some pictures of my testing setup, plus the code I used!

I set D4 as an INPUT and hooked it to the output of my AFG; D5 was set as an OUTPUT and connected to the AFG’s trigger input. Both of these connections were also routed to two analog inputs on my Scope.

Here’s a nice view of the Core and gear during testing.

The trigger pulse from the Core captured by the Scope. It should be 1mS but is almost 40% too short. On a positive note, the digital output from the Core doesn’t overshoot much and contains very little noise!

AFG setup to send a 25mS pulse 5mS after being triggered.

Another setup for a 500uS pulse.
int i = 0;
int disPos = 0;
void setup() {
Wire.begin();
pinMode(D4, INPUT);
pinMode(D5, OUTPUT);
pinMode(D6, OUTPUT);
digitalWrite(D5, LOW);
digitalWrite(D6, LOW);
}
void loop() {
digitalWrite(D5, HIGH);
delay(1);
digitalWrite(D5, LOW);
unsigned long pulseVal = pulseIn(D4, HIGH);
unsigned long pulseRaw = pulseVal / 0.405;
Wire.beginTransmission(0x4E);
if (disPos == 0) {
Wire.print("CL");
disPos++;
}
else if (disPos == 5) {
Wire.print("TP");
Wire.write(0);
Wire.write(0);
disPos = 1;
}
else {
Wire.print("TRT");
disPos++;
}
Wire.print("TT");
Wire.print(pulseVal);
Wire.print(" / ");
Wire.print(pulseRaw);
Wire.write(0x00);
Wire.endTransmission();
delay(1000);
}
unsigned long pulseIn(uint16_t pin, uint8_t state) {
GPIO_TypeDef* portMask = (PIN_MAP[pin].gpio_peripheral);
uint16_t pinMask = (PIN_MAP[pin].gpio_pin);
unsigned long pulseCount = 0;
unsigned long loopCount = 0;
unsigned long loopMax = 25000000;
// While the pin is *not* in the target state we make sure the timeout hasn't been reached.
while (GPIO_ReadInputDataBit(portMask, pinMask) != state) {
if (loopCount++ == loopMax) {
return 0;
}
}
// When the pin *is* in the target state we bump the counter while still keeping track of the timeout.
while (GPIO_ReadInputDataBit(portMask, pinMask) == state) {
if (loopCount++ == loopMax) {
return 0;
}
pulseCount++;
}
// Return the pulse time in microsecond!
return pulseCount * 0.405; // Calculated the pulseCount++ loop to be about 0.405uS in length.
}
Finally, here’s the code I used for testing. In a nutshell, it fires off a 1mS trigger pulse to the AFG on D5 then runs the pulseIn function on D4 to measure a precisely timed return pulse from the AFG. At this stage the pulseIn function was only returning the number of times pulseCount++ ran in the while loop. It would then print this out as a new line (or wrap to the top) on my OLED display before delaying for one second and starting the whole process over again.
So now, I could setup my AFG to output a pulse (e.g., 500uS) then read the pulseCount++ result on the OLED and by using some simple math determine the amount of time (in microseconds) that one loop took to run.
I then slightly modified the code to display both the raw pulseCount and the microsecond output, so I could tweak the modifier a bit.
That’s pretty much it! Surprisingly this took me almost all night, mainly because I tried reading the input port register another way at first, which ended up being a dead end. Once I got to the point of using the AFG to send precisely timed pulses to the Core, it only took me about two hours to get things tweaked and optimized (and a lot of that was waiting for the core to update OTA, since I was using my iPad in the lab).