CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

Magnetic card reader revisited

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Ed Arnold
Guest







Magnetic card reader revisited
PostPosted: Wed Nov 13, 2002 2:13 pm     Reply with quote

<font face="Courier New" size=-1>First, I would like to thank PCM Programmer for posting code to help me a few weeks ago. But, even though it was well documented, it was way over my head. I took a look at the MicroChip's App Note 727 on reading Mag Stripes and this was much clearer to me. Currently, I am using a LCD to display results, but the final use of this reader will simply buffer the data for the Master uController to poll for it. This is the first time I have mixed 'C' and assembly. So, I am not sure what I have done wrong. By the looks of my 'list' file, everything looks like it should work. Have a look at my code. Currently, I am getting no data in the buffer and a 'hex 3F' for my flags. Which translates into start sentinal found, end sentinal found, parity error is true, LRC error is true, and there is a buffer overrun. The cards I am using have a start sentinal(;), 10 data bytes, and an end sentinal(?). I am reading track 2, which has 5 bit data width. My code mostly follows the App Note. Does anyone know what I have done wrong here.

Thanks in advance

Ed Arnold

#include <16f84.h>
#reserve 0x20,0x2F
#fuses HS, NOWDT, NOPROTECT
#use delay(clock=8000000)
#use fast_io(a)
#use fast_io(b)
#zero_ram

#include <lcd.c>

#define _CD PIN_A2 //Card Detect line (active low)
#define _CLK PIN_A3 //Card Clock Line (active low)
#define _CDATA PIN_A4 //Card Data Line (active low)
#define START_CODE 0x58
#define END_CODE 0xF8
#define STATUS 0x03
#define FSR 0x04
#define INDF 0x00
#bit C = STATUS.0
#bit Zero_Flag = STATUS.2
#define P 7

typedef enum {NULL, BUSY, BAD_SWIPE, INVALID, VALID} POLL;
POLL fCARD_POLL;

#define BUF_SIZE 16
char CR_buf[BUF_SIZE];
#locate CR_buf=0x20
int test=0;
int flags;
int PLRC;

#bit next_byte = test.0

#bit found_start = flags.0 // found start sentinel
#bit found_end = flags.1 // found end sentinel
#bit parity_err = flags.2 // bad parity
#bit LRC_err = flags.3 // bad LRC
#bit buf_end = flags.4 // end of buffer
#bit read_write = flags.5 // read / write flag

///............................................................................

