Encoder Home

List Articles by...
Issue
Topic
Author
Encoder logo

2.4 GHz Wireless Link

by Johan Jordaan Winter 2006

So… You want to mess with 2.4Ghz?

Following is a description of the trials and tribulations of trying - and eventually succeeding - in firing up a 2.4GHz link system for a commercial project. The long hours and hysterical panic of trying of meet deadlines, has prompted me to share this account with others that they are spared the frustration and despair.

I think most people go in search of the modular (and hopefully, simple) approach. There are a number of solutions on the market and it seems the more prolific of these tend to be based on the Nordic Semiconductor nRF2401/2. There are the Freescale and other Zigbee modules, but thus far, the cost has been a factor and the very new modular boards are still fairly few and far between. This option was entertained for a while but dropped - also on the basis of expediency - having to plug-in and interface to, the SMAC firmware. By far the most cost effective modular solution is undoubtedly the nRF240x-based units.

Now, before we launch headlong into the technicalities here… there are some ground rules! Start by making sure the gun safe is locked and Mommy has the key hidden in a safe place. Also sharp and pointy objects that may come to hand in a fit of despair… lock in the toolbox and hand Mommy the key. Good idea to ensure spousal relationship is on a good footing lest one inadvertently fast tracks her to your life insurance policy!

Like any good hacker/engineer/technician, the first thing you need to do is arm your self with ALL the help you can find. Datasheets, application notes and anything else you can find lying around on the Internet that pertains to the problem at hand. Trust me, there isn't a whole bunch of information out there, outside of the tired old, incomplete datasheets. Interestingly enough, I found a number of ".edu" sites that have attempted the 2.4G link with exactly these modules and abandoned them along the way. Invariably citing time constraints in getting other aspects of the their (sometimes, very ambitious!) projects done… sad, but it alludes to the problems most new-comers face.

I bet most of us have read datasheets and been left with more questions than answers! There is always this empty feeling of "…yes, but what about…this…that… and the other…". Always a million questions. It is these gaps and undocumented pitfalls I am trying to address here… All the usual stuff can be found in all the usual places.

At the onset, I was looking for a "quick and dirty" solution. Not necessarily one I would stick to, come time to go to mass production, but something to get me off the ground and would prove the feasibility of a 2.4Ghz link in the commercial project being prototyped. Thus it was I came upon the Laipac Tech TRF-2.4G. The real inspiration was that their office was a stones throw from where I live! This is not a metaphor I use lightly - after the third phone call for technical support went unanswered, the vision of large plate glass window and airborne brick had huge appeal! The Jewish have this wonderful expression… "If you're looking for a helping hand, it's right there! At the end of your own arm…" This brings us to my Universal Truth #1: Just because you bought their junk, don't expect them to support it after they have been paid - you are on your own now. But I digress…

I'm from Missouri - show me…

For those of you still reading at this point, the first rule of setting up a two way link is, if you cant see what you're doing, you can never be sure of what you're doing. There are few things that will more effectively test your sanity than to attempt a 2-way RF link when you are not sure that at least ONE part is working as it should.

This is a strong recommendation: The time and effort it takes to build a rough and ready field strength meter, is MORE than worth it. It need be nothing more than a tuned circuit (for 2.4GHz obviously), a detector diode, and a d.c. meter amplifier (with lotsa gain!). Somewhere attached to this article is the schematic and some happy-snaps of my version of just such an instrument. More on this jiggly box later…

The TRF2.4G

The Basics…

The TRF-2.4G has two modes - direct and burst. Nice! You say… We'll use burst… Not so fast Tiger! This "burst" thing necessitates you to go messing with the dreaded config-beast. If the hapless TRF device is a lemon, or been Van de Graff'd to death, a lot of time is going to go down the pipes before the penny drops. Much easier solution…

Lets start with some facts you may have missed or will not find in the data sheets…

The nRF24xx fires up with default values - in the direct mode, but so what? If you apply Vcc and Gnd and toggle the "CE" input, it WILL transmit … Better yet, it will be a good, broad burst of RF, plainly visible on the FSM. So, without any great to-do one can prove that at least the device works. Not a very gung-ho approach, but I suspect there are many readers that have back peddled from streaking ahead and being stuck in dead-end allies. Further down the road, one can change the config parameters and see the envelope differences in 1Mbps/250Kbps, the steps in power settings, etc., all visible on the, now famed jiggly box.

It does need to be said… I too have stared at the datasheets and marveled at the convoluted English and seemingly contradictory statements surrounding the config settings. Don't we just love this working in "bits" stuff! It's a dastardly plan to drive rational engineers to hara-kiri at 3:00 a.m. I tell you! [Remember those ground rules in the beginning?] But I digress…

There's not much to say about the chunk of hardware, expect maybe to lament the seriously unfortunate choice of connector - dual row, 1.25mm pitch - what were these people thinking?? Try finding a matching socket for that puppy! One can get a sensible little "break-out" board from Sparks Fun Electronics at $1 a piece, that will adapt to the garden variety 0.1" connector we all know and love. The Spark Fun people also have their own version of an nRF2401 based transceiver that I have yet to try out - that one comes with… you guessed it, 0.1" connector! Had I known at the time…. On the plus side, the TRF-2.4G is about as small as I've seen these modules and the integrated antenna saves more horsing around with connectors and trying to match bits of wire. All in all… it is a wonderfully dinky solution.

In the ever shrinking world of wireless and my failing eyesight, there is this growing tendency toward fewer pins and serial I/O. No less so with the nRF240x family of devices.

This is the part that really sent me off into the middle distance when I first started this RF-link trip. There is so much left unsaid in the datasheets, both from Laipac Tech and Nordic Semi. Even the "said" bits of information tend to be confusing, particularly when it comes to the "what if's…" that apply to your unique requirements.

In a nutshell, there are two serial registers. The configuration register and the data register. Their respective control signals are fairly well explained in the datasheets.

The config register is an input-only situation, which in my humble opinion, is unfortunate. There is absolutely no way of reading back what has been sent. Of course this is academic once the system works, but in getting there, it would be useful. Enter the jiggly box once more… if, in testing you see a TX blip longer than 1mS, you are in direct mode and your config string has missed the potty! You are not configured. The 250Kbps speed (with about 20 bytes… sorry, 160 bits…) will show about a 1mS blip. Obviously 1Mbps will be less. The direct mode showed up as a 30mS blip in my tests, which makes it quite easy to discern a hit or miss on the config setup.

Note! You will have about a 10dB better receive S/N @ 250Kbps - this is noted in the datasheet.

Despite the config register setup being addressed more than once in the datasheet, I found this more confusing than helpful. The only way forward was to take multiple stabs at the config register until things started to take shape. The register will accept at least:

  • 144 bits (18 bytes) - The top 24 bits reserved for "testing". There is no documentation stipulating testing for what and by whom! So this is better avoided. It is not required of you to input data here for the proper functioning of the device (the defaults after power-up are valid). A little fact not expressly highlighted in any documents I have in my possession.
  • 120 bits (15 bytes) - This is where life gets tricky if one thinks too deeply. To wit: A 40 bit address field for heavens sake! What does one do if one has no need of such extravagance? A "duo-channel receiver"… really? Like we are not having enough difficulty getting ONE channel going, we now get lumbered with two - and then it needs config bits too - or does it? The available datasheets do not explain this at all well. The temptation is to toss those bits overboard - bad idea! The real story is this - YOU ABSOLUTELY HAVE TO SHOVE at least 120 BITS into this black hole on the FIRST config upload if you intend to use the "burst" mode!
  • The bits related to the second channel can be anything you like, but they do have to be there. This means that even if you elect to use an 8-bit address, you still have to pump 5 bytes of address field in the config string - 4 of them will be ignored and can be 0's. After the first config upload, the device can be adapted by a "partial" upload. These can be either…
  • 8 bits (single byte) - that can update the channel frequency and/or RX/TX mode, or…
  • 1 bit - that will switch between TX and RX. A simple "1-bit stuff" routine is all that is required here. Of course we would all have preferred a PTT input pin here, but this is what we are stuck with.

I have this suspicion that nRF240x 'processor' is intelligent enough that the config string (after the first upload) can be ANY length, not exceeding 144-bits and only those parameter-bits that reach up into the config register will be updated. Watch the parameter boundaries - I don't think it will like half parameter updates.

Another hugely important concept not explained very well in the datasheets I have, is this unavoidable ADDRESS that is such an integral part of the TRF device. It is important to keep in mind that the ADDRESS defines the address of the local receiver - the device you are working with. The transmitter does not have an address, BUT… it does have to output the address of the destination receiver immediately ahead of the payload data. The lack of address, or equally, a wrong address will be missed at the receive end. I found it easier to stick to one address for both receivers, since I was half-duplex-ing. This address scheme is a powerful tool in networking environments for those who have need of it.

Two quick "yellow stickies" to hang on your monitor as you read this…

  • Heed the "CS" and "CE" conflict rule - they may never both be active (high).
  • Ensure your config pump up routine goes MSBit first.

These are simple things that are fairly easy to get wrong when writing source code in the small hours of the morning.

