In this lab assignment, you will complete the design of the magnetic stripe reader. You already have a working LCD controller. You will add to this a circuit that collects data from the magnetic stripe reader and sends it to the LCD interface to be displayed.
Once again, you should fully design and simulate a circuit before you try to construct it. You should do as much as you can before attending lab session. You will have a total of two more weeks to complete the project, but please don’t wait until the last week! There will be no formal lab sessions the last week. Instead, we will post information on when TAs will be available in the lab to help you.
You will add one more PAL to your circuit as shown below to implement the interface to the magnetic stripe reader. The mag stripe reader send data serially, i.e. bit-by-bit, to the Mag Reader PAL. This PAL contains a controller that examines the serial bit-stream, collects the characters and displays them using the LCD interface.
The first thing you need to do is understand what the Magnetic Stripe Reader produces. You must study the datasheet and associated information, although we will summarize the main points here. There are three signals that you need to understand: CLS (card loaded), RDP (data), and RCP (clock). All three signals are asserted low. That is, CLS is 0 when the card is loaded, that is, in the slot, the data signal is inverted, and the clock is reversed so the high-to-low edge is the active edge.
The following timing diagram, copied from the datasheet, describes what happens when a stripe is read. Pay attention only to the RCP1, RDP1 and CLS signals. (The RCP2 and RDP2 signals are for the second track on the stripe, which we will ignore, unless you are interested in a bigger challenge!). The overbar means they are active low. CLS is asserted when the card is entered into the card reader. At some later point, the RCP and then RDP signals start to be asserted. The falling edge of RCP tells you when to sample the data signal: it’s a clock, but you will not use it to clock registers, just as another input signal. You should use the system clock, which is running much faster than RCP, to sample RCP. When you detect a 1 on RCP followed by a zero, you should sample the data bit on RDP. (We will not use RCP as a clock signal for our registers because it is not always running, only when a card is running through the reader.)
Data is sent in bit-serial fashion, 7 bits per character, low-order bit (LSB) first. The first six (low-order) bits are the 6-bit ASCI code, while the last, highest-order, bit is a parity bit, which you may ignore.
Note that in the timing diagram, the data is 0 for a while before a 1 appears - the first character starts with this first 1. The first character is a “start sentinel”, which is ‘1000101’. This is actually the data value ‘5’, with the high-order parity bit set. The character arrives in the order ‘1010001’, that is, low-order bit first. All the character definitions are given in the following table, which appears in full in the documentation. (This is more readable than the corresponding table in the datasheet.) You should compare this character code to the character code used by the LCD – they are not quite the same so you will have to do a translation.
Your design should be done in two parts. The first part should just worry about looking for edges on RCP, looking for the first data bit and counting data bits to keep track of where characters start and end so that it can send a write signal to the LCD controller. The second part should just collect the data bits into a character that can be sent to the LCD. Since you do not have enough room in one PAL for both these circuits, you should implement the second part in the data buffer PAL, which, let’s face it, isn’t doing very much right now. Partitioning a circuit into pieces that operate in parallel and work together to implement all the functionality is a very important task. We’ve told you how to partition the circuit. Now you will have to figure out how to make this partitioning work.
The signals from the magnetic stripe reader are not synchronous to our clock, meaning they can change anytime, even right when our clock is “ticking”. This means, that if we sample one of these signals with a register, we could violate the setup/hold time constraints of the register. We will address this in class, but for now, the way to solve this problem is to put two registers back to back (a shift register) on the RCP input and only use the output of the second register. (Why do you need to do this only for RCP?)
As always, you should make sure your circuit works in simulation before you try to build it. In addition to the LCD test fixture that we gave you last time, we will give you a magnetic card reader test fixture (the old one is here) that will generate the appropriate inputs to test your circuit. The magnetic stripe card reader should send the characters “HELL0!!!” to the LCD if your circuit works correctly.
You should be able to construct the circuit on a single prototyping board by sharing columns with a PAL, e.g. the dataBuffer PAL. If you decide to use two boards (this will cause you more pain than it’s worth) make sure you use only one board for power and leave the other board turned off. Powering up both boards could fry them and you will be responsible!
After you construct your entire circuit, it may not work correctly. Now what? The clock is running so fast (100KHz) that there is no chance of seeing what is going on. We could teach you how to use a logic analyzer, but that would take too much time. What we have done is to implement a stoppable clock (just like in lecture). If you switch the board to Step Mode, when you swipe a card, the FPGA on the board will collect all the signals and then replay them to you as you step the clock. This way, you can see exactly what your circuit does and, we hope, show you the error of your ways. We will publish the pins that are used to implement this testing interface.
Connection from cardreader to FPGA:
CLS - PD0
RCP1 - PD1
RDP1 - PD2
Connection from FPGA to your circuit:
outRDP - PD4
outRCP - PD5
outCLS - PD6
Common reset - LD6 (wired to BTN1)
SW8 - same as always
Card Reader pinouts:
Pin 1 (white) - Frame GND
Pin 2 (grey) - Signal GND
Pin 3 (purple) - VCC
Pin 7 (orange) - RDP1
Pin 8 (red) - RCP1
Pin 9 (brown) - CLS
How to use the debugging interface:
1) Press reset (BTN1) and give one clock pulse (BTN4)
2) Single step the clock until the LCD is reset and ready for data.
3) Press BTN3 to signal (a clock pulse from BTN4 is not necessary) the FPGA that the circuit is ready for data.
4) Single stepping from here will pipe the data bits out in the following manner:
a) First 3 clock ticks, CLS low
b) RCP high 2 clock ticks
c) RCP low 2 clock ticks
d) repeat steps b and c until 32 bits have been delivered
e) last 3 clock ticks, CLS low then goes high
Here are a couple options for extra credit, and you may add to these if you have a good idea.
1. The project can be implemented with just three PALs if you are clever enough.
2. There are two tracks of data on a card. Display the characters on both tracks using a switch to indicate which track to display. You will need the following table.
To get full credit for the final project, turn in the following by the due date: