📄 m500auc.c
字号:
///////////////////////////////////////////////////////////////////////////////
// Copyright (c), Philips Semiconductors Gratkorn
//
// (C)PHILIPS Electronics N.V.2000
// All rights are reserved. Reproduction in whole or in part is
// prohibited without the written consent of the copyright owner.
// Philips reserves the right to make changes without notice at any time.
// Philips makes no warranty, expressed, implied or statutory, including but
// not limited to any implied warranty of merchantibility or fitness for any
//particular purpose, or that the use will not infringe any third party patent,
// copyright or trademark. Philips must not be liable for any loss or damage
// arising from its use.
///////////////////////////////////////////////////////////////////////////////
#define DLL_EXPORT // library source module definition
#include <p89c51rx.h>
#include <Mfreg531.h>
#include <M500A.h>
#include <RdIo.h>
#include <string.h>
#include <stdio.h>
#include <main.h>
////////////////////////////////////////////////////////////////////////////////
// M O D U L E D E F I N I T I O N
////////////////////////////////////////////////////////////////////////////////
// COMMENT: This library module is modified from the original source code for a
// microcontroller C164 CI, to suit the general purpose 8051 mcu.
// The source can be ported to other platforms very easily.
// The communication channel to the RC500 reader IC is assumed to be
// unknown. All data is written with the generic IO functions
// of the module ReaderIO.h. In our case the reader module is
// connected via memory mapped io at base address 0x7f00.
// The interrupt pin of the reader IC is assumed to be connected to
// the fast external interrupt pin INT0# (active low) and the reset
// pin of the reader IC should be connected to a dedicated port pin
// (Port3: Pin: 3).
// In this configuration, a reset of the reader module is independend
// from the reset of the microcontroller.
// In order to generate communication timeouts,
// general purpose timer 2 of the microcontroller is used. This
// timer need not to be initialised in advance. Before every usage
// the timer is completely initialised in each function.
// Non of the timers is essential for the functionality of the reader
// module, but are helpful furing software development. All protocoll
// relevant timing constraints are generated
// by the internal timer of the reader module.
//
// Some explanations to the programming method of this library.
// There are three kind of functions coded in this module.
// a) internal functions, which have no prototypes in a header
// file and are not intended to be used outside of this file
// b) commands, which are intended for the reader module itself
// c) commands, which are intended for any tag in the rf field.
// These commands are send to the reader and the reader module
// transmitts the data to the rf interface.
// Commands for the reader and for the tag have the appropriate
// prefix (PCD for proximity coupled device or reader module
// PICC for proximity integrated circuit card or tag)
// and their protypes are defined in the header file.
// Each command for a PICC consists of a PCD command. Therefore
// the function M500PcdCmd is very important for the understanding
// of the communication.
//
// The basic functionality is provided by the interrupt service
// routine (ISR), which closely works together with the function
// M500PcdCmd. All kinds of interrupts are serviced by the
// same ISR.
// inline structure in order to reset the communication channel between
// function and ISR
#define ResetInfo(info) \
info.cmd = 0; \
info.status = MI_OK;\
info.irqSource = 0; \
info.nBytesSent = 0; \
info.nBytesToSend = 0; \
info.nBytesReceived = 0; \
info.nBitsReceived = 0; \
info.collPos = 0;
// struct definition for a communication channel between function and ISR
typedef struct
{
unsigned char cmd; //!< command code
char status; // communication status
unsigned char nBytesSent; // how many bytes already sent
unsigned char nBytesToSend; // how many bytes to send
unsigned char nBytesReceived;// how many bytes received
unsigned short nBitsReceived; // how many bits received
unsigned char irqSource; // which interrupts have occured
unsigned char collPos; // at which position occured a
// collision
} MfCmdInfo;
// modul variables
extern unsigned char xdata *GpBase;
static unsigned char idata MFIFOLength = DEF_FIFO_LENGTH; // actual FIFO length
static unsigned char xdata MKeys[1][1]; // dummy, not used in this project
//static unsigned char xdata MKeys[16][12]; // storage for authentication keys
// in order to provide a calling
// compatible interface to old libraries
// Other reader modules keep several sets
// of keys in an E2PROM. In this case,
// these keys are stored in the uC and
// transfered to the reader module
// before authentication
// Infomation concerning data processing
// send buffer for general use
static volatile unsigned char xdata MSndBuffer[MAX_RF_BUF_SIZE];
// receive buffer for general use
static volatile unsigned char xdata MRcvBuffer[MAX_RF_BUF_SIZE];
// info struct for general use
static volatile MfCmdInfo MInfo;
// Interrupt service routine
// Variable in order to exchange data between function and ISR
static volatile MfCmdInfo *MpIsrInfo = 0;
// ISR send buffer
static volatile unsigned char *MpIsrOut = 0;
// ISR receive buffer
static volatile unsigned char *MpIsrIn = 0;
// storage of the last selected serial number including check byte.
//For multi level serial numbers, only the first 4 bytes are stored.
unsigned char MLastSelectedSnr[5];
static volatile unsigned char TYPE = TYPEA; // Default with type A
// Timer 2
#define OSC_FREQ 22118400L
//#define OSC_FREQ 12083000L
#define RCAP2_50us 65536L - OSC_FREQ/240417L
#define RCAP2_1ms 65536L - OSC_FREQ/12021L
#define RCAP2_10ms 65536L - OSC_FREQ/1200L
sfr16 RCAP2LH = 0xCA;
sfr16 T2LH = 0xCC;
bit T2IR = 0; // Timer2 timeout flag
unsigned int idata CountDown = 0; // Timeout counter with 50us resolution
sbit RC500RST = P3^3;
/*! \name ISO14443 Support Properties
* \ingroup ISO14443
* Some of the protocol functions of ISO14443 needs information about
* the capability of the reader device, which are provided by this
* constants.
*/
//@{
#define TCLFSDSNDMAX 7 ///< max. frame size send
#define TCLFSDRECMAX 7 ///< max. frame size rcv
#define TCLDSMAX 3 ///< max. baudrate divider PICC --> PCD
#define TCLDRMAX 3 ///< max. baudrate divider PCD --> PICC
#define TCLDSDFLT 0 ///< default baudrate divider PICC --> PCD
#define TCLDRDFLT 0 ///< default baudrate divider PCD --> PICC
//@}
///////////////////////////////////////////////////////////////////////////////
// Prototypes for local functions
///////////////////////////////////////////////////////////////////////////////
void delay_50us(unsigned int _50us);
void start_timeout(unsigned int _50us);
void stop_timeout(void);
// _____________________________________________________________________________
//
// FUNCTION: M500PcdSetTmo
// IN: tmoLength 0 ... 0.302 ms timeout period (FWI=0)
// 1 ... 0.604 ms timeout period (FWI=1)
// 2 ... 1.208 ms timeout period (FWI=2)
// 3 ... 2.416 ms timeout period (FWI=3)
// 4 ... 4.832 ms timeout period (FWI=4)
// 5 ... 9.664 ms timeout period (FWI=5)
// 6 ... 19.33 ms timeout period (FWI=6)
// 7 ... 38.66 ms timeout period (FWI=7)
// 8 ... 77.31 ms timeout period (FWI=8)
// 9 ... 154.6 ms timeout period (FWI=9)
// 10 ... 309.2 ms timeout period (FWI=10)
// 11 ... 618.5 ms timeout period (FWI=11)
// 12 ... 1.236 s timeout period (FWI=12)
// 13 ... 2.474 s timeout period (FWI=13)
// 14 ... 4.948 s timeout period (FWI=14)
// OUT: -
// RETURN:
// COMMENT: Set timeout length of the reader internal timer. The lenght is set
// according to the value of FWI defined in ISO14443-3
// FWT = (256*16/fc)*2exp(FWI)
//
void M500PcdSetTmo(unsigned char tmoLength);
// _____________________________________________________________________________
//
// FUNCTION: M500PcdCmd
// IN: cmd PCD_IDLE
// PCD_WRITEE2
// PCD_READE2
// PCD_LOADCONFIG
// PCD_LOADKEYE2
// PCD_AUTHENT1
// PCD_CALCCRC
// PCD_AUTHENT2
// PCD_RECEIVE
// PCD_LOADKEY
// PCD_TRANSMIT
// PCD_TRANSCEIVE
// PCD_RESETPHASE
// for a detailed description of the parameter values, please
// have a look on the header file of the reader register
// definitions.
// send byte stream of variable length, which should be send to
// the PICC, the length of stream has to be specified
// in the info - structure
// OUT: rcv byte stream of variable length, which was received
// from the PICC or PCD
// info communication and status structure
// RETURN:
// COMMENT: This function provides the central interface to the reader module.
// Depending on the "cmd"-value, all necessary interrupts are enabled
// and the communication is started. While the processing is done by
// the reader module, this function waits for its completion.
// It's notable, that the data in the "send byte stream" is written
// to the FIFO of the reader module by the ISR. Immediate after
// enabling the interrupts, the LoAlert interrupt is activated.
// The ISR writes the data to the FIFO. This function is not involved
// in writing or fetching data from FIFO, all work is done by the
// ISR.After command completion, the error status is evaluated and
// returned to the calling function.
//
char M500PcdCmd(unsigned char cmd,
volatile unsigned char* send,
volatile unsigned char* rcv,
volatile MfCmdInfo *info);
// _____________________________________________________________________________
//
// FUNCTION: SetBitMask
// IN: reg register address
// mask bit mask to set
// OUT: -
// RETURN:
// COMMENT: This function performs a read - modify - write sequence
// on the specified register. All bits with a 1 in the mask
// are set - all other bits keep their original value.
//
char SetBitMask(unsigned char reg,unsigned char mask);
// _____________________________________________________________________________
//
// FUNCTION: ClearBitMask
// IN: reg register address
// mask bit mask to clear
// OUT: -
// RETURN:
// COMMENT: This function performs a read - modify - write sequence
// on the specified register. All bits with a 1 in the mask
// are cleared - all other bits keep their original value.
//
char ClearBitMask(unsigned char reg,unsigned char mask);
// _____________________________________________________________________________
//
// FUNCTION: FlushFIFO
// IN: -
// OUT: -
// RETURN:
// COMMENT: All remaining date in the FIFO of the reader module is
// erased by this function. Before wrinting new data or
// starting a new command, all remaining data from former
// commands should be deleted. Please note, that in
// normal operation, never data should be left, that means
// that a call to this function should not be necessary.
//
void FlushFIFO(void);
// _____________________________________________________________________________
//
// FUNCTION: M500PiccAuthState
// IN: auth_mode
// snr
// sector
// OUT: -
// RETURN:
// COMMENT:
//
char M500PiccAuthState(unsigned char auth_mode,// PICC_AUTHENT1A, PICC_AUTHENT1B
unsigned char *snr, // 4 byte serial number
unsigned char sector); // 0 <= sector <= 15
// sector address for authentication
//////////////////////////////////////////////////////////////////////
// E X C H A N G E B Y T E S T R E A M
///////////////////////////////////////////////////////////////////////
char ExchangeByteStream(unsigned char Cmd,
unsigned char *send_data,
unsigned char send_bytelen,
unsigned char *rec_data,
unsigned char *rec_bytelen);
///////////////////////////////////////////////////////////////////////////////
// Interrupt Handler RC500
///////////////////////////////////////////////////////////////////////////////
void RC500ISR (void) interrupt 0 using 1 //Ext0 interrupt
{
static unsigned char idata irqBits;
static unsigned char idata irqMask;
static unsigned char idata nbytes;
static unsigned char idata cnt;
IE0 = 0; // Clear interrupt request flag
if (MpIsrInfo && MpIsrOut && MpIsrIn) // transfer pointers have to be set
// correctly
{
while( ReadRawIO(RegPrimaryStatus) & 0x08) // loop while IRQ pending
// Attention: IRQ bit is
// inverted when used with
// low activ IRQ
{
irqMask = ReadRawIO(RegInterruptEn); // read enabled interrupts
// read pending interrupts
irqBits = ReadRawIO(RegInterruptRq) & irqMask;
MpIsrInfo->irqSource |= irqBits; // save pending interrupts
//************ LoAlertIRQ ******************
if (irqBits & 0x01) // LoAlert
{
nbytes = MFIFOLength - ReadRawIO(RegFIFOLength);
// less bytes to send, than space in FIFO
if ((MpIsrInfo->nBytesToSend - MpIsrInfo->nBytesSent) <= nbytes)
{
nbytes = MpIsrInfo->nBytesToSend - MpIsrInfo->nBytesSent;
WriteRawIO(RegInterruptEn,0x01); // disable LoAlert IRQ
}
// write remaining data to the FIFO
for (cnt = 0;cnt < nbytes;cnt++)
{
WriteRawIO(RegFIFOData,MpIsrOut[MpIsrInfo->nBytesSent]);
MpIsrInfo->nBytesSent++;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -