?lang_form? ?lang_select? ?lang_submit? ?lang_endform?
{HEADER END}
{FILE START}

library

?curdirlinks? - Rev 32

?prevdifflink? - Blame - ?getfile?

/********************************************************************
 FileName:              SCpic18.c
 Dependencies:  See INCLUDES section
 Processor:             PIC18 Microcontrollers
 Hardware:              This demo is natively intended to be used on LPC & HPC Exp board.
                                This demo can be modified for use on other hardware platforms.
 Complier:      Microchip C18 (for PIC18)
 Company:               Microchip Technology, Inc.

 Software License Agreement:

 The software supplied herewith by Microchip Technology Incorporated
 (the “Company”) for its PIC® Microcontroller is intended and
 supplied to you, the Company’s customer, for use solely and
 exclusively on Microchip PIC Microcontroller products. The
 software is owned by the Company and/or its supplier, and is
 protected under applicable copyright laws. All rights are reserved.
 Any use in violation of the foregoing restrictions may subject the
 user to criminal sanctions under applicable laws, as well as to
 civil liability for the breach of the terms and conditions of this
 license.

 THIS SOFTWARE IS PROVIDED IN AN “AS IS” CONDITION. NO WARRANTIES,
 WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED
 TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE COMPANY SHALL NOT,
 IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR
 CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.

********************************************************************
 File Description:

 Change History:
  Rev   Description
  ----  -----------------------------------------
  1.0   Initial release
  1.01  Cleaned up unnecessary variables
********************************************************************/

#include        <p18cxxx.h>
#include        "stdio.h"
#include        "Smart Card/pps18.h"
#include        "string.h"
#include        "GenericTypeDefs.h"
#include        "Smart Card/SCpic18.h"
#include    "sc_config.h"

unsigned int gBitTimeDelay;
unsigned int bitTime;
unsigned int initialBaudReg;
unsigned long scReferenceClock;

unsigned long baudRate;

////////////////////////////////////////
// Generate delay in microsec resolution
// 0 - 2  us
// 1 - 3 us
// 10 - 12 us
// ...
////////////////////////////////////////
void WaitMicroSec( WORD microSec )
{
        while( microSec )
        {
                Nop();
                microSec--;
        }
}       

void WaitMilliSec( WORD ms )
{
        while( ms-- )
                WaitMicroSec( 800 );
}

///////////////////////////////////
// precalculate 1 bit time microsec used for Delay counter 


////////////////////////////////////////////////////
////////////////////////////////////////////////////
void SCdrv_SendTxData( BYTE data )
{
        BYTE txRetryCounter = 0;
        BOOL noError = TRUE;

        //calculate parity
        _asm
     swapf    data,0,0  //reducing byte to nibble
     xorwf    data,0,0
     addlw    0x41    // bit 1 becomes B0^B1 and bit 7 becomes B6^B7
     iorlw    0x7C    // for carry propagation from bit 1 to bit 7
     addlw    2       // Done! the parity bit is bit 7 of W
        _endasm
        
        TXSTAbits.TX9D = WREG >> 7; //copy calc parity bit to the transmitter
        
        TXREG = data;
        TXSTAbits.TXEN = 1;

        while( !TXSTAbits.TRMT ) //wait for Tx Complete
        {
                Nop();
        }       
        
        TXSTAbits.TXEN = 0;

        //turn off uart
        RCSTAbits.SPEN = 0;

        if( !SCdrv_GetRxPinData() )  // The Receiver did not like our data. it is pulling line low 
        {                                         // to indicate PE or FR errors
                noError = FALSE;
        
                RCSTAbits.SPEN = 1;
                                                
                //now retransmit the data
                if( txRetryCounter < 5 )
                {
                        txRetryCounter++;
                        SCdrv_SendTxData(data);
                }
        }
        
        if( noError ) //no error detected
                txRetryCounter = 0;

        RCSTAbits.SPEN = 1;
        
        if( RCSTA & 0x6 )       //FERR or OERR occured
        {
                RCSTAbits.CREN = 0; //clear error flags
                RCSTAbits.CREN = 1;
        }       

        while(1)        // remove rx data recvd from our Tx line
        {
                BYTE temp;              
                if( PIR1bits.RCIF )
                {
                        temp = RCREG;
                }       
                else
                        break;
        }       
}

