⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 armspi.c

📁 用ARM的LPC2200来 SPI通信方式下读卡器驱动程序 其读卡器为FM172
💻 C
📖 第 1 页 / 共 4 页
字号:
/*************************************************************************
                        SPI通信方式下读卡器驱动程序

************************************************************************/
#include "config.h"
///////////////////////////////////////////////////////////////////////////////
//                           **底层函数**
///////////////////////////////////////////////////////////////////////////////
#define     FM1702_NSS      1<<24             //  P0.24 为片选线
#define     FM1702_RESET    1<<23
#define     BEEPCON         1<<7
///////////////////////////////////////////////////////////////////////////////
//                           **基本的写函数**
///////////////////////////////////////////////////////////////////////////////
void WriteIO(uint8 Address, uint8 value)
{   
    uint8   a;
    OS_ENTER_CRITICAL();
    IO0CLR=FM1702_NSS;	       
    S1PDR=(Address&0x3f)<<1;    
    while(0==(S1PSR&0x80));     
    a=S1PDR;                   
    S1PDR=value;               
    while(0==(S1PSR&0x80));
    a=S1PDR;
    IO0SET=FM1702_NSS;	      
    OS_EXIT_CRITICAL();
}
void WriteIOint(uint8 Address, uint8 value)
{   
    uint8   a;
  //  OS_ENTER_CRITICAL();
    IO0CLR=FM1702_NSS;	       
    S1PDR=(Address&0x3f)<<1;    
    while(0==(S1PSR&0x80));    
    a=S1PDR;                   
    S1PDR=value;                
    while(0==(S1PSR&0x80));
    a=S1PDR;
    IO0SET=FM1702_NSS;	       
   // OS_EXIT_CRITICAL();
}

///////////////////////////////////////////////////////////////////////////////
//                          **基本的读函数**
///////////////////////////////////////////////////////////////////////////////
uint8 ReadIO(uint8 Address)
{
   uint8 a;
    OS_ENTER_CRITICAL();
   IO0CLR=FM1702_NSS;	               // 选通
   S1PDR=((Address&0x3f)<<1)|0x80;    
   while(0==(S1PSR&0x80));            
   a=S1PDR;                        
   S1PDR=0;
   while(0==(S1PSR&0x80));          
   a=S1PDR; 
   IO0SET=FM1702_NSS;	           
   OS_EXIT_CRITICAL();
   return a;                               
} 
uint8 ReadIOint(uint8 Address)
{
   uint8 a;
  // OS_ENTER_CRITICAL();
   IO0CLR=FM1702_NSS;	              
   S1PDR=((Address&0x3f)<<1)|0x80;    
   while(0==(S1PSR&0x80));           
   a=S1PDR;                          
   S1PDR=0;
   while(0==(S1PSR&0x80));          
   a=S1PDR; 
   IO0SET=FM1702_NSS;	          
  // OS_EXIT_CRITICAL();
   return a;                               
}

///////////////memcpy1函数/////////////////////////////////////////
void memcpy1(uint8 *des,uint8 *source,uint8 len)
{
    uint8 i;
    for(i=0;i<len;i++)
        {*des=*source;
        des++;
        source++;
        }
}
//////////////初始化SPI接口以及1702引脚函数///////////////////////
void  FM1702SpiInit(void)
{  
     T1PR=0;           //不分频
     PINSEL0 =(PINSEL0&~0x0000C000);      
     IO0DIR|= BEEPCON;                 
     IO0SET=BEEPCON;
    PINSEL1 = ((PINSEL1 & ~0x3C3FF) | 0x2A9);
     EXTMODE|=0x01;
     EXTPOLAR&=0x0E;   
    IO0DIR|=0x01800000;              
    IO0SET=FM1702_NSS;           
    S1PCCR = 0x08;		           
    S1PCR  = (0 << 3) |				
 		     (0 << 4) |				
 		     (1 << 5) |				
 		     (0 << 6) |				
 		     (0 << 7);				
 
}


/********************************************************************************
*********************************************************************************
********************************************************************************/

//                M O D U L E   D E F I N I T I O N
////////////////////////////////////////////////////////////////////////////////

//为了复位 函数和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 
         {
            uint8  cmd;           
            int8   status;        
            uint8  nBytesSent;      
            uint8  nBytesToSend;   
            uint8  nBytesReceived;  
            uint16 nBitsReceived;  
            uint8  irqSource;      
            uint8  collPos;        
         } MfCmdInfo;

// ----------读卡模块使用的变量------------------

