BasicMicroUK - Forums

www.basicmicro.co.uk
It is currently Tue Jul 17, 2018 8:01 pm

All times are UTC [ DST ]




Post new topic Reply to topic  [ 1 post ] 
Author Message
 Post subject: Using The Atom In the Shop: ABA Card Reader Analyzer
PostPosted: Sat May 30, 2009 8:28 am 
Offline
Master

Joined: Mon Aug 18, 2008 1:26 am
Posts: 799
Location: CA bay Area
Once again I was glad to have a Basic Micro Atom on my bench. :D My version is the OEM Basic Atom Board from EL Products.com.

My employer had a new proximity card reader to check out. He knew it had a data output format similar to what we were using with our magnetic card readers, but different enough to keep it from working with the reader software we had written earlier. My job was to get a dump, in any form, of the data from a special prox card for him to study.
FYI, the card's data format is ABA (darned if I know what ABA means), which consists of two signals: a clock and the card data in a 5-bit packet, where four-bits are a hex character (0-F) and the fifth is a parity bit. The clock is used by the host processor to determine when to sample the data. The clock's falling edge is guaranteed to come in the middle of the data bit. The clock rate is fixed in the reader's controls. You place the card on the reader, which queries the card for its data using RFID (Radio Frequency ID). The reader then uses two wires to send this data to the host processor. In this case the host processor is one of our Local Intelligence Units, a board used in security systems.

I connected the reader to our LIU at the terminal block, then connected a 200MHz oscilloscope in parallel with the two wires. I set the 'scope for single-capture, used the clock for the trigger, and read the card. And there it was: two traces, the clocks across the top, the data bits across the bottom. What jumped out right away was how the data stayed high for the first 25 clocks. (This period was probably used to synch the signal or provide a preamble for the processor to work gainst, if needed.) And I was unpleasantly surprised as to how little data showed in this sample. I kept adjusting the sweep speed on the o-scope slower to see more of the data stream, until the clocks were undistinguishable from each other.
Problem: we suspected that the unit was going to send *at least* 220 bits of data. It was obvious we couldn't see the clocks individually on a display set for a sweep speed slow enough to get all the data in. And there wasn't enough sample memory in the o-scope to allow us to set the sweep faster and then go scroll through all the data and hand-record the bits based on clock edges. We had a logic analyzer, the Ant8, but it had the same limitation: insufficient sample memory for the job.

At this point my employer started talking about renting a better logic analyzer. I pointed out the Atom could easily sample at the rate needed and could be used to write the bit values directly to a terminal screen. He gave me permission to try it out. At last! I'm getting paid to write code for the Atom to get past a problem!

Four hours later I was printing the number of clocks seen and dumping the inverted bit values as 40-character lines of 1s nd 0s. (why can't the stupid reader just put out inverted bits in the first place?) I printed the data dump from two different cards and left it to my employer to divvy the lines into packets, then work out the character values. This was all gratefully received, as it eliminated human error while tediously trying to match traces up by eyeball.

A short theory-of-operation:
1. I initialize the EXTINT (external interrupt, pin RB0) to fire on a low-going clock edge.
2. The MAIN: routine sends out "It's alive!" to let the user know things are running, then loops constantly while waiting for a switch on P7 to get pressed (pin goes low).
3. Meanwhile, every clock/interrupt records the data's bit value to the bit zero of an arrayed variable called "Bit_In", whose array value is set by "index", whose value gets incremented last thing. Why record a bit to a byte? Long painful story, ran out of time, don't ask...
4. After the reader beeps to signal the card has been read, the user presses the switch at P7. By now all the clocks and data have been sent to the LIU and the Atom.
5. The Atom prints out the value in "index" minus one as the number of clocks (226, every time).
6. Lastly, it reads back all the recorded bits one at a time, inverts the bit value, then sends it to the screen.

We now come to the code and a picture of the bench set up. Sorry, I can't show the data dump or proximity reader, that's proprietary info. The code is pretty well commented, you should be able to follow along.
Love that Atom!
kenjj

CODE STARTS
Code:
;ABA reader for studying new Prox Reader
;Started 25 May 2009 By Ken J
; Final version 27 May 2009
; Clock's falling edge triggers an interrupt, which reads data level at B1.
; After suitable collection time, press switch at P7 to start dump of inverted
; stored bits to terminal. Use CAPTURE feature to record and print results.
; NOTE reports and records 226 clocks/data bits.

Bit_In VAR BYTE[228]
Switch_In VAR BIT
CHAR VAR NIB
index VAR BYTE
inloop VAR BYTE
temp VAR BYTE

;INITIALIZATION(S)
; Set up Interrupts
oninterrupt extint, IH_EXTINT
setextint ext_H2L
ENABLE extint
;End interrupt set up
TRISB = %11111111  ; PortB is all inputs
SETPULLUPS PU_ON  ; Turn on weak pullups
CLEAR  ; Clear all variables

MAIN:
SEROUT 14, i19200, [0,13, "It's Alive!!!", 13]  ; Clear screen, show Atom is running
; After card finishes reading, hit switch at P7 to start bits printout.
LOOPER
Switch_In = IN7
IF Switch_In = 1 THEN LOOPER
temp = 0  ;Why I have to zero this after a CLEAR is a mystery...
index = index - 1  ; 'index' is one too many at end of bit collection, must correct this
; Switch is pressed, print out number of clocks, inverted bit array (40 digits per row)
SEROUT 14, i19200, [13, "# of clocks: ", DEC (index), 13]  ; 'index' is number of clocks seen

FOR inloop = 0 to (index)
; Invert bit before printing
IF Bit_In(inloop).bit0 = 1 THEN
Bit_In(inloop).bit0 = 0
ELSE
Bit_In(inloop).bit0 = 1
ENDIF

; Print inverted binary value
SEROUT 14, i19200, [BIN Bit_In(inloop).bit0]
; At 40 characters do a Return
temp = temp + 1
IF temp = 40 THEN
SEROUT 14, i19200, [13]  ; Time for a carriage return
temp = 0
ENDIF
NEXT ; index

END  ; End program
;SubRoutine(s)
; None

;Interrupt Handler(s)
;Start by disabling all interrupts
DISABLE

IH_EXTINT
Bit_In(index).bit0 = IN3  ; save data bit
index = index + 1
RESUME

CODE ENDS


Attachments:
Atom-ABA Reader setup.JPG
Atom-ABA Reader setup.JPG [ 73.69 KiB | Viewed 2043 times ]

_________________
kenjj
http://blog.basicmicro.com/
http://kjennejohn.wordpress.com/
Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 1 post ] 

All times are UTC [ DST ]


Who is online

Users browsing this forum: No registered users and 0 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Jump to:  
cron
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group

phpBB SEO