Hi,
I don't see why you are considering the On-Chip Buffer, because I thought you were attempting to AVOID Writing even a few configuration bytes via SPI, whilst the Buffer will need a large number of Bits or Bytes to be Read over the Bus. I've not read the data sheet(s) but doubt if the chip will be able to interpret "PWM" encoding. In principle what you want to do appears to be much the same as reading simple OOK Radio or even Infra Red Remote Control signals, which I believe you've done before.
Generally, any Radio signal (carrier) will have two parameters, the Frequency and Amplitude, where each might be used to carry either Data (Modulation) or as a "Reference". Amplitude Shift Keying (ASK or OOK) is basically a binary subset of (Analogue) Amplitude Modulation whilst the Frequency is nominally a constant Reference for the channel being received. Prior to modern, precise Crystal-Controlled Frequency Synthesiser receivers, the receiver Frequency could drift, so an Automatic Frequency Control (AFC) system might use a very low-pass filter to correct for this, but could be used instead to detect Frequency Modulation. Frequency Shift Keying is basically a Binary subset of Frequency Modulation, where the (transmitted) Amplitude will be constant, with the received Amplitude being either "Don't Care" or stabilised with an Automatic Gain Control system (cf. AFC).
Therefore, both FSK or ASK modulation systems will deliver just two output voltage levels, nominally named 0 and 1. But a "One Wire Bus" (which is basically what a Radio or IR RC channel is) needs some method for Synchronisation, typically a "Start" or "Framing" pattern, a "Stop" or other method of End detection, a "known" bit-length period and maybe a method of error-detection. "RS232" is perhaps the best known and used protocol, where the Data Line has an Idle Level (often "1") and the Start (pulse) is initiated by a change of Level. Then the Data Bits are polled at times of 1.5T , 2.5T up to 8.5T (or also 9.5 or 10.5T for Parity and/or Stop Bits) where T is the nominal Bit (or Baud) period. The Stop bit is actually at the Idle Level, so a subsequent byte can follow immediately (i.e. be concatonated), or after ANY arbitrary delay, if using an Asynchronous UART.
A problem with RS232 is that the timing accuracy must be better than about +/- 5%, which can be tricky with a simple R-C oscillator, but the main problem is that many Higher-Level Computer languages (of which PICaxe Basic is one) have little concept of the flow of time. Thus the predominace of Two-Wire (or more) Buses, such as I2C or SPI (3 or more wires, because Read , Write and Enable Lines are separate), so that the "Host" can specify when each bit-period is to Start and/or Stop. But for One-Wire systems we must adopt a protocol which is tolerant of large timing errors (or "unknowns"), for example Pulses or Gaps of ratio 2 : 1 or even greater.
The PULSIN command in PICaxe Basic is one of the few ways available to measure time intervals but it has several issues. Firstly it measures the interval between two pulse-edges, so it CANNOT measure the width of the subsequent (or prior) "Gap" or Idle period. Secondly, a potential problem is that it creates a WORD value which is not compatible with the often necessary @BPTR (INC) variable. If selecting one Byte from the Word, the LSB resolution is just over 1 microsecond (at 32 MHz clock) which may be unnecessarily short, but the MSB resolution is over 300 us, sometimes "too long" to accurately identify Short and Long Pulses or Gaps. Furthermore, the whole PULSIN command requires a Run-In period (where the Interpreter reads and decodes the instruction token and initialises the measurement), a measurement period which "counts" whilst the input signal is stable, and a Run-Out where the result is stored or reported. Thus the execution time may be significantly longer than the actual Pulse, and in the case of a Square Wave (i.e. 1 : 1 duty cycle) there may be little (or no) time to "close the loop" in preparation for the next Pulse.
Thus many RF/IR communication protocols (such as the Watson / Fine Offset, SIRC , NEC , etc.) vary either the "Pulse" or the "Gap" in the carrier waveform, but NOT both. However, the wavforms in posts #5 and #22 above show BOTH the Pulse and the Gap changing (as also happens with Manchester Coding and RC5, etc.) so you CANNOT use the PULSIN command. Thus I think the only solution is to Bit-Bang a fast and efficient Algorithm, which does at least obviate the need to "Post Process" a sequence of PULSIN results, and to detect when a "Data Packet" has ended. Sometimes the End Of Packet can be detected by simply counting the number of Bits or Bytes received, or by detecting a Long Idle Time, but this may fail if there are any "Interference" signals from other systems (using either a similar or totally different protocol).
I have been considering writing a "Hints and Tips to Faster Bit-Banging (for RF and IR Protocols)" in a suitable thread, but now is not an ideal time, so I'll just give a few Bullet Points here:
+ Never use Subroutines, nor "slow" instructions such as SWAP and PWMDUTY. These can sometimes be detected from the number of bytes they add into the program (so do a Syntax Check with the instruction active and commented out). Interrupts are risky unless the program is expecting them (for example executing a PAUSE), and the RETURN is slow.
+ The best flow control is the
IF {pin , bit or variable } {Conditional expression}
THEN GOTO label instruction, noting that the Fall-Through (i.e. Not True) path is faster than the GOTO path. Therefore, direct the GOTO into the "acceptably slower" path and/or take advantage of "jumping backwards" in the program, to help close any Loops (i.e. avoid the Unconditional GOTO whenever possible).
+ Sometimes using the BITn variables contained within b0 to b3 can save some time. Note that the ON {variable} GOTO (aka the BRANCH instruction) can use just a single label (for a bit or variable zero value) with both the Fall-Through and Jump paths slightly faster than the IF .... THEN .. construct.
+ PAUSEUS has rather a high overhead (almost 100 us at 32 MHz) so use with caution. PAUSE 0 is about twice as fast as PAUSEUS 0 , if you need some padding. PAUSEUS and PULSOUT actually have exactly the same execution times, so PULSOUT can be useful for test markers during development or debugging.
+ Use @BPTRINC in place of @BPTR when possible because the execution times are identical (but beware there are some bugs in the more complex constructs, e.g. using POKE/PEEKSFR). Also, WORD execution times are exactly the same as for BYTES, so when handling serial bits a Word variable may reduce the number of necessary operations.
+ If a Program Loop takes too long, then partial Linear Coding may help. Recently, I went rather Off Topic in post #33 of
This Thread discussing my "Butterfly" Program Structure for faster Bit-Banging.
Cheers, Alan.