Pages

Sunday, 21 January 2024

Serial Data Transmission with RF - Receiving Notes Part 1

 

What follows is some preliminary detail on how I receive the data stream.

The STM8 chips have multiple timers. The simplest timer is 8 bits which is sufficient and was unused by STM8 eForth. I ended up using a lot of assembly code in STM8 eForth to measure the pulse timing. 

Update - with the benefit of hindsight now that it is working I didn't need to use as much assembly code as I used.

I clocked the 8 bit TIMER4 at 250kHz to avoid overflowing when a start pulse was received.

 In pseudo code then a word like: 

: PULSE@ ( -- ) \ measure the time from now till falling edge of pulse
         Turn on the timer      
         Wait for falling edge
         Turn off timer
;

 actually becomes when you can only test for logic levels:

: PULSE@ ( -- ) \ measure the time from now till falling edge of pulse

   TimOn \ turn on the timer
   [ $7200 _RX 2* + 1+ , PD_IDR , $FB C, ] \ wait till _rx is high
   [ $7200 _RX 2* +   , PD_IDR , $FB C, ] \ wait till _rx is LOW
   TimOff \ turn off the timer

This worked really well and could easily handle higher data rates.

However, I later worked out how to  copy the assembly code from a compiled word into a new word avoiding the need for CALLS and RETURNS. This gave me a smoother coding experience and avoided  repeating the assembly code whenever I wanted to incorporate it in a high level word. A bit like a macro in AVR assembler but the destination for the macro is a high level word.

: Pulse@ \ ( -- )  time, now to falling edge
   [ ' TimOn ]M! \ Turn on TIM4
   [ ' _RX=1 ]M! \ wait till _rx is high
   [ ' _RX=0 ]M! \ wait till _rx is LOW
   [ ' TimOff ]M! \ Turn off TIM4
;

While it is not obvious Pulse@ is now just pure assembly with no call's or return instructions. If I decide to use a different timer I only have to change the definition of TimOn and TimOff in one place. Later when I post the full code it will hopefully be clearer.

At this point the code now easily meets any time constraints.  But a better receiver, still to be tested, might allow much faster data transmission so I'm leaving the assembly code in place because I might want to push the data rate still faster one day.

And while all of this only takes a few clock cycles, the longest pulse length we want to measure is a start pulse of around 640uS. If all we were doing was measuring one pulse it would be simpler. But I planned to measure up to 10 pules in succession. My plan is to do some error checking takes after the pulses following a start pulse have been received. 

 




No comments:

Post a Comment