Showing posts with label embedded. Show all posts
Showing posts with label embedded. Show all posts

Friday, 2 January 2015

Logically seeing in the new year

My awesome other half got me an 8 channel 24 MHz "Saleae Logic" USB analyser for xmas. This (cheap clone) device seems to work well with the Saleae software Version 1.1.34 (beta) and detected immediately under Linux Mint 16 Petra.

Having never used a logic analyser (or oscilloscope) before, the first thing I did was hook it up to the 25L1605D on the animal card reader board. This unofficial Saleae device doesn't come with the nice E-Z Hook connectors that the official Saleae Logic comes with, so I bought these. They're possibly not as grippy as the E-Z Hooks, but they seemed to do the job. It is however a bit of a squeeze fitting them on the PCB mounted chip in the Animal Card reader.

So. Much. Cable.
The datasheet for the 25L1605D shows that it is Serial Peripheral Interface compatible. I'm pretty new reading datasheets, and I was really hoping that the listed clock speeds of 66/86 MHz were going to be maximum values. I was hoping that the toy was cheap enough that the micro-controller would be clocking the bus significantly lower.


Saleae recommend sampling SPI at least 4 times faster than the clock rate. This means the maximum clock I could hope to sample would be 6MHz - which is quite a lot less than the values in the data sheet.

I wired everything up, configured the Saleae software to record 10 seconds worth of samples at 24 MHz, hooked up the channels to the appropriate SPI signals, pressed "Start" and precariously swiped the card through the reader to trigger the sound. The recorded data successfully decoded as SPI, but subsequent recordings of the same card were producing different results. Also, the clock signal was very irregular.


