📄 mfrc500uc.c
字号:
///////////////////////////////////////////////////////////////////////////////
// Copyright (c), Philips Semiconductors Gratkorn
//
// (C)PHILIPS Electronics N.V.2000
// All rights are reserved.
// 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.
///////////////////////////////////////////////////////////////////////////////
#include <string.h>
#include <stdio.h>
#include <RICReg.h>
#include <MfRc500.h>
#include <PcdShared.h>
#include <uCInit.h>
#include <RcCommunication.h>
#include <PcdUtils.h>
#include <MfErrNo.h>
/*! \file MfRc500uC.c
*
* Projekt: MF EV X00 Firmware
*
* $Workfile:: MfRc500uC.c $
* $Modtime:: 30.03.01 9:46 $
* $Author:: Hb $
* $Revision:: 31 $
*
*
* This library modul is written for a C166 microcontroller derivative.
* 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 RcComunication.h (Reader core communication).
* In our case the reader module is
* connected via memory mapped io at base address 0x100000.
* 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
* (Port: P1 Pin: 9).
* 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 3 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.
* <ol>
* <li> internal functions, which have no prototypes in a header
* file. This kind of functions are not intended to be used
* outside of this file
* <li> commands, which are intended for the reader module itself
* <li> 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.
* </ol>
* 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.
* Certainly, each command for a PICC consists of an instruction to the PCD.
* Therefore
* the function PcdSingleResponseCmd is very important for the understanding
* of the communication.
*
* The basic functionality is provided by the interrupt service
* routine (SingleResponseCmd), which closely works together with the function
* PcdSingleResponseCmd. All kinds of interrupts are serviced by the
* same ISR.
*/
///////////////////////////////////////////////////////////////////////////////
// M O D U L V A R I A B L E S
///////////////////////////////////////////////////////////////////////////////
/*!
* \ingroup mfcompatible
* 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];
volatile unsigned char *MSndBuffer = 0; ///< pointer to the transmit buffer
volatile unsigned char *MRcvBuffer = 0; ///< pointer to the receive buffer
/*!
* In order to exchange some values between the ISR and the calling function,
* a struct is provided.
*/
volatile MfCmdInfo MInfo;
/*! \name ISO14443 Support Properties
* \ingroup ISO14443
* Some of the protokoll functions of ISO14443 needs information about
* the capability of the reader device, which are provided by this
* constants.
*/
//@{
#define TCLFSDSNDMAX 8 ///< max. frame size send
#define TCLFSDRECMAX 8 ///< 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
///////////////////////////////////////////////////////////////////////////////
/// Internal Authentication State Switch
/*!
* \ingroup internal
* \param auth_mode (<em>IN</em>)
* <ul> selects master key A or master key B
* <li> PICC_AUTHENT1A
* <li> PICC_AUTHENT1B
* </ul>
* \param *snr (<em>IN</em>)
* 4 byte serial number of the card, which should be
* authenticated
* \param sector (<em>IN</em>) Range [0..15]
* specifies the key RAM address
* from which the keys should be taken
* \return <ul>
* <li> MI_OK
* <li> CCE
* <li> MI_BITCOUNTERR wrong number of bits received
* <li> MI_AUTHERR wrong keys for selected card
* <li> MI_KEYERR error while loading keys
* </ul>
*
* Internal authentication state function.
*/
char Mf500PiccAuthState(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
///////////////////////////////////////////////////////////////////////
// M I F A R E M O D U L E C O N F I G U R A T I O N
///////////////////////////////////////////////////////////////////////
char Mf500PcdConfig(void)
{
char status = MI_RESETERR;
unsigned short RstLoopCnt = 0;
unsigned short CmdWaitCnt = 0;
// global initialisation
MSndBuffer = RicRxTxBuffer; // initialise send buffer
MRcvBuffer = RicRxTxBuffer; // initialise receive buffer
status = PcdReset();
if (status == MI_OK)
{
// test clock Q calibration - value in the range of 0x46 expected
WriteRC(RegClockQControl,0x0);
WriteRC(RegClockQControl,0x40);
SleepUs(24); // wait approximately 100 us - calibration in progress
ClearBitMask(RegClockQControl,0x40); // clear bit ClkQCalib for
// further calibration
// The following values for RegBitPhase and
// RegRxThreshold represents an optimal
// value for our demo package. For user
// implementation some changes could be
// necessary
// initialize bit phase
WriteRC(RegBitPhase,0xAD);
// initialize minlevel
WriteRC(RegRxThreshold,0xFF);
// disable auto power down
WriteRC(RegRxControl2,01);
// Depending on the processing speed of the
// operation environment, the waterlevel
// can be adapted. (not very critical for
// mifare applications)
// initialize waterlevel to value 4
WriteRC(RegFIFOLevel,0x1A); // initialize to 26d
//Timer Konfiguration
WriteRC(RegTimerControl,0x02); // TStopRxEnd=0,TStopRxBeg=0,
// TStartTxEnd=1,TStartTxBeg=0
// timer must be stopped manually
WriteRC(RegIRqPinConfig,0x3); // interrupt active low enable
PcdRfReset(1); // Rf - reset and enable output driver
}
return status;
}
///////////////////////////////////////////////////////////////////////
// M I F A R E R E M O T E A N T E N N A
// Configuration of slave module
///////////////////////////////////////////////////////////////////////
char Mf500ActiveAntennaSlaveConfig(void)
{
char status = MI_OK;
FlushFIFO(); // empty FIFO
ResetInfo(MInfo);
MSndBuffer[0] = 0x10; // addr low byte
MSndBuffer[1] = 0x00; // addr high byte
MSndBuffer[2] = 0x00; // Page
MSndBuffer[3] = 0x7B; // RegTxControl modsource 11,InvTx2,Tx2RFEn,TX1RFEn
MSndBuffer[4] = 0x3F; // RegCwConductance
MSndBuffer[5] = 0x3F; // RFU13
MSndBuffer[6] = 0x19; // RFU14
MSndBuffer[7] = 0x13; // RegModWidth
MSndBuffer[8] = 0x00; // RFU16
MSndBuffer[9] = 0x00; // RFU17
MSndBuffer[10] = 0x00; // Page
MSndBuffer[11] = 0x73; // RegRxControl1
MSndBuffer[12] = 0x08; // RegDecoderControl
MSndBuffer[13] = 0x6c; // RegBitPhase
MSndBuffer[14] = 0xFF; // RegRxThreshold
MSndBuffer[15] = 0x00; // RFU1D
MSndBuffer[16] = 0x00; // RegRxControl2
MSndBuffer[17] = 0x00; // RegClockQControl
MSndBuffer[18] = 0x00; // Page
MSndBuffer[19] = 0x06; // RegRxWait
MSndBuffer[20] = 0x03; // RegChannelRedundancy
MSndBuffer[21] = 0x63; // RegCRCPresetLSB
MSndBuffer[22] = 0x63; // RegCRCPresetMSB
MSndBuffer[23] = 0x0; // RFU25
MSndBuffer[24] = 0x04; // RegMfOutSelect enable mfout = manchester HT
MSndBuffer[25] = 0x00; // RFU27
// PAGE 5 FIFO, Timer and IRQ-Pin Configuration
MSndBuffer[26] = 0x00; // Page
MSndBuffer[27] = 0x08; // RegFIFOLevel
MSndBuffer[28] = 0x07; // RegTimerClock
MSndBuffer[29] = 0x06; // RegTimerControl
MSndBuffer[30] = 0x0A; // RegTimerReload
MSndBuffer[31] = 0x02; // RegIRqPinConfig
MSndBuffer[32] = 0x00; // RFU
MSndBuffer[33] = 0x00; // RFU
MInfo.nBytesToSend = 34;
status = PcdSingleResponseCmd(PCD_WRITEE2,
MSndBuffer,
MRcvBuffer,
&MInfo); // write e2
return status;
}
///////////////////////////////////////////////////////////////////////
// M I F A R E R E M O T E A N T E N N A
// Configuration of master module
///////////////////////////////////////////////////////////////////////
char Mf500ActiveAntennaMasterConfig(void)
{
char status = MI_OK;
WriteRC(RegRxControl2,0x42);
WriteRC(RegTxControl,0x10);
WriteRC(RegBitPhase,0x11);
return status;
}
///////////////////////////////////////////////////////////////////////
// M I F A R E R E Q U E S T
///////////////////////////////////////////////////////////////////////
char Mf500PiccRequest(unsigned char req_code, // request code ALL = 0x52
// or IDLE = 0x26
unsigned char *atq) // answer to request
{
return Mf500PiccCommonRequest(req_code,atq);
}
///////////////////////////////////////////////////////////////////////
// M I F A R E C O M M O N R E Q U E S T
///////////////////////////////////////////////////////////////////////
char Mf500PiccCommonRequest(unsigned char req_code,
unsigned char *atq)
{
char status = MI_OK;
//************* initialize ******************************
if ((status = Mf500PcdSetDefaultAttrib()) == MI_OK)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -