/* AT91SAM7 "presence reader" firmware for OpenPCD * * (C) 2006 by Milosch Meriac <meriac@openpcd.de> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #include <errno.h> #include <string.h> #include <lib_AT91SAM7.h> #include <librfid/rfid_layer2_iso14443a.h> #include "rc632.h" #include <os/dbgu.h> #include <os/led.h> #include <os/pcd_enumerate.h> #include <os/usb_handler.h> #include <pcd/rc632_highlevel.h> #include <librfid/rfid_reader.h> #include <librfid/rfid_layer2.h> #include "../openpcd.h" #include <os/main.h> #define RAH NULL u_int32_t delay_scan,delay_blink,last_uid,last_polled_uid; static struct rfid_reader_handle *rh; static struct rfid_layer2_handle *l2h; static int usb_presence_rx(struct req_ctx *rctx) { struct openpcd_hdr *poh = (struct openpcd_hdr *) rctx->data; switch (poh->cmd) { case OPENPCD_CMD_PRESENCE_UID_GET: DEBUGPCRF("get presence UID"); poh->flags |= OPENPCD_FLAG_RESPOND; if(last_polled_uid) { rctx->tot_len += 4; poh->data[0]=(u_int8_t)(last_polled_uid>>24); poh->data[1]=(u_int8_t)(last_polled_uid>>16); poh->data[2]=(u_int8_t)(last_polled_uid>> 8); poh->data[3]=(u_int8_t)(last_polled_uid ); last_polled_uid=0; } break; default: DEBUGP("UNKNOWN "); return USB_ERR(USB_ERR_CMD_UNKNOWN); break; } if (poh->flags & OPENPCD_FLAG_RESPOND) return USB_RET_RESPOND; return 0; } void _init_func(void) { DEBUGPCRF("enabling RC632"); rc632_init(); DEBUGPCRF("turning on RF"); rc632_turn_on_rf(RAH); DEBUGPCRF("initializing 14443A operation"); rh = rfid_reader_open(NULL, RFID_READER_OPENPCD); l2h = rfid_layer2_init(rh, RFID_LAYER2_ISO14443A); DEBUGPCRF("registering USB handler"); usb_hdlr_register(&usb_presence_rx, OPENPCD_CMD_CLS_PRESENCE); delay_scan=delay_blink=0; last_uid=0; } int _main_dbgu(char key) { unsigned char value; switch (key) { case '4': AT91F_DBGU_Printk("Testing RC632 : "); if (rc632_test(RAH) == 0) AT91F_DBGU_Printk("SUCCESS!\n\r"); else AT91F_DBGU_Printk("ERROR!\n\r"); break; case '5': opcd_rc632_reg_read(RAH, RC632_REG_RX_WAIT, &value); DEBUGPCR("Reading RC632 Reg RxWait: 0x%02xr", value); break; case '6': DEBUGPCR("Writing RC632 Reg RxWait: 0x55"); opcd_rc632_reg_write(RAH, RC632_REG_RX_WAIT, 0x55); break; case '7': rc632_dump(); break; } return -EINVAL; } void _main_func(void) { u_int32_t uid; int status; status = rfid_layer2_open(l2h); if (status >= 0 && l2h->uid_len==4) { uid=((u_int32_t)l2h->uid[0]) | ((u_int32_t)l2h->uid[1])<< 8| ((u_int32_t)l2h->uid[2])<<16| ((u_int32_t)l2h->uid[3])<<24; delay_scan=100; if(uid!=last_uid) { last_uid=last_polled_uid=uid; delay_blink=10; DEBUGPCR("UID:0x%08X", uid); } } else if(delay_scan) delay_scan--; else last_uid=0; led_switch(1,(delay_blink==0)?1:0); if(delay_blink) delay_blink--; /* first we try to get rid of pending to-be-sent stuff */ usb_out_process(); /* next we deal with incoming reqyests from USB EP1 (OUT) */ usb_in_process(); rc632_unthrottle(); }