Share this project


Share this project

RFIDler (RFID Low-frequency Emulator & Reader). An open platform RFID reader/writer/emulator that can operate in the 125-134 KHz range.
695 backers pledged £28,377 to help bring this project to life.

Baseband basics

Posted by Aperture Labs Ltd. (Creator)
1 like

One of the things that drove me nuts when I first started getting into RFID was trying to work out how everything related to eachother timewise, or frequency wise, or clockwise, or bitwise, or ... you get the picture!

Looking at one document everything would be described in terms of frequency, and in another in terms of microseconds and in another in terms of 'Field Clocks' etc. And to make matters worse, even those descriptions were often obfuscated even further - for example, a common term used in datasheets is 'RF/n'. So what the hell is RF and how do I calculate 'n'???

Currently I'm migrating all the test code into a standalone package, and the first chunk to move across (after the CLI) was baseband emulation. In doing so, I decided I needed a common standard for specifying parameters to the low level routines, as well as higher level 'user facing' stuff. Accordingly, here's a quick roundup of all the things I think we need to care about...

We've already established that everything's done in ASK/OOK as far as driving the coil's concerned, so in theory all we'd need to know is how long each on/off period is, and what sequence to send and we're done. In practice, since we're going to 'create' other modulation schemes by using ASK to influence the underlying carrier, we also need to know something about each of their requirements...

Looking through my datasheets collection, it is clear that there are only a few common standard modulation schemes, so a good start would be to make sure we've covered all of those (and I apologize in advance if I'm repeating myself, but it's worth doing as it'll make more sense further along):

  ASK - Amplitude Shift Keying (sometimes called NRZ or DIRECT)

  FSK - Frequency Shift Keying

  PSK - Phase Shift Keying

  Manchester Encoding

  BiPhase Encoding

There are some additional 'standard' types of FSK and PSK, so we need to make sure our baseband can cope with those (and they are just to do with the sub-carrier frequencies), so we can consider them a higher layer problem.

Manchester and BiPhase are interesting because they can be integral to the protocol and implemented in the baseband for ASK, but may also be provided at a higher layer for any of the other modulation types. More on that later!

So for each scheme, we need the following:

  ASK: bit period

  FSK: bit period, sub-carrier frequency of '0' bits, sub-carrier frequency of '1' bits

  PSK: bit period, sub-carrier frequency

  Manchester & BiPhase: fixed at half a bit period, so no extra info required

OK, so now we need to decide what unit of measure to use.

Frequency is, in my opinion, particularly unhelpful. It's way too analogue-y for my liking, and it's kind of meaningless in the context of a digital process. However, it's also integral to the problem as everything we do has to revolve around the fixed frequency that we're driving the tags at, e.g. 125 KHz. So how do we make that more useful? Well, when I'm testing, one of the things that I can easily check is the length of a pulse, and, more importantly, one of the things I can easily specify in my code is the length of a pulse, so let's convert 125KHz into a pulse length and see if we can use that as our most basic unit. One second divided by 125000 is 8 microseconds, so our base unit is 8 microseconds. That's a nice round number, so how does that relate to our datasheets and specifications etc?

Well, as it turns out, it relates very well. If a datasheet talks about 'Field Clocks', and the reader is clocking at 125KHz, then a single Field Clock is 8 microseconds. Great. So our base unit is actually one Field Clock.

It gets better - when they talk about data rates, they tend to express them, as previously mentioned, as 'RF/n'. Here's an example: EM4102 has a data rate of RF/64. If I measure a bit period from an EM tag it's 512 microseconds. 512 divided by 64 is 8. So what RF/64 really means is FC x 64. 64 Field Clocks! Similarly, sub-carriers are expressed as RF/n, and, again, they directly translate to FC x n: 'n' 'ticks' of the Field Clock creates one 'tick' of the sub-carrier. Lovely. So we can use FC as our basic measure, and not worry about calculating time periods (unless we want to check them on a scope).


At this point it's probably helpful to visualize what each modulation scheme looks like, and describe what they're doing in relation to the data:

In these diagrams, the 'Data stream' is the bit sequence, the 'Inverted modulator signal' is our emulation coil (note that it's inverted, so it's showing HIGH for UNDAMPED and LOW for DAMPED), and the 'RF field' shows the effect we're having on the READER's coil.

ASK / OOK - Amplitude Shift Keying / On-Off Keying

Here is ASK/NRZ/DIRECT with a Data Rate of RF/16:

This is obviously the simplest form of modulation - we just switch our DAMPING on/off in line with the data: DAMPED for a '1' and UNDAMPED for a '0'.

FSK - Frequency Shift Keying

Here is FSK with a Data Rate of RF/40 and RF/8 for ‘0’ and RF/5 for ‘1’:

And this is the most complex - we're having to create two different sub-carriers at different frequencies. Our coil is alternately DAMPING and UNDAMPING at a rate of 8 Field Clocks if we're signalling a '0', and 5 Field Clocks if we're signalling a '1'.

PSK - Phase Shift Keying