main()
{
int i;
set_tris_a(0xFF);
lcd_init();
fCARD_POLL=NULL;
printf(lcd_putc,"Access Card Reader v1.0\n");
while(1)
{
while(input(_CD))
{
if(!flags)fCARD_POLL=NULL;
else if(flags==0x23)fCARD_POLL=VALID;
else fCARD_POLL=BAD_SWIPE;
switch(fCARD_POLL)
{
case NULL :
PLRC=START_CODE;
flags=0; // clear all flags
#asm
MOVLW 0x20 // load buffer pointer into W
MOVWF FSR // move pointer to FSR
#endasm
break;
case VALID :
for(i=0;i<16;i++)
{
lcd_goto_xy(i+1,2);
printf(lcd_putc,"\%c",CR_buf[i]);
}
break;
case BAD_SWIPE :
lcd_goto_xy(18,2);
printf(lcd_putc,"\%x \%d",flags, test);
for(i=0;i<16;i++)
{
lcd_goto_xy(i+1,2);
printf(lcd_putc,"\%c",CR_buf[i]);
}
break;
default:
lcd_goto_xy(20,2);
printf(lcd_putc,"\%d",fCARD_POLL);
break;
}

}
fCARD_POLL=BUSY;
LRC_err=1;
while(input(_CLK))
{
if(next_byte)
{
#asm
RLF CR_buf // discard parity pit by shfting out
SWAPF CR_buf,W // swap nibbles, put data in lower nibble
ANDLW 0x3F // convert to ASCII
MOVWF CR_buf // move back into buffer
INCF FSR,F // inrement buffer pointer FSR++
MOVLW 0x0F // find end of buffer and loop
ANDWF FSR,F // if end is reached
BTFSS Zero_Flag // set buffer end
BSF buf_end // buffer overrun error
BCF PLRC,P // clear parity bit
CLRF CR_buf // clear next buffer byte
BSF CR_buf,4 // set 'check bit'
BCF next_byte
#endasm
}
}
if(input(_CDATA)) //get next incoming bit
{
#asm // data is inverted
BCF STATUS,0 // data bit is '0' clear carry flag
#endasm
}
else
{
#asm
BSF STATUS,0 // data bit is '1' set carry flag
MOVLW 0x80 // toggle parity bit in
XORWF PLRC,F // PLRC register
#endasm
}
#asm
RRF CR_buf // shift bit in current btye
BTFSS STATUS,0 // test carry flag for 'check bit'
GOTO test_start // test for start sentinal
BTFSS PLRC,P // test parity bit, if '1' passed
BSF parity_err // set parity error flag
MOVF CR_buf,W // update LRC nibble
XORWF PLRC,F // test LRC bit if '0' passed
//.............................................................
BTFSS found_end // was end sentinal found before
GOTO test_end // test for end sentinal
MOVF PLRC,W // load LRC into W
ANDLW 0x78 // mask off unwanted bits
BTFSC Zero_Flag // test LRC if '0' passed
BCF LRC_err // clear LRC error flag
BSF read_write // set read_write bit
GOTO end // done ready for read
//.............................................................
test_end:
MOVLW END_CODE // load end code into W
XORWF CR_buf,W // compare with end code
BTFSC Zero_Flag // is this the end sentinal?
BSF found_end // set found_end flag
GOTO next // prepare for next byte
//.............................................................
test_start:
BTFSC found_start // was start sentinal found before
GOTO end // yes, go to end
MOVLW 0xF8 // load mask into W
ANDWF CR_buf // mask current byte in buffer
MOVLW START_CODE // load start code into W
XORWF CR_buf,W // compare with start code
BTFSS Zero_Flag // is this the start sential?
GOTO end
BSF found_start // set found_start flag
//...........................................................
next:
BSF next_byte
end:
#endasm
while(!input(_CLK));
}
}
___________________________
This message was ported from CCS's old forum
Original Post ID: 8861
Ed Arnold
Guest







Re: Magnetic card reader please help!
PostPosted: Thu Nov 14, 2002 1:40 pm     Reply with quote

Adding 'Please Help' seems to work for others so I'll try it. I have made very little progress with this code. I am not sure if my use of #reserve and #locate are correct. I am tring to use the same ram loctions for a buffer. So the 'C' code and assembly use the same buffer. I am not sure if my use of FSR and INDF is correct either. I have placed test points all over. At the end of a swipe, the FSR is 0x2E, which doesn't make sense. I also use test2 to see how many times next_byte routine is run. That equals 12 times which is correct for the cards I am using. Does anyone know what could be happening?

Thanks in advance

Ed Arnold

