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

library

?curdirlinks? - Rev 32

?prevdifflink? - Blame - ?getfile?

/********************************************************************
 FileName:              SCpic24.c
 Dependencies:  See INCLUDES section
 Processor:             PIC24 Microcontrollers
 Hardware:              This demo is natively intended to be used on Exp 16 board.
                                This demo can be modified for use on other hardware platforms.
 Complier:      Microchip C30 (for PIC24)
 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        "string.h"
#include        "GenericTypeDefs.h"
#include        "sc_config.h"
#include    "./Smart Card/SCpic24.h"
#if defined(__PIC24F__)
        #include        "./Smart Card/pps-macro.h"
#endif

unsigned long baudRate;
unsigned long scReferenceClock; // Smart Card Reference Clock

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

        U1STAbits.UTXEN = 1;
        U1TXREG = data;         

        while( !U1STAbits.TRMT )
        {
                Nop();
                Nop();
        }
        
        U1STAbits.UTXEN = 0;

        U1MODEbits.UARTEN = 0;  // Disable UART Module

        WaitMicroSec( 1 );
        
        if( !SCdrv_GetRxPinData() )  // The Receiver did not like our data. it is pulling line low 
        {                                         // to indicate PE or FR errors
                noError = FALSE;

//              WaitMicroSec((U1BRG * 170)/371);  //wait two etu before repeating
                
                U1MODEbits.UARTEN = 1;
                                                
                //now retransmit the data
                if( txRetryCounter < 5 )
                {
                        txRetryCounter++;
                        SCdrv_SendTxData(data);
                }
        }
        else
        {       
//              WaitMicroSec((U1BRG * 140)/371);  //wait 1.5 etu
        }

        if( noError ) //no error detected
                txRetryCounter = 0;

        U1MODEbits.UARTEN = 1;  // Enable UART Module
        
        U1STAbits.OERR = 0;     //clear any overflow error that we caused
        
        while(1)        // remove rx data recvd from our Tx line
        {
                WORD temp;              
                if( U1STAbits.URXDA )
                        temp = U1RXREG;
                else
                        break;
        }       
}

/////////////////////////////////////////////
/////////////////////////////////////////////
BOOL SCdrv_GetRxData( BYTE* pDat, unsigned long nTrys )
{
        //wait for data byte
        while( !U1STAbits.URXDA && nTrys-- );
        
        if( !U1STAbits.URXDA )
                return FALSE;
        
        if( U1STAbits.PERR )    //Parity Error detected
        {
                SCdrv_TxPin_Direction(0);  //pull it low to tell the card that there was error receiving data
                U1MODEbits.RXINV = 1;  //do not recognize this low state as a valid start bit
                                        
                //Read the data from UART to clear the error flag
                *pDat = U1RXREG;                
        
                WaitMicroSec((U1BRG * 116)/371);  //for 9600 baud, 116 us. for 250kbps, 5us

                SCdrv_TxPin_Direction(1); //release RD10. Card should retransmit now.

                U1MODEbits.RXINV = 0;

                return SCdrv_GetRxData(pDat, 10000);    //Read the data from retransmission
        }
        else
        {
                //Read the data from UART
                *pDat = U1RXREG;
        }

        return TRUE;
}

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

        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
                {
                        U1BRG = (unsigned int)((unsigned long)((unsigned long)FCY/(4 * (unsigned long)9600 * factorD)) - 1);   //Internal clk used in card
                }
                else    // If externa; clock used to drive Smart Card
                {
                        baudRate = (unsigned long long)((unsigned long long)((unsigned long long)scReferenceClock * factorD)/factorF);

                        U1BRG = (unsigned int)((unsigned long)((unsigned long)FCY/(4 * baudRate)) - 1);   //10752bps with 4Mhz clk to card
                }

        #else   // If internal clock used in Smart Card

                U1BRG = (unsigned int)((unsigned long)((unsigned long)FCY/(4 * (unsigned long)9600 * factorD)) - 1);   //Internal clk used in card

        #endif
}       
        
///////////////////////////////////////////////////
//////////////////////////////////////////////////
void SCdrv_CloseUART(void)
{
        SCdrv_DisableClock();           // turn off Clock
        U1MODEbits.UARTEN = 0;  // Turn off UART
        U1STAbits.OERR = 0;;

        // Disable Pull-ups at Tx & Rx pins
        SCdrv_DisableTxPinPullUp();
        SCdrv_DisableRxPinPullUp();     
}

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

        #ifdef ENABLE_SC_POWER_THROUGH_PORT_PIN
                SCdrv_PowerPin_Direction(0);    //set RG8 as output to power the Smart Card
        #endif
        
        SCdrv_ResetPin_Direction(0);    //set RD0 as output for Smart Card Reset Pin
        SCdrv_CardPresent_Direction(1);   //RD3 Input Card Present - SmartCard Conn Active Hi
        SCdrv_SimPresent_Direction(1);   //RG12 Input Card Present - SimCard Conn Active Low
        
        SCdrv_SetTxPinData(0);
        SCdrv_TxPin_Direction(1);       // use as gpio to pull the line low

        //Turn on the pull-up on both RX and TX line for faster transitions.
        SCdrv_EnableTxPinPullUp();
        SCdrv_EnableRxPinPullUp();

        // Enable Pull-ups for card present/sim present pins
        SCdrv_EnableCardPresentPinPullUp();
        SCdrv_EnableSimPresentPinPullUp();

        #ifdef ENABLE_SC_POWER_THROUGH_PORT_PIN
                SCdrv_SetSwitchCardPower(0);    //Turn off power to smart card
        #endif

        SCdrv_SetSwitchCardReset(0); //keep card in reset state         

        MapUART1RxPin();                // Map UART1 Rx pin
        MapUART1TxPin();                // Map UART1 Tx pin

        Scdrv_ClockSet();

        // Initial Baud Rate of Smart Card for external Clock
        #ifdef ENABLE_SC_EXTERNAL_CLOCK

                power2temp = REF_CLOCK_POWER2_VALUE;

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

                scReferenceClock = REF_CLOCK_CIRCUIT_INPUT_CLK/(power2Value + REF_CLOCK_DIVISOR_VALUE);
        
                baudRate = scReferenceClock/372;

                U1BRG = (unsigned int)((unsigned long)((unsigned long)FCY/(4 * baudRate)) - 1);   //10752bps with 4Mhz clk to card
        
        #else
        
                U1BRG = (unsigned int)((unsigned long)((unsigned long)FCY/(4 * (unsigned int)9600)) - 1);   //Internal clk used in card

        #endif

        U1MODEbits.PDSEL        = 1;    //8bits + even parity
        U1MODEbits.STSEL        = 0;    //1 stop bit
        U1MODEbits.BRGH         = 1;
}





{FILE END}
{FOOTER START}

Powered by WebSVN v2.8.3