Turning to the data register; The datasheet is fairly explicit in pointing out that the pre-amble and CRC are internal functions - no problem there, It took a little longer to acclimatize to the concept of ADDRESS+DATA out, but only DATA in (discussed a minute ago). I don't like writing single chunks of wildly complicated assembly code to address the IN and OUT issues in one hit. Hellish to debug! Later when the software discussion comes up, it will be obvious I have taken the lesser-evil route. Suffice it to say for now, the IN and OUT routines will differ in that the TX upload requires the number of bytes/bits you have elected to use for the address, to be added in ahead of the data.

Much has been said here about the TX end of this project and all the wonderful things the FSM will do in helping… Come time to receive however, it's a whole different kettle of fish. Truthfully, it either works or it doesn't and the only advice I can give here is this. There are just two factors at play here - the first being the receive download routine or, and far more likely, the address bytes are forgotten/messed up/backwards (MSB, remember!). If you are going 2-ways (half duplex), the address must be the same at both ends and both TX's must include the address of the destined receiver - it was this that had me fall off the wagon, since it's the silly, simple things we tend to loose sight of When the DR1 line goes high, hit the save key on the text editor - you're done with the config end of things All that's left now is to suck your chosen number of bits out of the TRF, format them into bytes and stack them away.

Now I have a confession to make. I use REAL microprocessors. None of this PICky stuff, or worse yet, the MCS Intel/Philips (31/51 and derivatives) that have been on artificial respiration and dialysis for the last two decades… Real mucho-dudes use MOTOROLA! (okay, Freescale if you must). This is not the best part though… The real joy-of-joys is the software - fast, compact, control down to the last bit - you guessed… Assembly Language!

Since this screed originates from a commercial venture that has me pinned down with non-disclosure clauses, I can only present a snippet of the overall schematic and the relevant software. Nonetheless, I'm sure the information pertaining to this discussion will be complete and can be duplicated without any loose ends. After all this verbiage, its time for pictures!

The only piece of schematic you need from me… Nothing fanciful about these interconnects and essentially any port will do. Hereafter it's just a series of bit banging.

On the other end of my RF link I needed the KBI (PTA) feature and did not need the SCI.1 port so the TRF moved to PTE. It was dead simple to adapt the software. Talking of which…

This is what you really came here for… Lest I be accused of leaving some stone unturned, and I beg the indulgence of the software whiz kids here, I will deluge the entire listing of the relevant code in the next few pages.

I tend to use "*.inc" files fairly heavily, to break the mile-long software listing. Also, I tend to comment prolifically This is for MY good. I find I forget my train of thought shortly after I write the code and the comments "re-align" me when I come back after an absence.

First, an extract from the "equate.inc" file… Not much to comment on. Identify the memory locations as they come up in the later subroutines.

 

**************************************************************
* Application Specific Equates                               *
**************************************************************
asciiCR:    equ   $0D            ;ascii carriage return
asciiLF:    equ   $0A            ;ascii linefeed
;
VectorStart equ   $FFCC
;
**************************************************************
         org RamStart
;
status      rmb !1                ;Machine Status byte
;                       76543210
;                       ||||||||
;                       |||||||+- SCI #1 RX data pending
;                       ||||||+-- SCI #2 RX data pending
;                       |||||+--- TRX - RX data pending
;                       ||||+---- Undefined
;                       |||+----- Undefined
;                       ||+------ Undefined
;                       |+------- Undefined
;                       +-------- Undefined
;
 
count16a    rmb !2                ;General Purpose 16 bit Counter #1
count16b    rmb !2                ;General Purpose 16 bit Counter #2
count16c    rmb !2                ;General Purpose 16 bit Counter #3
count16d    rmb !2                ;General Purpose 16 bit Counter #4
;
count8a     rmb !1                ;General Purpose 8 bit Counter #1
count8b     rmb !1                ;General Purpose 8 bit Counter #2
count8c     rmb !1                ;General Purpose 8 bit Counter #3
count8d     rmb !1                ;General Purpose 8 bit Counter #4
count8e     rmb !1                ;General Purpose 8 bit Counter #5
;
**************************************************************
* TRANSCEIVER INPUT/OUTPUT DATA REGISTERS                    *
* These reserved memory locations store the input and output *
* blocks of information transfered by the transceiver module.*
**************************************************************
* Transceiver Received data:                                 *
*------------------------------------------------------------*
RXdata      rmb !20               ;TRF2.4G Receiver Register
RXbcnt      rmb !1                ;RX data bit count
;

Forgive the 1-byte at a time listing that follows, but it suits the way I use this data in the prototype application. Readers will change this to suit themselves.

**************************************************************
* Transceiver Data for TX. Payload:                          *
* Rec.addr. = 40 bits (5 bytes)                              *
* Data bytes = 160 bits (20 bytes)                           *
*------------------------------------------------------------*
recaddr     rmb !5                ;Receiver address
txmdat01    rmb !1                ;Switch Input Register #1
txmdat02    rmb !1                ;Switch Input Register #2
txmdat03    rmb !1                ;Switch Input Register #3
txmdat04    rmb !1                ;Switch Input Register #4
txmdat05    rmb !1                ;HE Sensor Input Register
txmdat06    rmb !1                ;Travel Switch Input Register
txmdat07    rmb !1                ;Aux. data byte
txmdat08    rmb !1                ;Aux. data byte
txmdat09    rmb !1                ;Aux. data byte
txmdat10    rmb !1                ;Aux. data byte
txmdat11    rmb !1                ;Aux. data byte
txmdat12    rmb !1                ;Aux. data byte
txmdat13    rmb !1                ;Aux. data byte
txmdat14    rmb !1                ;Aux. data byte
txmdat15    rmb !1                ;Aux. data byte
txmdat16    rmb !1                ;Aux. data byte
txmdat17    rmb !1                ;Aux. data byte
txmdat18    rmb !1                ;Aux. data byte
txmdat19    rmb !1                ;Aux. data byte
txmdat20    rmb !1                ;Aux. data byte
;

Moving along to the 'initial.inc" file, we set up Port "A"

**************************************************************
* Transceiver Interface Port Initialize                      *
**************************************************************
Init_PTA:                          ;Transciever port
          ldx   #%00011010
;                 ||||||||
;                 |||||||+-- Data (bi-directional)
;                 ||||||+--- Clk1 (Output Tx & Rx)
;                 |||||+---- DR1  (Input "data ready")
;                 ||||+----- CS (Output - Config. reg. select)
;                 |||+------ CE (Output - Communication Enable)
;                 ||+------- Not Used
;                 |+-------- Not Used (no pins)
;                 +--------- Not Used (no pins)
          stx   PTADD              ;Set Data Dir.
          mov   #$00,PTAD          ;Clear port
;

The bits we've all been waiting for - the "trxsys.inc" file.

This covers all the sins we have to commit to make the TRF-2.4G perform. This file, with the changes to PTA and PTE I mentioned earlier, works for both ends of my RF-link. A couple of things to note here…

This is a collection of routines that perform the following functions:

  1. (TRFcfg) The configuration routine that pumps up the config register in the TRF device. In addition, I load the RAM locations in the TX output string (remember the ADDRESS+DATA string that must be TX-ed). It is important to note that the routine controls only the "CS" input to the TRF. It is assumed that "CE" will be inactive at this time. The same holds true for the next two routines…
  2. The "Program for Transmit" (TRXptx). A 1-bit bang routine!
  3. The "Program for Receive" (TRXprx). Ditto.
  4. The Transmit routine (TRFxmt). Here we control only the "CE" input. "CS" is assumed to be inactive.
  5. The "Received data Download" routine (TRFrec). The important thing to note here is that this routine only downloads the data if "DR1"=1 - it does not set up the conditions for the TRF to be able to receive. Setting the config register D0=1 and "CE"=1 are controlled in the main body program. I will show a sample of such a Rx -> Tx -> Rx switching listing towards the end of this article. I have not done so here, but it is permissible to switch "CE" low early in the routine, to save power. If "DR1"=0, the program pops right out again.

I succumbed to the allure of the 5-byte (40 bit) address - why not - its there, and I did note from another source that it helps overcome false receives. I have not done any real experimentation here and I'm prepared to accept this as good advice at face value. The same source also recommended the 16-bit CRC option that I have adopted without question.

In the Configuration Table, I list 18 bytes - I don't actually use the top 3 bytes. Just haven't cleaned up my act yet.

**************************************************************
*      = GENERAL NOTES ON TRANSCEIVER SUBROUTINES =          *
*      --------------------------------------------          *
* Routines included here are;-                               *
* 1. Transceiver configuration routine - sets up the TRF2.4G *
*    Includes both TX and RX parameters in a 120 bit string  *
*    organized as 15 x 8 bit contiguous bytes.               *
*    NOTE! The TX / RX switching is embedded in this config  *
*          programming (the LSB of the 120 bit string).      *
*          It is located in the byte TRX001, bit 0.          *
* 2. Program Transmit routine - sets the LSB in the TRF2.4G  *
*    config. register to enable transmitting when "CE" is    *
*    activated.                                              *
* 3. Program Receive routine - sets the LSB in the TRF2.4G   *
*    config. register to enable receiving when "CE" is       *
*    activated.                                              *
* 4. Transceiver data transmit routine - Loads the data to   *
*    be transmitted into the TFR2.4G and initiates the       *
*    transmit function.                                      *
* 5. Transceiver data-received download routine - Down loads *
*    the data received by the TFR2.4G and saves it to memory.*
*    NOTE! This routine only downloads the stored data from  *
*    the transceivers receiver section once DR1 ( the data   *
*    received flag) is set - it does not enable or initiate  *
*    the devices receive sequence.                           *
*                                                            *
**************************************************************
* Transceiver configuration output routine:                  *
* The following ports apply...                               *
* PTA0 = Data (bi-directional)                               *
* PTA1 = Clk1 (Output Tx & Rx)                               *
* PTA2 = DR1  (Input "data ready")                           *
* PTA3 = CS (Output - Config. reg. select)                   *
* PTA4 = CE (Output - Communication Enable)                  *
* PTA5 = Not Used                                            *
*                                                            *
**************************************************************
TRXcfg    bset  0,PTADD           ;Set D0 as output
          mov   #!15,count8a      ;Set byte counter
          mov   #!8,count8b       ;Set bit counter
;
          bset  3,PTAD            ;Set "CS" high
          ldhx  #$000F            ;Set delay (>5uS)
          jsr   delay1            ;Do delay
;
          ldhx  #TRX015           ;Get start of bit field
trxc01    lda   ,X                ;Get data byte
trxc02    asla                    ;Shift D7 -> (C)
          bcs   trxc03            ;C=1, skip
          bclr  0,PTAD            ;Make dataline = 0
          bra   trxc04            ;Skip
;
trxc03    bset  0,PTAD            ;Make dataline = 1
trxc04    nop                     ;Wait (Ts > 500nS)
          nop                     ;Wait...
          nop                     ;Wait...
          bset  1,PTAD            ;Set "CLK" high
          nop                     ;Wait (Th > 500nS)
          nop                     ;Wait...
          nop                     ;Wait...
          bclr  1,PTAD            ;Set "CLK" low
          nop                     ;Wait...
;
          dbnz  count8b,trxc02    ;Step -1 byte-bit count
          aix   #1                ;Step +1 byte addr.
          mov   #!8,count8b       ;Reset bit counter
          dbnz  count8a,trxc01    ;Step -1 byte count
;
          bclr  3,PTAD            ;Set "CS" low
          bclr  0,PTADD           ;Set D0 as input
;
* Now move receiver #1 addr. into TX payload string...
* Its only 5 bytes... do this the easy way!
;
trxc05    lda   TRX008            ;Get addr. byte
          sta   recaddr           ;Save it...
          lda   TRX007            ;Get addr. byte
          sta   recaddr+1         ;Save it...
          lda   TRX006            ;Get addr. byte
          sta   recaddr+2         ;Save it...
          lda   TRX005            ;Get addr. byte
          sta   recaddr+3         ;Save it...
          lda   TRX004            ;Get addr. byte
          sta   recaddr+4         ;Save it...
trxcxt    rts                     ;exit
;
**************************************************************
* Program TRX for transmit:                                  *
* See "Transceiver Configuration data" below. (& dataheet)   *
* Config byte 'TRX001' - bit-0                               *
**************************************************************
TRXptx    bset  0,PTADD           ;Set D0 as output
          bset  3,PTAD            ;Set "CS" high
          ldhx  #$000F            ;Set delay (>5uS)
          jsr   delay1            ;Do delay
          bclr  0,PTAD            ;Make dataline = 0 (TX)
          nop                     ;Wait (Ts > 500nS)
          nop                     ;Wait...
          bset  1,PTAD            ;Set "CLK" high
          nop                     ;Wait (Th > 500nS)
          nop                     ;Wait...
          bclr  1,PTAD            ;Set "CLK" low
          nop                     ;Wait...
          bclr  3,PTAD            ;Set "CS" low
          bclr  0,PTADD           ;Set D0 as input
          rts                     ;exit
;
**************************************************************
* Program TRX for receive                                    *
* See "Transceiver Configuration data" below. (& dataheet)   *
* Config byte 'TRX001' - bit-0                               *
**************************************************************
TRXprx    bset  0,PTADD           ;Set D0 as output
          bset  3,PTAD            ;Set "CS" high
          ldhx  #$000F            ;Set delay (>5uS)
          jsr   delay1            ;Do delay
          bset  0,PTAD            ;Make dataline = 1 (RX)
          nop                     ;Wait (Ts > 500nS)
          nop                     ;Wait...
          bset  1,PTAD            ;Set "CLK" high
          nop                     ;Wait (Th > 500nS)
          nop                     ;Wait...
          bclr  1,PTAD            ;Set "CLK" low
          nop                     ;Wait...
          bclr  3,PTAD            ;Set "CS" low
          bclr  0,PTADD           ;Set D0 as input
          rts                     ;exit
;
**************************************************************
* Transceiver Configuration data. (See dataheet)             *
* Note: These bytes are sent serially to the configuartion   *
*       register of the transceiver, starting with the byte  *
*       "trx015". 120 bits are sent starting with the MSB.   *
*                                                            *
* The configuration shown below sets the TCVR up as follows; *
* (From trx001 to trx015)
* - Receive mode                                             *
* - Channel #1                                               *
* - Single channel                                           *
* - Burst mode                                               *
* - 250Kbps bit rate                                         *
* - Default Osc. setting                                     *
* - Power setting = Max.                                     *
* - Address width = 40 bits                                   *
* - CRC width = 16 bits                                      *
* - CRC enabled                                              *
* - Primary channel address = 40 bits (arbitrary)            *
* - Secondary channel address = 40 bits (arbitrary, not used)*
* - Primary chan. data width = 200 bits                      *
* - Secondary chan. data width = 200 bits (not used)         *
* - Test bytes (3x). Fixed data - DO NOT ALTER!              *
*                                                            *
**************************************************************
TRX018      fcb  %10001110        ;Fixed Test Data
TRX017      fcb  %00001000        ;Fixed Test Data
TRX016      fcb  %00011100        ;Fixed Test Data
;
TRX015      fcb  !160             ;Data width RX2 (in BITS!)
TRX014      fcb  !160             ;Data width RX1 (in BITS!)
;
TRX013      fcb  $CC              ;Addr. byte 5/RX2 [Bits 96 - 103]
TRX012      fcb  $55              ;Addr. byte 4/RX2 [Bits 88 - 95]
TRX011      fcb  $AA              ;Addr. byte 3/RX2 [Bits 80 - 87]
TRX010      fcb  $55              ;Addr. byte 2/RX2 [Bits 72 - 79]
TRX009      fcb  $AA              ;Addr. byte 1/RX2 [Bits 64 - 71]
;
TRX008      fcb  $AA              ;Addr. byte 5/RX1 [Bits 56 - 63]
TRX007      fcb  $55              ;Addr. byte 4/RX1 [Bits 48 - 55]
TRX006      fcb  $AA              ;Addr. byte 3/RX1 [Bits 40 - 47]
TRX005      fcb  $55              ;Addr. byte 2/RX1 [Bits 32 - 39]
TRX004      fcb  $AA              ;Addr. byte 1/RX1 [Bits 24 - 31]
;
TRX003      fcb  %10100011        ;Address width & CRC
;                 ||||||||  [Bits 16 - 23]
;                 |||||||+- CRC Enabled (1) TX & RX
;                 ||||||+-- 16 Bit CRC (1). 8 bit = 0
;                 |||||+--- Addres W.bit 0 ( NOTE! Max =40 )
;                 ||||+---- Addres W.bit 1 SET UP FOR 40 bits!
;                 |||+----- Addres W.bit 2
;                 ||+------ Addres W.bit 3
;                 |+------- Addres W.bit 4
;                 +-------- Addres W.bit 5
;
TRX002      fcb  %01001111        ;RF Mode
;                 ||||||||  [Bits 8 - 15]
;                 |||||||+- RF Power bit 0 (1)
;                 ||||||+-- RF Power bit 1 (1)
;                 |||||+--- Xosc bit 0. Always 1
;                 ||||+---- Xosc bit 1. Always 1
;                 |||+----- Xosc bit 2. Always 0
;                 ||+------ Data rate 0=250kbps, 1=1Mbps
;                 |+------- Mode select. 0=direct, 1=Burst
;                 +-------- Dual/Single Chan. 0=Single
;
TRX001      fcb  %00000011        ;TX/RX & Channel (freq)
;                 ||||||||  [Bits 0 - 7]
;                 |||||||+- RX bit (1), Tx = (0)
;                 ||||||+-- Channel select bit 0
;                 |||||+--- Channel select bit 1
;                 ||||+---- Channel select bit 2
;                 |||+----- Channel select bit 3
;                 ||+------ Channel select bit 4
;                 |+------- Channel select bit 5
;                 +-------- Channel select bit 6
;
**************************************************************
* Transceiver data transmit routine:                         *
* Transmission starts ~3mS after "CE" returns low.           *
*                                                            *
* ! Note similarity to Trx configuration output routine !    *
* The following ports apply...                               *
* PTA0 = Data (bi-directional)                               *
* PTA1 = Clk1 (Output Tx & Rx)                               *
* PTA2 = DR1  (Input "data ready")                           *
* PTA3 = CS (Output - Config. reg. select)                   *
* PTA4 = CE (Output - Communication Enable)                  *
* PTA5 = Not Used                                            *
*                                                            *
**************************************************************
TRXxmt    bset  0,PTADD           ;Set D0 as output
          mov   #!25,count8a      ;Set byte counter
          mov   #!8,count8b       ;Set bit counter
;
          bset  4,PTAD            ;Set "CE" high
          ldhx  #$000F            ;Set delay (>5uS)
          jsr   delay1            ;Do delay
;
          ldhx  #recaddr          ;Get start of bit field
trxx01    lda   ,X                ;Get data byte
trxx02    asla                    ;Shift D7 -> (C)
          bcs   trxx03            ;C=1, skip
          bclr  0,PTAD            ;Make dataline = 0
          bra   trxx04            ;Skip
;
trxx03    bset  0,PTAD            ;Make dataline = 1
trxx04    nop                     ;Wait (Ts > 500nS)
          nop                     ;Wait...
          bset  1,PTAD            ;Set "CLK" high
          nop                     ;wait (Th > 500nS)
          nop                     ;Wait...
          bclr  1,PTAD            ;Set "CLK" low
;
          dbnz  count8b,trxx02    ;Step -1 byte-bit count
          aix   #1                ;Step +1 byte pointer
          mov   #!8,count8b       ;Reset bit counter
          dbnz  count8a,trxx01    ;Step -1 byte count
;
          bclr  4,PTAD            ;Set "CE" low
          bclr  0,PTADD           ;Set D0 as input
          rts                     ;exit
;
**************************************************************
* Transceiver data-received download routine:                *
* NOTE! 1. Only 20 bytes are output (160 bits).              *
*       2. This does NOT set up "CE" signal and the "RXEN"   *
*          (bit-D0) in the config string! It only monitors   *
*          the "DR1" input signals from the TXR.             *
*                                                            *
* The following ports apply...                               *
* PTA0 = Data (bi-directional)                               *
* PTA1 = Clk1 (Output Tx & Rx)                               *
* PTA2 = DR1  (Input "data ready")                           *
* PTA3 = CS (Output - Config. reg. select)                   *
* PTA4 = CE (Output - Communication Enable)                  *
* PTA5 = Not Used                                            *
*                                                            *
**************************************************************
TRXrec    brclr 2,PTAD,TRXr04     ;TRX input? No, then skip...
          bclr  0,PTADD           ;Set PTA-D0 as input
          bset  2,status          ;Set "rcvd data" status bit
          mov   #!8,count8a       ;Set bit-loop counter
          clr   count8b           ;Clear total-bits counter
          ldhx  #RXdata           ;Get addr of data field
;
TRXr01    bset  1,PTAD            ;Set "CLK" high
          brclr 0,PTAD,TRXr02     ;Is data bit=0?, doesnt matter!
TRXr02    rol   count8c           ;(C)->D0 (shift bits up anyway)
          bclr  1,PTAD            ;Set "CLK" low
          inc   count8b           ;Step total-bits counter
          dbnz  count8a,TRXr01    ;Done 8 bits? no, decr & skip...
          mov   count8c,X+        ;Yes, save data byte + step addr.
          mov   #!8,count8a       ;Reset bit-loop counter
          brclr 2,PTAD,TRXr03     ;All bits done? Then skip..
          bra   TRXr01            ;Else loop..
;
TRXr03    mov   count8b,RXbcnt    ;Save total-bits count
TRXr04    rts                     ;Exit.
;

The promised main body sequence to switch Tx and Rx and as always, a few clarifying notes before we get into the deep end.

  • I'm not sure that the term 'tally" means much to many people, so by way of explanation - a tally is an indicator. In my little world this is usually an LED. I just love flashing lights!
  • Ignore the gobbledigook in the beginning that addresses the LCD.
  • TRX = transceiver.
  • The delay1 value of $0FFF = ~6.4mS goes up in smoke. I use this a lot!

The rest that follows, I'm sure is fairly self explanatory except to point out that the delay following the "Do transmit" (11 lines down from "Begin"), is very important. If attempts to control "CE" and the D0 in the config are done while the TFR is still transmitting, things go wrong. Either you will torpedo the "Tsby2txSB" 195uS condition and transmit will fail, or the config update will not update and you will not be in RX mode for the duration after the transmission. Trust me, you want to wait…

**************************************************************
* Main program loop after a RESET.                           *
**************************************************************
          jsr   lcdla1             ;Setup LCD line.1 addr.
          ldhx  #lcdm00            ;Get message addr.
          jsr   lcdwrt             ;Output message line
;
          jsr   lcdla2             ;Setup LCD line.2 addr.
          ldhx  #lcdm01            ;Get message addr.
          jsr   lcdwrt             ;Output message line
;
          jsr   tlyclr            ;Clear tallies
;
* ---------- RECEIVE / TRANSMIT -----------------
* Note the default mode of the transceiver is RECEIVE!
* After a TRANSMIT routine is carried out, the receive mode
* must be re-instated.
;
          bclr  4,PTAD             ;Set "CE"=0
          jsr   TRXprx             ;Program TRX for RX
          bset  4,PTAD             ;Set "CE"=1 to enable TRX
;
Begin     jsr   TRXrec             ;Do receive download
          brclr 2,status,PGM001    ;Was there data? No, then skip
          jsr   tly1onn            ;Yes, Turn on tally #1
          ldhx  #$0FFF             ;Set delay
          jsr   delay1             ;Do delay
          clr   RXbcnt             ;Reset bit-counter
          bclr  2,status           ;Reset "rvcd data" flag
          jsr   tly1off            ;Turn off tally #1
;
          bclr  4,PTAD             ;Set "CE"=0 (To allow "CS")
          jsr   TRXptx             ;Program TRX for TX
          jsr   tly2onn            ;Turn on tally #2
          jsr   TRXxmt             ;Do transmit
          ldhx  #$0FFF             ;Set delay for TX to complete
          jsr   delay1             ;Do delay
          jsr   tly2off            ;Turn off tally #2
;
          bclr  4,PTAD             ;Set "CE"=0 (To allow "CS")
          jsr   TRXprx             ;Program TRX for RX
          bset  4,PTAD             ;Set "CE"=1 to enable TRX
;
* -------- This ends the RX/TX Program ----------------------
;
PGM001    brclr 0,status,PGM002    ;Check for SCI input
… and on to a bunch of inconsequential prototype stuff…

So now you know, tally 1 tells me I have received and tally 2 tells me I am transmitting.

I think we are done here.

The FSM…

Life just doesn't get any easier than this - for the benefit of not having to thrash around blindly for hours (days!) on end - this is an absolute Godsend. Take 30 minutes to knock it up on perf-board if you must… or follow the dictates of the Dutch-Franco-Germanic psyche (me!) route and spiffy it up in an enclosure.

The trim-cap, C1 is much easier to mount directly on the loop antenna, which is where it belongs - I wasted more time than I should have scheming on ways to "hide" it in the enclosure before applying Revelations 13:1 "Aw to hell with it!" Keep the RF leads as short as possible to the diode. The value of C2 is critical only in the sense that too large a value slugs the unit's response time. The meter I used was a 1mA fsd movement. For the rest of the circuit… go nuts, experiment!

A word about the detector diode - ignore the gasps of horror from your microwave-pundit buddies at not using a $4 IN23A or the like… the humble $0.20 germaniums are plenty good enough. We are not looking to decode the signal, but merely to detect the presence of an envelope.

The more astute reader will, of course, have picked up on the fact that a METER is all but useless when looking for an envelope with a duration of <1mS and a duty cycle around 100:1. The meter was kind of a panicked and mindless following of the standard instrument topology after a week of no progress on the project. So, the addition of the 'scope probe sockets is a must - implying also that one needs any old 'scope that can display the TX "blip".

Performance wise, the unit will need to be quite close to the TRF antenna - I found that putting the unit face-down with the FSM antenna about 1" or 2" above the TRF gave a useful blip on the 'scope (about 100mV). I suppose more gain on the meter amplifier would improve the distance or amplitude, but stopped tinkering as soon as I had a useable signal - too many other things to do and couldn't afford the time!

Since the unit is simplicity itself, I'll refrain from engineering it to death with words… here's the pictures…

 

In retrospect, the addition of the meter was not a bad idea, since it did allow me to tune the 2.4Ghz circuit using the microwave oven - thus saving me the indignity of dragging the 'scope into the kitchen. Microwave oven you say? Sure! Great source of MONDO 2.4Ghz steady signal. (Don't forget to dummy load the oven). A little less mondo, but still useful, is the 2.4Ghz cordless phone base-set. Bear in mind, the Q of the simple tuned circuit is fairly low, thus it spans any frequency discrepancies among these signal sources. Just peak the meter and you're done.

A word about polarization; The TRF antenna is horizontally polarized. The antenna on the FSM is vertically polarized. This means you will find that the TRF and FSM are at right-angles to each other for maximum field strength. A happy accident, since it suits my prototype topology perfectly!

The only noteworthy construction tip on this unit is the perf-board that holds the antenna and RF components in place. It is glued to the top cover with copious amounts of epoxy to hold the antenna rigid. In the interest of short leads, the diode and C2 (smt) are mounted here too.

Time to warm up that soldering iron…

 

- - - - - - - - - - END - - - - - - -