:=#include <16f84.h>
:=#reserve 0x20,0x2F
:=#fuses HS, NOWDT, NOPROTECT
:=#use delay(clock=8000000)
:=#use fast_io(a)
:=#use fast_io(b)
:=#zero_ram
:=
:=#include <lcd.c>
:=
:=#define _CD PIN_A2 //Card Detect line (active low)
:=#define _CLK PIN_A3 //Card Clock Line (active low)
:=#define _CDATA PIN_A4 //Card Data Line (active low)
:=#define START_CODE 0x58
:=#define END_CODE 0xF8
:=#define STATUS 0x03
:=#define FSR 0x04
:=#define INDF 0x00
:=#bit C = STATUS.0
:=#bit Zero_Flag = STATUS.2
:=#define P 7
:=
:=typedef enum {NULL, BUSY, BAD_SWIPE, INVALID, VALID} POLL;
:=POLL fCARD_POLL;
:=
:=#define BUF_SIZE 16
:=char CR_buf[BUF_SIZE];
:=#locate CR_buf=0x20
:=int test=0;
:=int flags;
:=int PLRC;
:=
:=#bit next_byte = test.0
:=
:=#bit found_start = flags.0 // found start sentinel
:=#bit found_end = flags.1 // found end sentinel
:=#bit parity_err = flags.2 // bad parity
:=#bit LRC_err = flags.3 // bad LRC
:=#bit buf_end = flags.4 // end of buffer
:=#bit read_write = flags.5 // read / write flag
:=
:=///............................................................................
:=
:=main()
:={
:= int i;
:= set_tris_a(0xFF);
:= lcd_init();
:= fCARD_POLL=NULL;
:= printf(lcd_putc,"Access Card Reader v1.0\n");
:= while(1)
:= {
:= while(input(_CD))
:= {
:= if(!flags)fCARD_POLL=NULL;
:= else if(flags==0x23)fCARD_POLL=VALID;
:= else fCARD_POLL=BAD_SWIPE;
:= switch(fCARD_POLL)
:= {
:= case NULL :
:= PLRC=START_CODE;
:= flags=0; // clear all flags
:= #asm
:= MOVLW 0x20 // load buffer pointer into W
:= MOVWF FSR // move pointer to FSR
:= #endasm
:= break;
:= case VALID :
:= for(i=0;i<16;i++)
:= {
:= lcd_goto_xy(i+1,2);
:= printf(lcd_putc,"\%c",CR_buf[i]);
:= }
:= break;
:= case BAD_SWIPE :
:= lcd_goto_xy(18,2);
:= printf(lcd_putc,"\%x \%d",flags, test2);
:= for(i=0;i<16;i++)
:= {
:= lcd_goto_xy(i+1,2);
:= printf(lcd_putc,"\%c",CR_buf[i]);
:= }
:= break;
:= default:
:= lcd_goto_xy(20,2);
:= printf(lcd_putc,"\%d",fCARD_POLL);
:= break;
:= }
:=
:= }
:= fCARD_POLL=BUSY;
:= LRC_err=1;
:= while(input(_CLK))
:= {
:= if(next_byte)
:= {
:= test2++; // test how many times entered here
:= #asm
:= RLF CR_buf // discard parity pit by shfting out
:= SWAPF CR_buf,W // swap nibbles, put data in lower nibble
:= ANDLW 0x3F // convert to ASCII
:= MOVWF CR_buf // move back into buffer
:= INCF FSR,F // inrement buffer pointer FSR++
:= MOVLW 0x0F // find end of buffer and loop
:= ANDWF FSR,F // if end is reached
:= BTFSC Zero_Flag // set buffer end
:= BSF buf_end // buffer overrun error
:= BCF PLRC,P // clear parity bit
:= CLRF CR_buf // clear next buffer byte
:= BSF CR_buf,4 // set 'check bit'
:= BCF next_byte
:= #endasm
:= }
:= }
:= if(input(_CDATA)) //get next incoming bit
:= {
:= #asm // data is inverted
:= BCF STATUS,0 // data bit is '0' clear carry flag
:= #endasm
:= }
:= else
:= {
:= #asm
:= BSF STATUS,0 // data bit is '1' set carry flag
:= MOVLW 0x80 // toggle parity bit in
:= XORWF PLRC,F // PLRC register
:= #endasm
:= }
:= #asm
:= RRF CR_buf // shift bit in current btye
:= BTFSS STATUS,0 // test carry flag for 'check bit'
:= GOTO test_start // test for start sentinal
:= BTFSS PLRC,P // test parity bit, if '1' passed
:= BSF parity_err // set parity error flag
:= MOVF CR_buf,W // update LRC nibble
:= XORWF PLRC,F // test LRC bit if '0' passed
:= //.............................................................
:= BTFSS found_end // was end sentinal found before
:= GOTO test_end // test for end sentinal
:= MOVF PLRC,W // load LRC into W
:= ANDLW 0x78 // mask off unwanted bits
:= BTFSC Zero_Flag // test LRC if '0' passed
:= BCF LRC_err // clear LRC error flag
:= BSF read_write // set read_write bit
:= GOTO end // done ready for read
:= //.............................................................
:= test_end:
:= MOVLW END_CODE // load end code into W
:= XORWF CR_buf,W // compare with end code
:= BTFSC Zero_Flag // is this the end sentinal?
:= BSF found_end // set found_end flag
:= GOTO next // prepare for next byte
:= //.............................................................
:= test_start:
:= BTFSC found_start // was start sentinal found before
:= GOTO end // yes, go to end
:= MOVLW 0xF8 // load mask into W
:= ANDWF CR_buf // mask current byte in buffer
:= MOVLW START_CODE // load start code into W
:= XORWF CR_buf,W // compare with start code
:= BTFSS Zero_Flag // is this the start sential?
:= GOTO end
:= BSF found_start // set found_start flag
:= //...........................................................
:= next:
:= BSF next_byte
:= end:
:= #endasm
:= while(!input(_CLK));
:= }
:=}
:= ___________________________
This message was ported from CCS's old forum
Original Post ID: 8936
Laurent chouinard
Guest







Re: Magnetic card reader please help!
PostPosted: Fri Nov 15, 2002 1:26 pm     Reply with quote

I don't know about others, but I'm certainly not an expert in assembly, which is why I bought CCS's compiler. From what I see in your code, there's a heck of a lot of ASM code!! I can't really grasp what your program is doing because frankly, I don't really like assembly...

About adding "Please help" to gain more attention, i bet that the reason you had no reply yet is because it's mostly ASM code and we're all a bunch of C programmers :)

Laurent

:=Adding 'Please Help' seems to work for others so I'll try it. I have made very little progress with this code. I am not sure if my use of #reserve and #locate are correct. I am tring to use the same ram loctions for a buffer. So the 'C' code and assembly use the same buffer. I am not sure if my use of FSR and INDF is correct either. I have placed test points all over. At the end of a swipe, the FSR is 0x2E, which doesn't make sense. I also use test2 to see how many times next_byte routine is run. That equals 12 times which is correct for the cards I am using. Does anyone know what could be happening?
:=
:=Thanks in advance
:=
:=Ed Arnold
:=
:=:=#include <16f84.h>
:=:=#reserve 0x20,0x2F
:=:=#fuses HS, NOWDT, NOPROTECT
:=:=#use delay(clock=8000000)
:=:=#use fast_io(a)
:=:=#use fast_io(b)
:=:=#zero_ram
:=:=
:=:=#include <lcd.c>
:=:=
:=:=#define _CD PIN_A2 //Card Detect line (active low)
:=:=#define _CLK PIN_A3 //Card Clock Line (active low)
:=:=#define _CDATA PIN_A4 //Card Data Line (active low)
:=:=#define START_CODE 0x58
:=:=#define END_CODE 0xF8
:=:=#define STATUS 0x03
:=:=#define FSR 0x04
:=:=#define INDF 0x00
:=:=#bit C = STATUS.0
:=:=#bit Zero_Flag = STATUS.2
:=:=#define P 7
:=:=
:=:=typedef enum {NULL, BUSY, BAD_SWIPE, INVALID, VALID} POLL;
:=:=POLL fCARD_POLL;
:=:=
:=:=#define BUF_SIZE 16
:=:=char CR_buf[BUF_SIZE];
:=:=#locate CR_buf=0x20
:=:=int test=0;
:=:=int flags;
:=:=int PLRC;
:=:=
:=:=#bit next_byte = test.0
:=:=
:=:=#bit found_start = flags.0 // found start sentinel
:=:=#bit found_end = flags.1 // found end sentinel
:=:=#bit parity_err = flags.2 // bad parity
:=:=#bit LRC_err = flags.3 // bad LRC
:=:=#bit buf_end = flags.4 // end of buffer
:=:=#bit read_write = flags.5 // read / write flag
:=:=
:=:=///............................................................................
:=:=
:=:=main()
:=:={
:=:= int i;
:=:= set_tris_a(0xFF);
:=:= lcd_init();
:=:= fCARD_POLL=NULL;
:=:= printf(lcd_putc,"Access Card Reader v1.0\n");
:=:= while(1)
:=:= {
:=:= while(input(_CD))
:=:= {
:=:= if(!flags)fCARD_POLL=NULL;
:=:= else if(flags==0x23)fCARD_POLL=VALID;
:=:= else fCARD_POLL=BAD_SWIPE;
:=:= switch(fCARD_POLL)
:=:= {
:=:= case NULL :
:=:= PLRC=START_CODE;
:=:= flags=0; // clear all flags
:=:= #asm
:=:= MOVLW 0x20 // load buffer pointer into W
:=:= MOVWF FSR // move pointer to FSR
:=:= #endasm
:=:= break;
:=:= case VALID :
:=:= for(i=0;i<16;i++)
:=:= {
:=:= lcd_goto_xy(i+1,2);
:=:= printf(lcd_putc,"\%c",CR_buf[i]);
:=:= }
:=:= break;
:=:= case BAD_SWIPE :
:=:= lcd_goto_xy(18,2);
:=:= printf(lcd_putc,"\%x \%d",flags, test2);
:=:= for(i=0;i<16;i++)
:=:= {
:=:= lcd_goto_xy(i+1,2);
:=:= printf(lcd_putc,"\%c",CR_buf[i]);
:=:= }
:=:= break;
:=:= default:
:=:= lcd_goto_xy(20,2);
:=:= printf(lcd_putc,"\%d",fCARD_POLL);
:=:= break;
:=:= }
:=:=
:=:= }
:=:= fCARD_POLL=BUSY;
:=:= LRC_err=1;
:=:= while(input(_CLK))
:=:= {
:=:= if(next_byte)
:=:= {
:=:= test2++; // test how many times entered here
:=:= #asm
:=:= RLF CR_buf // discard parity pit by shfting out
:=:= SWAPF CR_buf,W // swap nibbles, put data in lower nibble
:=:= ANDLW 0x3F // convert to ASCII
:=:= MOVWF CR_buf // move back into buffer
:=:= INCF FSR,F // inrement buffer pointer FSR++
:=:= MOVLW 0x0F // find end of buffer and loop
:=:= ANDWF FSR,F // if end is reached
:=:= BTFSC Zero_Flag // set buffer end
:=:= BSF buf_end // buffer overrun error
:=:= BCF PLRC,P // clear parity bit
:=:= CLRF CR_buf // clear next buffer byte
:=:= BSF CR_buf,4 // set 'check bit'
:=:= BCF next_byte
:=:= #endasm
:=:= }
:=:= }
:=:= if(input(_CDATA)) //get next incoming bit
:=:= {
:=:= #asm // data is inverted
:=:= BCF STATUS,0 // data bit is '0' clear carry flag
:=:= #endasm
:=:= }
:=:= else
:=:= {
:=:= #asm
:=:= BSF STATUS,0 // data bit is '1' set carry flag
:=:= MOVLW 0x80 // toggle parity bit in
:=:= XORWF PLRC,F // PLRC register
:=:= #endasm
:=:= }
:=:= #asm
:=:= RRF CR_buf // shift bit in current btye
:=:= BTFSS STATUS,0 // test carry flag for 'check bit'
:=:= GOTO test_start // test for start sentinal
:=:= BTFSS PLRC,P // test parity bit, if '1' passed
:=:= BSF parity_err // set parity error flag
:=:= MOVF CR_buf,W // update LRC nibble
:=:= XORWF PLRC,F // test LRC bit if '0' passed
:=:= //.............................................................
:=:= BTFSS found_end // was end sentinal found before
:=:= GOTO test_end // test for end sentinal
:=:= MOVF PLRC,W // load LRC into W
:=:= ANDLW 0x78 // mask off unwanted bits
:=:= BTFSC Zero_Flag // test LRC if '0' passed
:=:= BCF LRC_err // clear LRC error flag
:=:= BSF read_write // set read_write bit
:=:= GOTO end // done ready for read
:=:= //.............................................................
:=:= test_end:
:=:= MOVLW END_CODE // load end code into W
:=:= XORWF CR_buf,W // compare with end code
:=:= BTFSC Zero_Flag // is this the end sentinal?
:=:= BSF found_end // set found_end flag
:=:= GOTO next // prepare for next byte
:=:= //.............................................................
:=:= test_start:
:=:= BTFSC found_start // was start sentinal found before
:=:= GOTO end // yes, go to end
:=:= MOVLW 0xF8 // load mask into W
:=:= ANDWF CR_buf // mask current byte in buffer
:=:= MOVLW START_CODE // load start code into W
:=:= XORWF CR_buf,W // compare with start code
:=:= BTFSS Zero_Flag // is this the start sential?
:=:= GOTO end
:=:= BSF found_start // set found_start flag
:=:= //...........................................................
:=:= next:
:=:= BSF next_byte
:=:= end:
:=:= #endasm
:=:= while(!input(_CLK));
:=:= }
:=:=}
:=:= ___________________________
This message was ported from CCS's old forum
Original Post ID: 9020
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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 vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group