Huge gaps between clock cycles...doesn't look good
Since I was using the same animal card each time, would have expected to see the same data retrieval from the flash each time in order to produce the same sound. Since this wasn't the case I assume I have one of two problems:

  1. The SPI bus on the animal card reader is clocked higher than 6MHz (which means I can't use my new logic analyser to spy on it), or
  2. My IC hooks are interfering with each other/shorting
To confirm number 1 I would have to track down a tool that can sample at a higher rate. Unfortunately I don't own an oscilloscope or a faster logic analyser, and since I'm on holidays at the moment, I can't access these at work. I could eliminate number 2 by soldering on some pigtails and attaching to the pins that way, but to be honest, I'm pretty sure the issue is number 1 (also I'm terrible at soldering).

UPDATE: I bought a soldering station and soldered on some pigtails to the SPI pins on the flash chip but still had similar results using the Saleae software. I then decided to take it into work and get one of the guys to log the SPI bus using the sexy new 4 channel Agilent scope. Clock speed is 16 MHz so, as expected, there was no chance of getting this to work with the 24 MHz logic analyser. 

So what's a girl to do? I'd need another project in order to play with my new Logic analyser.

Enter my mate Kev to the rescue on New Year's eve - equipped with his NeoPixel ring project (and beer).

Kev is in the process of making an abstract wall clock using the NeoPixel LEDs and an Arduino. He's using this library to configure the pixel ring to show the time using various colours and patterns. The datasheet for the chainable/programmable LEDs can be found here.

Kev's setup uses a single data pin to program the chained LEDs so we simply hooked up the Saleae analyser to his breadboard and recorded 10 seconds of traffic on the single wire bus. We had no idea what the protocol was - and both being noobs, we spent a while messing with various protocols in the Saleae software before retiring to board games and festivities (oh and not ignoring our significant others due to technology distractions).

The next day I decided to approach this properly (soberly).

According to the data sheet, each LED's controller will remove 24 bits from the data stream, interpret that as the green, red and blue (in that order) intensities for itself and pass the rest of the packet onto the next chip in the chain. The signal is self-clocking, with a rising edge indicating the start of a bit and the timing of the falling edge indicating whether the value is a logical 0 or 1. Each new transmission is preceded by a reset period.

In the Saleae software, it looks a little something like this:


Despite the fact that the protocol is pretty basic, I could not work out a way to interpret it with the inbuilt analysers in the Saleae software.

In order to cater for these situations, Saleae offer a C++ SDK for writing your own analysers. Just make sure if you are using the Beta Logic software, you remember to grab the Beta analyser SDK. You get some crazy core dumps if you forget to do this :)

A custom analsyer consists of 4 main parts:
  1. A class that knows what settings are required to be configured by the user (e.g. which channels map to which parts of the protocol, baudrates, etc)
  2. A class that knows how to generate simulated signals
  3. A class that knows how to display and write to file the decoded signals
  4. A class that knows how to decode the signals into frames and packets
The 4 classes get compiled into a dynamically linked library using the provided python script. You then just tell the Logic software where to look for additional libraries in Options -> Preferences -> Developer.

There are some great PDF instructions included in the API download that walk you through the whole process of compiling and modifying the core classes to implement your analyser. I found it useful to implement the classes in the order suggested and use gdb to diagnose any issues along the way.

It took me a little while to work out how to "call" the generator code, but it is actually quite simple. If you run the Logic software without a device connected, the big green start button in the top left of the "Capture" tab is actually a "Start Simulation" button. If you have your new analyser loaded on the right hand side, it will call your generator code with the current capture settings (i.e. sample rate and time, etc).


Once I had everything working with the simulator, I was able to load the data we captured on New Year's eve, decode it and write it to file. As usual, you can find all the source code on github

Monday, 8 December 2014

The revenge of the Super Animal cards

Since my last post:

  1. I've continued tinkering with this a bit.
  2. Woolworths announced this weekend an extra 72-card Christmas themed set, as a special gift too all parents out there who weren't already at their limit because of the first 108 cards that their children "must have".
So it turns out that at least 72 of my generated cards are from this new set. But which ones? What about the rest of the IDs - do they trigger a sound?


Earlier in the week I managed to get a hold of a card reader and took it apart to have a look it how it works.



 The card slot contains an infrared (IR) LED and sensor.

The card reader strip with IR LED and sensor

The LED is turned on by a simple switch when the user starts pulling the card through the slot. As the card continues to pass through, infrared light is reflected off the white parts of the card, but not the black parts and since the plastic behind the card is also white, the only non-reflected portions are the barcode. The micro controller (Mactronix 25L1605D) inside the device receives this information from the IR sensor and interprets the lack of reflections as the barcode.

UPDATE: In my rush to get things done I didn't bother to read the spec sheet. U1 is actually just the flash chip. The big black dot on the board is the micro. This process is called chip-on-board.

I might have to mess with this later...

My boss pointed out that this would be easy to spoof programmatically with an Arduino. Since I already had a couple of boards lying around I started on a simple sketch based on the basic blinking LED example provided by the Arduino team.

Humans can't see infrared light. Most digital cameras (such as the one in your phone) are able to detect the infrared light, so you can use a camera to view it, but I decided it would be easier to just do my development with a regular LED and switch over to and infrared LED later on. Conveniently the Arduino board I decided to use has a LED on the board connected to pin 13.

You can find the code here.

After making sure the lights blinked nicely at a speed that felt similar to swiping a card through the reader, I wired up my bread board. I was a bit lazy laying out the circuit and just chose a 330 Ohm resister I had handy to protect the LED. There's heaps of tutorials on the net about using Ohms law to calculate the resistor value correctly, but...well, I'm pretty lazy and was doing most of this in the 20 min before bed so I pretty much couldn't be bothered.

For the IR LED, I pulled the transmitting part out of a QRD1114 I had lying around.


The program that I uploaded to the Arduino cycles through all ID values starting at 1 and working through to 1023. I found that if I held the card reader's IR sensor over the LED and messed around triggering the switch, I would eventually trigger it at the right time to scan for the barcode and it would play the sound.

So my proof of concept worked. However, in order to improve things, I'd needed a way to trigger the switch programmatically as well - and despite all of the components I've collected over the years I don't own a relay. Time for a trip to Jaycar.

I swung by before work and picked up 2 TRR1A05D00 5 Volt reed relays (always good to have a spare). Wiring these up is pretty easy. I connected PIN 2 on the relay to one of the Arduino digital outputs. I connected PIN 6 of the relay to ground. PINS 14 and 8 get connected to each side of the open switch on the animal card reader.

The whole circuit precariously resting and held together with duct tape

I modified my Arduino sketch to trigger the relay before the barcode is simulated using the IR LED. I messed around with the timing a bit until I managed to get a sound out of the reader. At this point my program was cycling from 181 through to 1023. A few random animal noises later, I finally hear what I've been waiting for:

"Better luck next time"


In an American female voice. Success! There is an Easter egg! ID 191 is the Easter egg.

There appear to be additional animals from 181 through to 190 - so maybe there'll be another "special edition" card extension sometime soon.

In the meantime, I look forward to showing my nice what I've found when I see her this week :)

UPDATE: As I was writing this post, I left the program running on the Arduino. A good chunk of the way through I heard a beep and what sounded like a camera shutter sound. I guess I'll have to do a more thorough check at a later date.

Tuesday, 2 December 2014

Super Reverse Engineering Animal Cards

I spent the afternoon last Sunday reverse engineering the barcodes on these after helping my niece and nephew sort through the horde of them my partner and I had collected from Woolworths.

There are 108 cards in the set and each one has a unique bar code on the back. You can buy a sound card reader accessory that reads the barcode as it is swiped and plays an audio file for the specific animal on the card.



From initial inspection of a few of the cards, I worked out that there were 13 bits in the code and the top (as in top of the card - the last three to pass through the reader) 3 bits were the same for a bunch of the cards. There were only ever two combinations of these bits - 0b101 and 0b011. The remaining 10 bits are used for the ID of the card. Card number 1 is 0b0000000001, card number 2 is 0b0000000010 and so on.

I immediately realised there were way more bits than required for the 108 cards in the set and wondered if they were mapped to anything. I recently listened to an Embedded Podcast where Elecia White interviewed Jeri Ellsworth. They spoke about putting Easter eggs in their embedded product and this made me wonder if the developers of the Super Animals card reader toy decided to do the same thing.

So I explained to my 10 year old niece what I was thinking. She was initially skeptical, but we decided to have a go making a paper barcode with the next number in the series. Since I didn't know what the top 3 bits were, we just copied them from one off the other cards and encoded 109 in the 10 ID bits. I explained that binary encoding was similar to the 1's, 10's 100's columns of decimal numbers that they learn in school, except that there were only possible values in each column - 0 and 1 instead of 0 to 9 like in the decimal system. 

We swiped the hand drawn card through the reader. It didn't work.

At this point my niece wasn't overly impressed, but unperturbed I suggested that we try one of the cards in the set that they were missing. We chose card number 18 in the series. I went through the same procedure (using the same top 3 bits), this time encoding 18 in binary instead of the 109 we had just tried.

Success! Chirping bird noises! We checked the list of cards and indeed number 18 is a bird.


So now my niece was convinced I wasn't just making things up, but we had run out of time. I had to go home, but those last three bits continued to bother me so I kept working on the problem there.

I messed around with some 3 bit CRC calculations before I realised that there was no way I could only ever get only 2 combinations like on the cards. I stopped thinking about the 3 bits as a single checksum and saw that the last bit was probably a stop bit, which would make sense for a swipe barcode reader.

I had earlier decided that even or odd parity didn't make sense as I had three bits to deal with, not one. However after a bit more messing around, it finally dawned on me that the other two bits were probably even and odd parity since one was always the inverse of the other.

I had taken photos of all of the cards, so to confirm the parity theory, I used these to make a table of card IDs and 3 bit values. I wrote a quick C++ program to spit out a similar list and diffed the files. Perfect match.

Armed with the ability to generate my own barcodes, I decided to write a Qt program to render these to pdf so that I could print them out and go hunting for Easter eggs (or at the very least, some extra animal noises). 



A couple of days later I managed to get a hold of my own card reader toy, print the cards 109-117 and give it a shot. All of the cards worked. Now I just had to work out if they were duplicates or a completely different set of audio tracks.

To be continued...maybe.

(You can download the pdf for all 1023 barcodes here)