I'm work on a project that needs a "fallback" communication protocol, which will likely end up to be BFSK. The trick is to see if I can capture this entirely in software on the Xmega. The challenge is that the base frequencies are going to be quite fast, probably at least F_CPU/4 and maybe faster if possible.
Now, the trick I've dreamed up would seem to work in theory, but practice is being a little difficult. It seems I'm either misreading the datasheet about a key point, or there's something else going on that's not described properly.
My theory is this: timer #1 is free-running at F_CPU, but the input waveform is routed to an event that is configured with TC.CTRLD = TC_EVACT_RESTART_gc. What that does is cause the counter to start at zero and run up to the number of period of the incoming waveform, then start over.
Now, I set a compare channel to a value that's just above the expected period for the waveform I'm attempting to discriminate. For example, with F_CPU=32MHz and the incoming waveform at 1MHz, the counter should range from 0 to 31 and back, so I set CCA to 33 or 34.
Now, timer #2 is set up at some much slower rate, and what it does is check out the CCAIF bit. If the bit it set, that means the period of the waveform is *longer* than what I'm expecting at 1MHz, and thus the frequency is *higher* than that. If CCAIF is not set, the input freq is lower than that. After each timer #2 fire, it clears CCAIF for the next period.
Now, the theory is that CCAIF *latches* during every timer #2 period (currently 10mS for testing), so any single waveform period that's longer than expected will trigger it. Thus for every period I can determine if the frequency is higher or lower than the threshold, and CCAIF becomes the input bit to an oversampling serial receiver.
If I set CCA to 25, CCAIF should be set for every single sampling period. There are 10000 waveforms, every single one of which should bring the TC.CNT well past 25 and thus latch CCAIF on. However, that is *not* what's happening. I only find CCAIF on a fraction of the time, as if it's either not latching on, or being reset by something.
The best thing I can think would be resetting it would be the RESTART command triggered by the incoming event, which would defeat the purpose of the whole exercise.
The problem is that if this trick doesn't fly, I'll have to look into doing single-shot frequency capture at a very high oversampling ratio, which puts some pretty severe restrictions on the datarate. Alternately, I have the option of adding a PLL with lock detector (e.g. CD7046) and using the lock output as input to a USART, but that's a fair bit outside my expertise...
So, does anybody have any idea why it is that CCAIF isn't latching, or know of another technique that could work reasonably well in software? Or a straightforward example of somebody using a CD4046/7046 as an FSK discriminator?