/////////////////////////////////////////////
/////////////////////////////////////////////
BOOL SCdrv_GetRxData( BYTE* pDat, unsigned long nTrys )
{
        //wait for data byte
        while( !(PIR1 & 0x20) )
        {
                if( nTrys-- == 0 )
                        return FALSE;
        }
        
        //calculate parity
        _asm
     swapf    RCREG,0,0  //reducing byte to nibble
     xorwf    RCREG,0,0
     addlw    0x41    // bit 1 becomes B0^B1 and bit 7 becomes B6^B7
     iorlw    0x7C    // for carry propagation from bit 1 to bit 7
     addlw    2       // Done! the parity bit is bit 7 of W
     RLNCF    WREG,0,0          //rotate left W reg
     xorwf    RCSTA,0,0
        _endasm

        if( WREG & 1 )  //Parity Error detected
        {
                RCSTAbits.SPEN = 0;
                SCdrv_TxPin_Direction(0);  //pull it low to tell the card that there was error receiving data
                
                WaitMicroSec(gBitTimeDelay );
                                
                SCdrv_TxPin_Direction(1); //release line. Card should retransmit now.
                                
                RCSTAbits.SPEN = 1;
                return SCdrv_GetRxData( pDat, nTrys );  //Read the data from retransmission 
        }

        *pDat = RCREG;
        return TRUE;
}


///////////////////////////////////////////////////
//////////////////////////////////////////////////
void SCdrv_SetBRG( BYTE speedCode )
{
        float factorD = 1;
        unsigned int factorF = 372;
        BYTE tempCode;
        unsigned int baudReg;

        tempCode = speedCode & 0x0F;
        
        // Calculate Factor 'D' from TA1 value
        switch(tempCode)
        {
                case 0x00:
                case 0x07:
                case 0x01:
                                        break;

                case 0x02:
                                        factorD = 2;
                                        break;

                case 0x03:
                                        factorD = 4;
                                        break;

                case 0x04:
                                        factorD = 8;
                                        break;

                case 0x05:
                                        factorD = 16;
                                        break;

                case 0x06:
                                        factorD = 32;
                                        break;

                case 0x08:
                                        factorD = 12;
                                        break;

                case 0x09:
                                        factorD = 20;
                                        break;

                case 0x0A:
                                        factorD = 0.5;
                                        break;

                case 0x0B:
                                        factorD = 0.25;
                                        break;

                case 0x0C:
                                        factorD = 0.125;
                                        break;

                case 0x0D:
                                        factorD = 0.0625;
                                        break;

                case 0x0E:
                                        factorD = 0.03125;
                                        break;

                case 0x0F:
                                        factorD = 0.015625;
                                        break;
        }

        // If you are not using internal clock in Smart Card & are 
        // using external clock to drive Smart Card than calculate 
        // factor 'F' from TA1 value
        #ifdef ENABLE_SC_EXTERNAL_CLOCK

                tempCode = (speedCode & 0xF0) >> 4;
                
        // Calculate Factor 'F' from TA1 value
                switch(tempCode)
                {
                        case 0x00:
                        case 0x07:
                        case 0x08:
                        case 0x0E:
                        case 0x0F:
                                                break;
        
                        case 0x01:
                                                factorF = 372;
                                                break;
        
                        case 0x02:
                                                factorF = 558;
                                                break;

                        case 0x03:
                                                factorF = 744;
                                                break;
        
                        case 0x04:
                                                factorF = 1116;
                                                break;
        
                        case 0x05:
                                                factorF = 1488;
                                                break;
        
                        case 0x06:
                                                factorF = 1860;
                                                break;
        
                        case 0x09:
                                                factorF = 512;
                                                break;
        
                        case 0x0A:
                                                factorF = 768;
                                                break;
        
                        case 0x0B:
                                                factorF = 1024;
                                                break;
        
                        case 0x0C:
                                                factorF = 1536;
                                                break;
        
                        case 0x0D:
                                                factorF = 2048;
                                                break;  
                }

                if(tempCode == 0x00)    // If internal clock used in Smart Card
                {
                        baudReg = (unsigned int)(FCY/(9600 * factorD) - 1);
                        SPBRG = (unsigned char)baudReg;
                        SPBRGH = (unsigned char)(baudReg >> 8);
                }
                else    // If externa; clock used to drive Smart Card
                {
                        baudRate = (scReferenceClock * factorD)/factorF;
                        baudReg = (unsigned int)((FCY/baudRate) - 1);
                        SPBRG = (unsigned char)baudReg;
                        SPBRGH = (unsigned char)(baudReg >> 8);
                }

        #else   // If internal clock used in Smart Card

                baudReg = (unsigned char)(FCY/(9600 * factorD) - 1);
                SPBRG = (unsigned char)baudReg;
                SPBRGH = (unsigned char)(baudReg >> 8);

        #endif
        
        //recalculate bit time
        gBitTimeDelay = baudReg;
        gBitTimeDelay *= bitTime;       //micro sec for 1 bit @ 9.6kbps
        gBitTimeDelay /= initialBaudReg;                
}       

///////////////////////////////////////////////////
//////////////////////////////////////////////////
void SCdrv_CloseUART(void)
{
        SCdrv_DisableClock();   //turn off Clock
        RCSTAbits.SPEN = 0;             //turn off UART
        RCSTAbits.CREN = 0;
}


///////////////////////////////////////////////////
//////////////////////////////////////////////////
void SCdrv_InitUART(void)
{
        unsigned int power2Value = 1;
        BYTE power2temp;

        SCdrv_PowerPin_Direction(0);    //set RB0 as output to power the Smart Card
        SCdrv_ResetPin_Direction(0);    //set RB4 as output for Smart Card Reset Pin
        SCdrv_CardPresent_Direction(1);  //RB3 Input Card Present
        SCdrv_SimPresent_Direction(1);   //RB1 Input Card Present
        
        SCdrv_SetTxPinData(0);
        SCdrv_TxPin_Direction(1);       // TX1 also act as gpio to pull the line low
        SCdrv_RxPin_Direction(1);       
        
        SCdrv_EnableCardSimPresentPinPullUp();  //enable pull up, active low

        SCdrv_SetSwitchCardPower(0);    //Turn off power to smart card
        SCdrv_SetSwitchCardReset(0); //keep card in reset state         

        // Set the clock value that you want to trigger the smart card.
        // Dont enable the clock,only set it.
        Scdrv_ClockSet();

        power2temp = REF_CLOCK_POWER2_VALUE;

        while(power2temp--)
        {
                power2Value = power2Value * (BYTE)2;
        }

        scReferenceClock = REF_CLOCK_CIRCUIT_INPUT_CLK/(power2Value + REF_CLOCK_DIVISOR_VALUE);

        baudRate = scReferenceClock/(unsigned int)372;

        initialBaudReg = ((FCY/baudRate) - 1);
        SPBRG = (unsigned char)initialBaudReg;
        SPBRGH = (unsigned char)(initialBaudReg >> 8);
        bitTime = (1000000UL)/baudRate + 1;

        gBitTimeDelay = initialBaudReg;
        gBitTimeDelay *= bitTime;       //micro sec for 9.6k baud
        gBitTimeDelay /= initialBaudReg;  

        TXSTAbits.TX9  = 1; //select 9 bit transmission
        TXSTAbits.SYNC = 0; //Async mode        
        TXSTAbits.BRGH = 1;
        BAUDCONbits.BRG16 = 1;

        RCSTAbits.CREN = 1;
        RCSTAbits.RX9  = 1;
}


{FILE END}
{FOOTER START}

Powered by WebSVN v2.8.3