Whilst I wait for the PCB to arrive I can crack on with writing the code that’s going to run on the PIC. I’ll write it in C (not assembler…!), using the MPLAB X IDE and the CCS C compiler. I much prefer the old MPLAB 8 IDE, but Microchip has stopped supporting new devices in version 8, so I’m left with no choice but to use MPLAB X. It’s all very pretty and I’m sure I’ll get used to it…soon.
I’ve chosen to use the CCS C compiler over Microchip’s C compiler basically because of cost. Although Microchip have a free version of their XC compiler, all of the optimisations are disabled. This results in terribly compiled code which takes up much more space than it needs to. Not ideal for a small embedded device with limited storage like I am using!
If I wanted to buy the version of the Microchip C compiler with optimisations enabled then it would cost me £749.01!! Seven-hundred-and-forty-nine-pounds-and-one-penny! Clearly I don’t have that kind of money lying around. The professional, fully optimising, version of the CCS C compiler for the 16F devices only costs £114. Much more reasonable. Granted this version of the CCS C compiler doesn’t work with the higher end PIC18 devices, but even if I were to buy a version that supports all 8-bit devices, as per the Microchip compiler, it would still only cost me £306. Less than half the price of Microchip’s offering. In my experience the CCS compiler generates decent code and there are plenty of built-in libraries too.
Microchip have started offering a subscription for the XC compiler, at £22 per month. I’ve decided against this too as it is likely that I will be tweaking the firmware over several months. I could end up finding myself in a situation where each tweak is costing me £22. Not ideal!
The code will hopefully be fairly straight-forward to write. TI helpfully provide some software examples for interfacing with the CC112x line of devices. I’ll reuse most of this for the CC1125 interface, stitching in my own PIC-specific SPI related code as required.
I plan to put the CC1125 and PIC into deep sleep mode for around 16 seconds, using a timer interrupt to wake the PIC after this time at which point I’ll wake the radio up and wait for a transmission. If no transmissions are received then I’ll go back to sleep for another 16 seconds. This will hopefully keep my power consumption very low.
I’ve done some work on the message format already – this is the format of the messages arriving at the PIC from the basestation:
/* Data should be formed of: * 1 byte - length * 1 byte - device address * 8 bytes - our encrypted data * byte 0 - message id * byte 1-4 - 32-bit counter * (this prevents people performing replay attacks * on us - we check that the counter is increased * from the previous message received) * byte 5 - 0xFF - number of bytes to transmit in beacon mode * byte 6 - 0x0A - sanity check * byte 7 - 0xEC - sanity check * 2 bytes - status bytes from CC1125 */
I think I’ll have four different operation modes. The ‘message id’ field will be used to tell the PIC which mode to go in to:
- GPS Position Mode. In this mode, CatTrack sends back the GPS position data from the GPS module every 10 seconds. This will be the primary mode of operation. It’ll send GPS data for 30 minutes before reverting back to sleep mode.
- Stop Mode. This mode tells the PIC to stop whatever it’s doing and go back to sleep.
- Beacon Mode. In this mode, CatTrack will send back a short message containing just the battery voltage, once per second, up to the number of times specified in the request. It is intended that this mode is firstly used to check the battery life left in the collar, but also could be used to hone in on the cat, if the GPS isn’t working (the cat could be stuck in a garage for example). I will be able to monitor the signal strength of this message from the basestation and thus will be able to work out roughly where he is.
- RF Test Mode. This mode will be used to verify the antenna match. The PIC will instruct the CC1125 to sweep a tone from around 850 MHz to 880 MHz. I will then be able to set up a spectrum analyser nearby and ensure that peak power is received at the design frequency – 868 MHz.
The format for the data sent back in the GPS Position Mode will be thus:
txbuffer = gps_data.hour; txbuffer = gps_data.minute; txbuffer = gps_data.second; txbuffer = gps_data.quality; txbuffer = (uint8_t) (gps_data.latitude >> 24); txbuffer = (uint8_t) (gps_data.latitude >> 16); txbuffer = (uint8_t) (gps_data.latitude >> 8); txbuffer = (uint8_t) gps_data.latitude; txbuffer = (uint8_t) (gps_data.longitude >> 24); txbuffer = (uint8_t) (gps_data.longitude >> 16); txbuffer = (uint8_t) (gps_data.longitude >> 8); txbuffer = (uint8_t) gps_data.longitude; txbuffer = gps_data.sats; txbuffer = gps_data.hdop; txbuffer = count; /* GPS message count */ txbuffer = 0xAC; /* Means we can be sure we decrypted it ok on the other end */
I’ll be encrypting the data with XXTEA before sending it, just because why not! Given that I expect transmissions to occur once every few weeks at a maximum, plus it’s hardly incredibly sensitive data, encryption isn’t essential, but I might as well. XXTEA is ideally suited to small microcontrollers – perfect for implementation on a PIC.
I’m also planning to add replay protection. Again, not essential but I might as well. As you can see above, I’ve reserved 4 bytes for a 32-bit counter, which is part of the encrypted payload. The idea is that the base unit will increase this counter with each transmission. The PIC in CatTrack then decrypts the payload and checks that the counter has incremented from the last transmission. If the counter is the same then the message will be ignored. This prevents anybody ‘sniffing’ a transmission from the base unit and replaying it back to CatTrack.