Skids - what does the input look like?
Is it a fixed number of bits, or a small number of bits?
Is there a big gap (silence) between data 'packets', with plenty of time for the data to be used/processed?
My experiments wiggling output pins, showed 12MHz was the fastest practical speed (executing from Flash).
That was:
- 2 cycles to update a pin to 1
- 2 cycles to update a pin to 0
- 2 cycles for the while(true) loop
A for
loop would make this slower, and any tests on the data would make it slower still.
I would suggest at 1MHz, sampling in software, and deducing something about the signal is not a good way to go.
But you could try option 1 at low speed to get a feel for the approach.
Option 3
As poslathian said, it will be very hard to make it work using interrupts to trigger sampling, just because it will consume quite a lot of time bouncing in and out of an interrupt.
Any approach using interrupts to directly capture the pin value will consume quite a lot of processor cycles, and runs the risk of losing information if other interrupts are happening. You'd need to switch off the USB and underlying timer interrupt (systick).
I can't seem to find the right document page, but AFAIK, the minimum interrupt response time on the STM32F, is an optional 1 instruction depending on when the input to the GPIO happened, 6 cycles to stack registers and start using the interrupt handler (I assume worse if it uses attach interrupt), and 6 to return from the interrupt.
So worst case, almost 14 cycles, normally 12.
So that would be a maximum sample rate of 6MHz, ignoring the cost of doing anything with the data. Of course, 5 times out of 6, the data will not have changed!
In the interrupt handler, I'm assuming it doesn't have to figure out which pin, as it is the only thing hanging on that port. If that assumption is incorrect, it will get much slower.
An interrupt routine will need to have some state in memory, which gets updated, so 4 cycles per variable, plus time to do an operation on the variable.
So I don't see it being much shorter than 20 cycles/interrupt, and easily much slower, so 3.5MHz would be the maximum sample rate. Clearly it might get damaged if there were another event, like the system clock, or USB, which caused it to miss a signal transition. If it missed two transitions, then it would be harder still.
Option 4
I think the 4 is not as easy as it sounds because a different interrupt could cause a bit to be dropped.
I assume the input capture pin would be used, and so the resolution could be full clock speed, i.e. of 72MHz.
Option 5
IMHO, a better way than 4 is to have the timer channel 'capture' the timer clock when the external signal edge transitions. This gets a reasonably stable value and doesn't depend on the interrupt service routine (ISR) timing to get the clock time.
An ISR needs to be triggered when the signal transition time is captured, so it is only triggered at roughly 1MHz. The ISR copies the value from the channel's capture register to memory, or even decodes it there and then. The ISR resets the clock ready for the next signal transition.
If you are very careful, you may get this to run continuously, i.e. there is no need to have any 'silence' when no signal is being received. I am SWAGing, but maybe it'll consuming about 50% of the processor cycles, or maybe less.
Option 6
A merging of option 5 and option 2
Use DMA to store the times captured by the timer channel, into memory, and process them in the main loop. I'd need to look to see that the DMA can reset the timer, but if it can, then many edges can be captured without spending cycles on a per/transition interrupt. This depends on understanding how to use DMA and the timers properly, which is quite intricate on the STM32F.
Without hardware help, debugging it will be hard, so start off with a slow signal, and measure.