In part 1, we used some simple tools available to us to look at the modulation and frequency the Response alarms use (868MHz, 2-FSK)
In part 2, we opened the alarm up and looked at the main components in the system (TI CC11xx RF chips with various microprocessors).
Now we are going to try and look at the communication between the microprocessors and the TI CC1150 chips. They have an SPI serial interface, allowing the user to set various registers to control the rich and complex feature set.
I have a number of tools available to me that can sniff SPI. The cheapest is the Bus Pirate. This has an SPI sniffer interface along with a basic logic analyzer. It works well, 90% of the time. If timings are curious or the protocol deviates slightly from normal, it tends to fall over.
I also have an oscilloscope. It is hard work decoding serial though – it doesn’t have any built in protocol analysers.
So I go to my good old friend, the Saleae Logic 8-channel logic analyser. I have had this a number of years and it has rarely let me down. It’s simply brilliant for dealing with embedded systems, and the software is very easy to use and cross-platform.
I’m going to work with the door sensor initially – they are the cheapest and simplest sensors. I was planning on selling unopened sensors, and the PIRs fetch decent prices on ebay (as an aside, the provenance of alarm detectors on eBay is questionable – could this be an attack vector?).
The RF daughterboard has a 8 pin header. We need to work out which is ground, and then we can safely connect the Saleae Logic. We do this using a continuity tester between the battery connector and pins. It looks like pin 1 is ground.
Another pin will be the supply, but at this stage, it doesn’t really matter which. I just need to confirm it is <5V to avoid damaging the logic analyser. I connect the board to the power supply and confirm that no voltages are higher than 3V, regulated down from the two CR2032 batteries.
Small wires are soldered to the pin header to make connecting the logic analyser easier.
We then start the logic analyser with no triggering and press the test button on the contact.
Excellent – this looks very much like we have data!
I could at this stage buzz out the pins to the CC1150 chip to work out what the pins do, but the daughterboard is soldered down so the chip is hard to access. I’d rather just have a guess at the pins – we know it is SPI after all.
SPI requires the following pins:
- CS – chip select, generally active low.
- SCLK – the clock for the data.
- MOSI – master out, slave in data.
- MISO – master in, slave out data.
CS is nearly always going to be the slowest changing pin – let’s zoom in to the beginning of the trace and see what we have:
From this, I’d wager that CS is channel 0.
Now, to look at this trace, it would be easy to assume that channel 3 is a clock – look how regular it is! However, in SPI, because we are transferring at least 8-bits of data, we need at least 8 transitions each time CS is asserted. Channel 3 isn’t nearly fast enough.
What about channel 4 being the clock? The pulses look to short (and on some traces, they are very irregular as well!):
But if we look a little closer, we can clearly see 8 pulses per CS. There is no requirement for the clock pulses to be regular and they also don’t need to have a 50% duty cycle.
The two other channels with changes are 3 and 5. One will be MOSI, the other MISO – we aren’t really bothered which right now as it won’t have any impact on decoding the data.
I’ll now set up the Saleae Logic’s protocol decoder for SPI on these channels. There are a number of configuration settings, let’s leave them on the defaults and see what happens – it will throw errors or produce obviously squiffy data if incorrect.
The little orange and green boxes represent decoded data – we just need to zoom in to see what that data is now. I can then export this as CSV to examine in an external program. We have no errors, so we can check if the decoding has worked by examining the packets against the datasheet.
Time [s] |
Packet ID |
MOSI |
MISO |
0 |
0 |
0x30 |
0xFF |
0.0001085 |
1 |
0x01 |
0xFF |
0.00018025 |
1 |
0x0B |
0xFF |
0.00024925 |
2 |
0x02 |
0x0F |
0.00032075 |
2 |
0x0C |
0x0F |
0.00038925 |
3 |
0x03 |
0x0F |
0.0004615 |
3 |
0x07 |
0x0F |
0.0005305 |
4 |
0x04 |
0x0F |
0.0006025 |
4 |
0xD3 |
0x0F |
0.00067225 |
5 |
0x05 |
0x0F |
0.00074475 |
5 |
0x91 |
0x0F |
0.00081325 |
6 |
0x06 |
0x0F |
0.000886 |
6 |
0xFF |
0x0F |
0.00096775 |
7 |
0x08 |
0x0F |
0.00103925 |
7 |
0x12 |
0x0F |
0.00110775 |
8 |
0x09 |
0x0F |
0.00118 |
8 |
0x00 |
0x0F |
0.00124725 |
9 |
0x0A |
0x0F |
0.0013195 |
9 |
0x00 |
0x0F |
0.001408 |
10 |
0x0D |
0x0F |
0.00148075 |
10 |
0x21 |
0x0F |
0.00154925 |
11 |
0x0E |
0x0F |
0.001622 |
11 |
0x65 |
0x0F |
0.0016915 |
12 |
0x0F |
0x0F |
0.00176475 |
12 |
0x6A |
0x0F |
0.00183425 |
13 |
0x10 |
0x0F |
0.00190625 |
13 |
0x87 |
0x0F |
0.00197525 |
14 |
0x11 |
0x0F |
0.002048 |
14 |
0xF8 |
0x0F |
0.0021175 |
15 |
0x12 |
0x0F |
0.00218975 |
15 |
0x00 |
0x0F |
0.00225725 |
16 |
0x13 |
0x0F |
0.00232975 |
16 |
0x22 |
0x0F |
0.00239825 |
17 |
0x14 |
0x0F |
0.002471 |
17 |
0xF8 |
0x0F |
0.0025405 |
18 |
0x15 |
0x0F |
0.00261325 |
18 |
0x50 |
0x0F |
0.00269225 |
19 |
0x17 |
0x0F |
0.0027655 |
19 |
0x30 |
0x0F |
0.002834 |
20 |
0x18 |
0x0F |
0.002906 |
20 |
0x18 |
0x0F |
0.00306925 |
21 |
0x22 |
0x0F |
0.0031415 |
21 |
0x15 |
0x0F |
0.0032105 |
22 |
0x23 |
0x0F |
0.00328375 |
22 |
0xE9 |
0x0F |
0.00335325 |
23 |
0x24 |
0x0F |
0.0034255 |
23 |
0x2A |
0x0F |
0.0034945 |
24 |
0x25 |
0x0F |
0.00356725 |
24 |
0x00 |
0x0F |
0.0036345 |
25 |
0x26 |
0x0F |
0.00370725 |
25 |
0x1F |
0x0F |
0.00379825 |
26 |
0x29 |
0x0F |
0.003871 |
26 |
0x59 |
0x0F |
0.0039405 |
27 |
0x2A |
0x0F |
0.00401325 |
27 |
0x7F |
0x0F |
0.0041055 |
28 |
0x2D |
0x0F |
0.00417875 |
28 |
0x35 |
0x0F |
0.00424825 |
29 |
0x2E |
0x0F |
0.0043215 |
29 |
0x09 |
0x0F |
0.00438775 |
30 |
0x7E |
0x0F |
0.004463 |
30 |
0x00 |
0x0F |
0.00451425 |
30 |
0x0B |
0x0F |
0.00456675 |
30 |
0x25 |
0x0F |
0.0046195 |
30 |
0x68 |
0x0F |
0.00467225 |
30 |
0x60 |
0x0F |
0.004725 |
30 |
0x86 |
0x0F |
0.0047775 |
30 |
0xCC |
0x0F |
0.00483075 |
30 |
0xC3 |
0x0F |
0.0049125 |
31 |
0x35 |
0x0F |
0.01802275 |
32 |
0x36 |
0x2F |
This is exactly what I would expect to see when a micro is controlling a CC1150. Let’s work out what is going on.
We are just going to lock at MOSI – the packets the microcontroller is sending to the CC1150.
The first packet is an 1 byte packet, where 0x30 is sent. If we search for 0x30 in the datasheet, we find out that there are a series of 1 byte packets called “strobe commands” on page 42, table 25 . They all trigger changes in the internal state machine. 0x30, SRES, reset – fairly obvious meaning!
Next we have a series of 2 byte packets. You can see the first byte of each packet is generally just incrementing one by one. Again, we look through the datasheet and on page 43, table 26, we have a list of the configuration registers. Notice how we skip some numbers – 0x0C, 0x0D – this is because they are only used for reception, not transmission, and the CC1150 is a transmitter only.
I could go through these one by one, explaining how they are configuring the radio. But let’s just look at the most important ones for now, referring to the datasheet.
FREQ2, FREQ1, FREQ0 are stored in 0x0D, 0x0E, 0x0F and are set to 0x21, 0x65, 0x6A respectively. From page 47 of the data sheet, we need to concatenate these (0x21656a) and then use a simple formula to work out the frequency. This gives a result of 868,299,865Hz – almost exactly as we measured.
MDMCFG2, 0x12, contains modulator settings. Bits 6-4 are the modulation format – so let’s look at them. The value written to 0x12 is 0x00, so bits 6-4 are 0b000. This corresponds to 2-FSK, as we observed before.
DEVIATN, 0x15, tells us the deviation settings (i.e. how far apart the two frequencies will be in 2-FSK). A simple formula is used. Bits 6-4 give us the exponent, and 2-0 give us the mantissa. 0x15 is set to 0x50, so the exponent is 0b101 and the mantissa 0b000. From this we get 50781.25Hz – again, this corresponds to our ~100kHz gap between the two peaks from part 1.
We are now confident that we the SPI traffic we are looking at is correct. Now we need to work out how data is being sent between the two. There are so many different ways this can be done using the CC1150, so we will need to drill into the settings and sniffed traffic in more detail – which we will do in the next part.