#include <16F688.h> #include #include //#fuses HS,NOWDT,NOPROTECT,NOBROWNOUT,NOMCLR,PUT //#use delay(clock=20000000) #fuses INTRC_IO,NOWDT,NOPROTECT,NOBROWNOUT,MCLR,PUT #use delay(clock=8000000) #use rs232(stream=console,baud=9600,parity=N,bits=8,XMIT=PIN_C4,RCV=PIN_C5,ERRORS) /////////////////////// pinout: PIC16F688 #define MT_CARD PIN_A0 #define MT_DATA PIN_A1 #define MT_CLK PIN_A2 // must be RA2, the external interrupt pin #define BUTTON1 PIN_A3 #define LED2 PIN_A4 #define LED1 PIN_C3 #define LCD_ECLK PIN_C0 #define LCD_DCLK PIN_C1 #define LCD_DATA PIN_C2 // 1 - vdd+ vss- - 14 // 2 - reader? ra5 ra0 MTcard - 13 // 3 - led2 ra4 ra1 MTdata - 12 // 4 - reset ra3 ra2 MTclk - 11 // 5 - debugrx rc5 rc0 lcdEclk - 10 // 6 - debugtx rc4 rc1 lcdDclk - 9 // 7 - led1 rc3 rc2 lcdData - 8 /////////////////////// prototypes int init(); /////////////////////// prototypes: magtek stuff int magtek_read(); /////////////////////// prototypes: rs232 stuff // signed int get_int(); // void get_string(char* s, int max); // char fgetc_timed(); /////////////////////// prototypes: lcd stuff int lcd_init(); int lcd_nibble(int8 rsbit, char out); int lcd_putc(char c); int lcd_clear(); int lcd_clearregister(); int lcd_gotoxy(int x, int y); /////////////////////// main void main() { // fprintf(console,"start...\r\n"); output_high(LED2); init(); // fprintf(console,"prelcdinit...\r\n"); delay_ms(3000); lcd_init(); // fprintf(console,"preclear...\r\n"); delay_ms(3000); // lcd_clear(); // fprintf(console,"waiting for mag swipe...\r\n"); // lcd_clear(); // printf(lcd_putc,"init..."); // delay_ms(2000); lcd_clear(); delay_ms(500); output_low(LED2); printf(lcd_putc,"Ready for swipe"); delay_ms(500); // fprintf(console,"ready...\r\n"); magtek_read(); output_low(LED2); // card removed // lcd_gotoxy(1,2); // fprintf(console,"done.\r\n"); while(1) { output_high(LED1); delay_ms(100); output_low(LED1); delay_ms(1900); } } /////////////////////// general functions int init() { output_low(LED1); output_low(LCD_ECLK); output_low(LCD_DCLK); output_low(LCD_DATA); switch ( restart_cause() ) { case NORMAL_POWER_UP: { output_high(LED1); break; } default: { output_high(LED1); break; } } return 0; } /////////////////////// rs232 Functions ////// put these back for debugging // signed int get_int(); // void get_string(char* s, int max); // char fgetc_timed(); /////////////////////// LCD Functions int lcd_init() { int8 i; lcd_clearregister(); //extra for(i=0;i<3;++i) { lcd_nibble(0,0x30); } // init lcd_nibble(0,0x20); // 4bit mode lcd_nibble(0,0x10); lcd_nibble(0,0x80); // 2rows,5x7 lcd_nibble(0,0x10); lcd_nibble(0,0x00); // display off lcd_nibble(0,0x00); lcd_nibble(0,0x10); // display clear lcd_nibble(0,0x10); lcd_nibble(0,0x80); // setup cursor move lcd_nibble(0,0x00); lcd_nibble(0,0xF0); // enable display/cursor return 0; } int lcd_clearregister() { int8 i; output_low(LCD_DATA); output_low(LCD_DCLK); output_low(LCD_ECLK); for(i=0;i<5;++i) { // spin the clock output_high(LCD_DCLK); output_low(LCD_DCLK); } return 0; } int lcd_nibble(int8 rsbit, char out) { int8 i; lcd_clearregister(); // fprintf(console,"LCD: %x\r\n",out); output_bit(LCD_DATA,rsbit); output_high(LCD_DCLK); delay_cycles(1); output_low(LCD_DCLK); for (i=0;i<4;i++) { output_low(LCD_DCLK); output_bit(LCD_DATA, shift_left(&out,1,0)); output_high(LCD_DCLK); delay_cycles(1); output_low(LCD_DCLK); } output_low(LCD_DCLK); output_high(LCD_ECLK); delay_cycles(1); output_low(LCD_ECLK); delay_ms(5); return 0; } int lcd_putc(char c) { lcd_nibble(1, c); delay_cycles(1); shift_left(&c,1,0); shift_left(&c,1,0); shift_left(&c,1,0); shift_left(&c,1,0); lcd_nibble(1, c); delay_cycles(1); return 0; } int lcd_clear() { lcd_nibble(0,0x00); lcd_nibble(0,0x10); // display clear return 0; } int lcd_gotoxy(int x, int y) { int i; byte addr; if (y>1) { addr=0x40; } else { addr=0; } addr+=x-1; addr=0x80 | addr; lcd_nibble(0, addr); for(i=0;i<4;++i) { shift_left(&addr,1,0); } lcd_nibble(0, addr); return 0; } /////////////////////// Magtek Functions int magtek_read() { int i,j,k; int bit; int done; int bitnum; int started; int thebyte; char value; int bytenum; int result[48]; started=0; bytenum=0; done=0; while(!done) { if (!input(MT_CARD)) { output_high(LED1); // card present output_high(LED2); // card present // fprintf(console,"Card inserted!\r\n"); while (!input(MT_CARD)) { // wait until the clock is low while (input(MT_CLK) && !input(MT_CARD)) { } // wait for the clock to go high while (!input(MT_CLK) && !input(MT_CARD)) { } // just went high bit = !input(MT_DATA); if (!started && bit) { started=1; bitnum=1; } if (started) { // fprintf(console,"%d", bit); shift_left(&thebyte,1,bit); if (bitnum > 4) { shift_left(&thebyte,1,0); shift_left(&thebyte,1,0); shift_left(&thebyte,1,0); result[bytenum] =thebyte; bytenum++; // fprintf(console," (%x)", thebyte); bitnum=1; } else { bitnum++; } } } // TODO: once the card goes away, perform parity and // LRC checks, and output the data XXX //delay_ms(200); // fprintf(console,"Card removed!\r\n"); output_low(LED1); // card removed started=0; done=1; j=0; k=0; lcd_clear(); for (i=0;i<=bytenum;i++) { switch (result[i]) { case 0xd0: { value=0; break; } //start sentinal case 0x08: { value='0'; break; } case 0x80: { value='1'; break; } case 0x40: { value='2'; break; } case 0xc8: { value='3'; break; } case 0x20: { value='4'; break; } case 0xa8: { value='5'; break; } case 0x68: { value='6'; break; } case 0xe0: { value='7'; break; } case 0x10: { value='8'; break; } case 0x98: { value='9'; break; } case 0xb0: { value='|'; break; } // field separator case 0xf8: { value=0; break; } //end sentinal case 0x00: { value=0; break; } // default: { value=result[i]; } } if (value!=0) { j++; k++; if (k==17) { lcd_gotoxy(1,2); } if (k>33) { return 1; } // if (j > 4) { j=0; printf(lcd_putc,"_"); } // fprintf(console,"%c", value); printf(lcd_putc,"%c", value); } else { // fprintf(console,"ZZ", value); } } bytenum=0; // fprintf(console,"\r\n"); } } return 0; }