static  volatile uint8  MFIFOLength = DEF_FIFO_LENGTH; // 实际的FIFO的长度

//定义50us延时
#define DELAY50    Fpclk/20000
   
static   volatile uint8  MSndBuffer[SND_BUF_LEN];// 发送缓冲区
static   volatile uint8  MRcvBuffer[RCV_BUF_LEN]; // 接收缓冲区
static   volatile MfCmdInfo     MInfo;                 

//--------------------中断服务程序------------------------------
static   volatile MfCmdInfo  *MpIsrInfo = 0;
static   volatile uint8 *MpIsrOut  = 0; 
static   volatile uint8 *MpIsrIn   = 0;  

uint8 MLastSelectedSnr[5];

uint8	volatile Timer1out_flag	= 0;	    // 定时器1溢出标志位
///////////////////////////////////////////////////////////////////////////////
//             Prototypes for local functions 
///////////////////////////////////////////////////////////////////////////////

void delay_50us(uint32 _50us);
void start_timeout(uint32 _50us);
void stop_timeout(void);

// _____________________________________________________________________________
//  FUNCTION: FM1702PcdSetTmo
void FM1702PcdSetTmo(uint8 tmoLength);

// _____________________________________________________________________________
//
//  FUNCTION: FM1702PcdCmd
int8 FM1702PcdCmd(uint8 cmd, volatile uint8* send, volatile uint8* rcv, volatile MfCmdInfo *info);
               
// _____________________________________________________________________________
//
//  FUNCTION: SetBitMask
int8 SetBitMask(uint8 reg,uint8 mask);

// _____________________________________________________________________________
//  FUNCTION: ClearBitMask
int8 ClearBitMask(uint8 reg,uint8 mask);

// _____________________________________________________________________________
void FlushFIFO(void);

// _____________________________________________________________________________
//  FUNCTION: FM1702PiccAuthState
int8 FM1702PiccAuthState(uint8 auth_mode,uint8 *snr,uint8 block); 
                         
                       

///////////////////////////////////////////////////////////////////////////////
//                  FM1702中断服务程序
///////////////////////////////////////////////////////////////////////////////
void  EXINT0_Exception (void)
{
   static uint8  irqBits;
   static uint8  irqMask;            
   static uint8  nbytes;
   static uint8  cnt,a;
   
   if (MpIsrInfo && MpIsrOut && MpIsrIn)// transfer pointers have to be set correctly
                                         {OS_ENTER_CRITICAL();
      while( ReadIOint(RegPrimaryStatus) & 0x08)// loop while IRQ pending--IRQ
                           // Attention: IRQ bit is inverted when used with low activ IRQ
                                              
      {
         irqMask = ReadIOint(RegInterruptEn); // read enabled interrupts
         // read pending interrupts
         irqBits = ReadIOint(RegInterruptRq) & irqMask;
         MpIsrInfo->irqSource |= irqBits; // save pending interrupts
         //************ LoAlertIRQ ******************
         if (irqBits & 0x01)    //LoAlert
         {  
            nbytes = MFIFOLength - ReadIOint(RegFIFOLength);
            // less bytes to send, than space in FIFO
            if ((MpIsrInfo->nBytesToSend - MpIsrInfo->nBytesSent) <= nbytes)
            {
               nbytes = MpIsrInfo->nBytesToSend - MpIsrInfo->nBytesSent;
               WriteIOint(RegInterruptEn,0x01); // LoAlert IRQ
              
             }
            
            IO0CLR=FM1702_NSS;	// Enable the /CS for RC500选通
            S1PDR=((RegFIFOData&0x3f)<<1);  
            while((S1PSR&0x80)==0);    
            a=S1PDR;                       
            for ( cnt = 0;cnt < nbytes;cnt++)
                {
                   S1PDR=MpIsrOut[MpIsrInfo->nBytesSent];
                   MpIsrInfo->nBytesSent++;
                   while((S1PSR&0x80)==0);    
                   a=S1PDR;                     
                }
            IO0SET=FM1702_NSS;	// disable the /CS for RC500
            WriteIOint(RegInterruptRq,0x01);  //  LoAlertIRQ bit
            
            
         }
         //************* TxIRQ Handling **************
         if (irqBits & 0x10)       
         {
            WriteIOint(RegInterruptRq,0x10);    // TxIRQ bit 
            WriteIOint(RegInterruptEn,0x82);    // enable HiAlert Irq for response
                                        
            if (((MpIsrInfo->cmd & 0xF0) == 0x90)&& (MpIsrInfo->nBitsReceived == 7))
            	// if cmd is anticollision switch off parity generation
               WriteIOint(RegChannelRedundancy,0x02);	// RXCRC and TXCRC disable, parity disable
         }

         //************* HiAlertIRQ or RxIRQ Handling ******************
         if (irqBits & 0x0E) 
         {
            // read some bytes ( length of FIFO queue)  into the receive buffer            
            nbytes = ReadIOint(RegFIFOLength);
            // read date from the FIFO and store them in the receive buffer
            for ( cnt = 0; cnt < nbytes; cnt++)               
            {
               MpIsrIn[MpIsrInfo->nBytesReceived] = ReadIOint(RegFIFOData);
               MpIsrInfo->nBytesReceived++;
            }
            WriteIOint(RegInterruptRq,0x0A & irqBits); 
                            // reset IRQ bit - idle irq will be deleted in a seperate section
         }   
   
         //************** IdleIRQ Handling ***********
         if (irqBits & 0x04)   
         {	
            WriteIOint(RegInterruptEn,0x20); 
            WriteIOint(RegInterruptRq,0x20); 
            irqBits &= ~0x20;   // clear Timer IRQ in local var
            MpIsrInfo->irqSource &= ~0x20; // clear Timer IRQ in info var
                                        // when idle received, then cancel timeout
                                     
            WriteIOint(RegInterruptRq,0x04);  // reset IRQ bit
            // status should still be MI_OK
            // no error - only used for wake up
         }
       
         //************* TimerIRQ Handling ***********
         if (irqBits & 0x20)       // timer IRQ
         {
            WriteIOint(RegInterruptRq,0x20); // reset IRQ bit
            MpIsrInfo->status = MI_NOTAGERR; // timeout erro----保存错误原因
                                             // otherwise ignore the interrupt
         }
         
      }
      OS_EXIT_CRITICAL();
   }
   EXTINT|=1; 	
   VICVectAddr=0;
   
}