Here is PSK1 with a Data Rate of RF/16 and a Sub-Carrier of RF/2:

This looks complex but actually isn't. All we need to do is create a single sub-carrier by alternately DAMPING and UNDAMPING our coil at a rate of 2 Field Clocks, and we signal our data by skipping a beat if the data value changes. In other words, if we've just sent a '0' and the next bit is also a '0', we do nothing - just carry on modulating as usual. However, if the next bit is different from the last then we keep our current DAMPING or UNDAMPING state for an extra Field Clock and this has the effect of shifting the phase of the sub-carrier by one Field Clock.

Manchester Encoding

Here is Manchester with a Data Rate of RF/16:

This is essentially ASK with an extra toggle mid-bit. If we're sending a '0' we start UNDAMPED and then DAMP halfway through the bit period. Sending a '1' is the other way around - start with DAMPED and switch to UNDAMPED. This is an essential technique for a few reasons:

Firstly, it allows you to send a '0', which otherwise would be indistinguishable from no data at all.

Secondly, it allows you to latch on to the start of a bit and automatically calculate the bit period. Since a bit must be either LOW/HIGH or HIGH/LOW, if you see a HIGH/HIGH or a LOW/LOW then you are reading your data half a bit out of time and you're looking at the tail end of one bit and the first half of the next. Simply wait half a clock and try again and you'll be in sequence. Your bit period can be calculated by measuring your longest pulse, since this will be a HIGH/HIGH or a LOW/LOW, and is therefore equal to two half bits or one full bit.

Thirdly, you can use it for error detection. Since the only two sequences allowed are LOW/HIGH for a '0' and HIGH/LOW for a '1', that means you should only ever see at most two LOWs or two HIGHs in sequence. You'll get two LOWs if a '0' follows a one: HIGH/LOW LOW/HIGH, and two HIGHs if a '1' follows a '0': LOW/HIGH HIGH/LOW. If you ever see three HIGHs or LOWs in sequence, then your data is corrupt.

BiPhase Encoding

Here is BiPhase with a Data Rate of RF/16:

BiPhase is similar to Manchester, except that we always toggle our DAMPING at the end of a bit period, and we only toggle on the half-bit if the data is a '1'.


We've implemented several emulators over the years, but they've always been for a specific purpose, designed to emulate one particular tag type. Whether it's Hitag2, HID or EM4012, etc., we'd take a top-down approach and work out the parameters required to emulate that particular tag, create a circuit that could drive a coil, write code that generated exactly the right bit pattern, and off it would go. But this time it's different - we want to be able to emulate anything and everything, so we're going bottom-up. Get the baseband right and the rest should be much easier. If we can reliably encode in the baseband, then implementing a new tag type should be as simple as reading the parameters off the data sheet, generating an appropriate bitstream, and bingo! The reader will go beep!

Great, so now we know what we're doing, in theory all I need to pass to my emulation routines is the size of FC - e.g. 8 for 125KHz, the data rate in FCs, the sub-carriers in FCs, and some data. Simple!

So let's see how it looks in practice. If I feed my low level baseband routines the same data as we saw in the examples above, our traces should look exactly the same...

Here's how the CLI looks:

So if we start with the simplest scheme, ASK, and we want a bit pattern of 10011010 (hex 0x9a), a Field Clock of 8,16 Field Clocks per bit, and no repeats, we would issue this command:

  ask 9a 8 16 0

and this is what our trace looks like:

(Note that our modulator signal is not inverted, so we're showing HIGH for DAMPED and LOW for UNDAMPED.)

Looking good! Seems to be exactly as expected.

the next was FSK with a Data Rate of RF/40 and RF/8 for ‘0’ and RF/5 for ‘1’:

  fsk 9a 8 40 8 5 0

and this is what our trace looks like:

then we had PSK1 with a Data Rate of RF/16 and a Sub-Carrier of RF/2:

  psk1 9a 8 16 2 0

and this is what our trace looks like:

and Manchester with a Data Rate of RF/16:

  manchester on

  ask 9a 8 16 0

and this is what our trace looks like:

and finally, BiPhase with a Data Rate of RF/16:

  biphase on

  ask 9a 8 16 0

and this is what our trace looks like:

So far, so good. All the traces look as we'd expect them, so we should be good to go.

As you can see, we've provided an 'examples' command which gives some example data for testing:

these are correct data values, either pre-calculated or read from genuine tags, so if I feed them to the corresponding readers, they should respond as if the original tag had been presented...

The proof of the pudding's in the eating:

I love it when a plan comes together! :)

Sam Grimee likes this update.


Only backers can post comments. Log In
    1. Sam Grimee on

      sorry i meant :-)

    2. Sam Grimee on

      really cannot wait for the next course :-(

    3. Sam Grimee on

      cannot wait for the next lesson! :-)

    4. Kalus on

      Very good update. I also like realized theoreticals by get proofing Hannibal

    5. Missing avatar

      David Mitchell on

      Great update, thanks! Whats the music?

    6. Missing avatar

      Pictor on

      thanks a lot for another excellent course!

    7. Heri Sim

      Great work