///////////////////////////////////////////////////////////////////////
//         S e t   T i m e o u t   L E N G T H
//设置FM1702内部定时器的定时时间
///////////////////////////////////////////////////////////////////////
void FM1702PcdSetTmo(uint8 tmoLength)
{
   switch(tmoLength)
   {  // timer clock frequency 13,56 MHz
        //TimerClock
        //TimerReload
      case 1:                       // short timeout (1,0 ms)
         WriteIO(RegTimerClock,0x07); // TAutoRestart=0,TPrescale=128-
         WriteIO(RegTimerReload,0x6a);// TReloadVal = 'h6a =106(dec) 
         break;
      case 2:                       // medium timeout (1,5 ms)
         WriteIO(RegTimerClock,0x07); // TAutoRestart=0,TPrescale=128
         WriteIO(RegTimerReload,0xa0);// TReloadVal = 'ha0 =160(dec) 
         break;
      case 3:                       // medium timeout (6 ms)
         WriteIO(RegTimerClock,0x09); // TAutoRestart=0,TPrescale=4*128
         WriteIO(RegTimerReload,0xa0);// TReloadVal = 'ha0 =160(dec) 
         break;
      case 4:                       // long timeout (9.6 ms)                      
         WriteIO(RegTimerClock,0x09); // TAutoRestart=0,TPrescale=4*128           
         WriteIO(RegTimerReload,0xff);// TReloadVal = 'hff =255(dec) 
         break;
      case 5:                       // long timeout (38.5 ms)
         WriteIO(RegTimerClock,0x0b); // TAutoRestart=0,TPrescale=16*128
         WriteIO(RegTimerReload,0xff);// TReloadVal = 'hff =255(dec) 
         break;
      case 6:                       // long timeout (154 ms)
         WriteIO(RegTimerClock,0x0d); // TAutoRestart=0,TPrescale=64*128
         WriteIO(RegTimerReload,0xff);// TReloadVal = 'hff =255(dec) 
         break;
      case 7:                       // long timeout (616.2 ms)
         WriteIO(RegTimerClock,0x0f); // TAutoRestart=0,TPrescale=256*128
         WriteIO(RegTimerReload,0xff);// TReloadVal = 'hff =255(dec) 
         break;
      default:                       // 
         WriteIO(RegTimerClock,0x07); // TAutoRestart=0,TPrescale=128
         WriteIO(RegTimerReload,tmoLength);// TReloadVal = 'h6a =tmoLength(dec) 
         break;
   }     

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -