/*********************************************************************
* Function:         void InitSymbolTimer()
*
* PreCondition:     none
*
* Input:		    none
*
* Output:		    none
*
* Side Effects:	    TMR0 for PIC18 is configured for calculating
*                   the correct symbol times.  TMR2/3 for PIC24/dsPIC
*                   is configured for calculating the correct symbol
*                   times
*
* Overview:		    This function will configure the UART for use at 
*                   in 8 bits, 1 stop, no flowcontrol mode
*
* Note:			    The timer interrupt is enabled causing the timer
*                   roll over calculations.  Interrupts are required
*                   to be enabled in order to extend the timer to
*                   4 bytes in PIC18.  PIC24/dsPIC version do not 
*                   enable or require interrupts
********************************************************************/
void InitSymbolTimer()
{
#if defined(__18CXX)
    TMR_CON = 0b00000000 | CLOCK_DIVIDER_SETTING;
    TMR_IP = 1;
    TMR_IF = 0;
    TMR_IE = 1;
    TMR_ON = 1;

    timerExtension1 = 0;
    timerExtension2 = 0;
#elif defined(__dsPIC30F__) || defined(__dsPIC33F__) || defined(__PIC24F__) || defined(__PIC24FK__) || defined(__PIC24H__)
    T2CON = 0b0000000000001000 | CLOCK_DIVIDER_SETTING;
    T2CONbits.TON = 1;
#elif defined(__PIC32MX__)
    #if defined (SECOND_PROTOTYPE) //Timer 3 freed for ADC rjk
        CloseTimer4();
        WriteTimer4(0x00);
        WriteTimer5(0x00);
        WritePeriod5(0xFFFF);
        OpenTimer4((T4_ON|T4_32BIT_MODE_ON|CLOCK_DIVIDER_SETTING),0xFFFFFFFF);
    #else
        CloseTimer2();
        WriteTimer2(0x00);
        WriteTimer3(0x00);
        WritePeriod3(0xFFFF);
        OpenTimer2((T2_ON|T2_32BIT_MODE_ON|CLOCK_DIVIDER_SETTING),0xFFFFFFFF);
    #endif
#else
    #error "Symbol timer implementation required for stack usage."
#endif
}
Beispiel #2
0
// low level pulse timer - return prescaled ticks converted back to a long
unsigned long GetTimer_ticks(BYTE reset)
{
    unsigned long time;

    time= ReadTimer5();

    if(reset)
       WriteTimer5(0);
    return time * TIMER5_PRESCALER;
}
Beispiel #3
0
// low level pulse timer
unsigned int GetTimer_us(BYTE reset)
{
    unsigned int time;
    
    time= ReadTimer5();

    if(reset)
       WriteTimer5(0L);
    return time / TimeScaler;
}
Beispiel #4
0
void fis_Timer5_config(unsigned int period){
    //                      7654321076543210
    unsigned int config = 0b1000000000110000; //T4_ON & T4_GATE_ON & T4_IDLE_CON & T4_PS_1_1 & T4_SOURCE_INT;
    //                      7654321076543210
    //unsigned int period = 0b0000000000000111;
    WriteTimer5(0x0000);
    OpenTimer5( config, period );

    //ConfigIntTimer5(T5_INT_ON & T5_INT_PRIOR_1);
    EnableIntT5;

    //printf("t5_config\n");
}
Beispiel #5
0
// DATA reading ISR
void __ISR(_TIMER_4_VECTOR, ipl7auto) HW_read_bit(void)
{
    static unsigned long count= 0L;
    unsigned int time;
    static char out, previous= -1;
    BYTE i, *p;
    BOOL fskread= FALSE;

    // show trigger moment (you must also set end of routine debugger statement)
    //DEBUG_PIN_2= HIGH;

    // reset interrupt
    mT4ClearIntFlag();

    // toggle bit period flag for analogue sampler
    ReaderPeriod= !ReaderPeriod;

    if(FakeRead)
        return;


    // don't do anything unless we've got data to read - we may have been left running due to higher level error.
    if(!HW_Bits)
    {
        stop_HW_reader_ISR();
        return;
    }

    // debugging - monitor with a logic analyser
    // show data value
    //DEBUG_PIN_3= READER_DATA;

    switch(RFIDlerConfig.Modulation)
    {
        case MOD_MODE_ASK_OOK:

            // get current bit value
            out= READER_DATA;

            // check for manchester encoding sync/errors
            if(RFIDlerConfig.Manchester && count)
            {
                // the 2nd half bit may not be equal to the 1st
                // this error is allowed to occur exactly once, in which case we
                // are out of sync so we slip timing by half a bit
                if(count % 2 && out == previous)
                {
                    //DEBUG_PIN_4= !DEBUG_PIN_4;
                    // error LED on
                    mLED_Error_On();
                    if(Manchester_Error)
                    {
                        //DEBUG_PIN_4= !DEBUG_PIN_4;
                        // 2 strikes and we fail!
                        count= 0L;
                        previous= -1;
                        Manchester_Auto_Correct= FALSE;
                        stop_HW_reader_ISR();
                        return;
                    }
                    else
                    {
                        //DEBUG_PIN_4= !DEBUG_PIN_4;
                        // 1st error - reset data and start again, now offset by a half bit.
                        Manchester_Error= TRUE;
                        //DEBUG_PIN_2= LOW;

                        // special case - if tag can start with a '0' (i.e. there is no initial '1' as a sync
                        // bit, it will look like a 1/2 bit error, but we may only detect the error later on,
                        // so we must correct all the previous mis-reads, offset the count by 1/2 a bit and
                        // complete this read
                        if(Manchester_Auto_Correct && count != 1)
                        {
                            for(i= 0, p= EMU_Data ; i <= count / 2L ; ++i, --p)
                                *p= !*(p);
                            --count;
                        }
                        else
                        {
                            EMU_Data -= (count / 2L);
                            count= 1L;
                            // successful read resets timeout
                            WriteTimer5(0);
                            return;
                        }
                    }
                }
            }
            
            // now set data bit

            // biphase is 1 if mid-bit change or 0 if no mid-bit change
            if(RFIDlerConfig.BiPhase && count % 2L)
            {
                if(previous == out)
                    *(EMU_Data++)= 0x00 ^ RFIDlerConfig.Invert;
                else
                    *(EMU_Data++)= 0x01 ^ RFIDlerConfig.Invert;
               //DEBUG_PIN_1= *(EMU_Data - 1);
               // successful read resets timeout
               WriteTimer5(0);
            }

            // read data direct for normal ASK
            if(!RFIDlerConfig.Manchester && !RFIDlerConfig.BiPhase)
            {
                //DEBUG_PIN_1= out;
                *(EMU_Data++)= out ^ RFIDlerConfig.Invert;
                // successful read resets timeout
                WriteTimer5(0);
            }

            // read only 2nd half of bit if manchester
            if (RFIDlerConfig.Manchester && count % 2L)
            {
                //DEBUG_PIN_1= out;
                // always invert as we are now reading 2nd half bit, so opposite value
                *(EMU_Data++)= !(out ^ RFIDlerConfig.Invert);
                // successful read resets timeout
                WriteTimer5(0);
            }

            previous= out;

            break;

        case MOD_MODE_FSK1:
        case MOD_MODE_FSK2:
            // to read FSK we will measure a pulse width. we must stop before end of bit period so we don't
            // get caught by the next interrupt. accordingly our time period is shortened by 20%, but
            // that should be OK as we only need to see a single pulse.
            //DEBUG_PIN_4= !DEBUG_PIN_4;
            //time= CONVERT_TO_TICKS(RFIDlerConfig.FrameClock * (RFIDlerConfig.DataRate - (RFIDlerConfig.DataRate / 5)));
            time= RFIDlerConfig.FrameClock * (RFIDlerConfig.DataRate - (RFIDlerConfig.DataRate / 5));
            GetTimer_us(RESET);
            // measure 2nd pulse
            while(GetTimer_us(NO_RESET) < time && !fskread)
            {
              fskread= TRUE;
              //DEBUG_PIN_4= !DEBUG_PIN_4;
                // skip to first pulse
              while(READER_DATA)
                    if(GetTimer_us(NO_RESET) > time)
                    {
                        fskread= FALSE;
                        break;
                    }
                while(!READER_DATA)
                    if(GetTimer_us(NO_RESET) > time)
                    {
                        fskread= FALSE;
                        break;
                    }
                // skip first pulse
                while(READER_DATA)
                    if(GetTimer_us(NO_RESET) > time)
                    {
                        fskread= FALSE;
                        break;
                    }
                while(!READER_DATA)
                    if(GetTimer_us(NO_RESET) > time)
                    {
                        fskread= FALSE;
                        break;
                    }
                // measure second pulse
                GetTimer_us(RESET);
                //DEBUG_PIN_4= !DEBUG_PIN_4;
                while(READER_DATA)
                    if(GetTimer_us(NO_RESET) > time)
                    {
                        fskread= FALSE;
                        break;
                    }
            }
            //DEBUG_PIN_4= !DEBUG_PIN_4;
            // successful read resets timeout
            if(fskread)
                *(EMU_Data++)= GetTimer_us(RESET); // get pulsewidth in uS
            break;

        // TODO: PSK2, PSK3
        case MOD_MODE_PSK1:
            // READER_DATA goes high when a phase change occurs
            // we toggle bit value on phase change

            // data line should go high at start of bit period, but to allow for some lag
            // we will wait for up to a full frame clock just to be sure
            time= CONVERT_TO_TICKS(RFIDlerConfig.FrameClock);
            WriteTimer5(0);
            while(ReadTimer5() < time)
                if(READER_DATA)
                    break;

            // show toggle output
            //DEBUG_PIN_1 ^= READER_DATA;

            // get data
            out ^= (READER_DATA ^ RFIDlerConfig.Invert);

            // test read quality - pulsewidth wil be short if tag not correctly coupled
            if(PSK_Min_Pulse && READER_DATA)
            {
                // fast reset timer
                WriteTimer5(0);
                //DEBUG_PIN_1 ^= 1;
                while(READER_DATA)
                    ;
                time= GetTimer_us(NO_RESET);
                if(time < PSK_Min_Pulse)
                    PSK_Read_Error= 1;
                //DEBUG_PIN_1 ^= 1;
            }

            *(EMU_Data++)= out;
            // successful read resets timeout
            WriteTimer5(0);
            break;
            
        default:
            break;
    }

    ++count;

    // debugging - reset output line
    //DEBUG_PIN_2= LOW;

    // finished?
    if(count == HW_Bits)
    {
        HW_Bits= count= 0L;
        previous= -1;
        // if only 1 manchester error caught, that's OK
        Manchester_Error= FALSE;
        // caller must reset this to use again
        Manchester_Auto_Correct= FALSE;
        mLED_Error_Off();
        // stop reading, but leave clock running to preserve tag state - higher level will shut down when done
        stop_HW_reader_ISR();
    }
}
Beispiel #6
0
// Reader clock ISR
// also process RWD commands while we toggle clock line
void __ISR(_OUTPUT_COMPARE_5_VECTOR, ipl6auto) reader_clock_tick (void)
{
    static unsigned int count= 0;
    static unsigned int bcount= 0;

    // Clear interrupt flag
    mOC5ClearIntFlag();
    
    mLED_Clock_On();

    // process RWD commands (if any)
    switch (RWD_State)
    {
        case RWD_STATE_INACTIVE:
        case RWD_STATE_ACTIVE:
            //DEBUG_PIN_4= !DEBUG_PIN_4;
            break;

        case RWD_STATE_GO_TO_SLEEP:
            //DEBUG_PIN_4= !DEBUG_PIN_4;
            //DEBUG_PIN_4= !DEBUG_PIN_4;
            // initial shutdown of coil to restart tag
            READER_CLOCK_ENABLE_OFF();
            COIL_OUT_LOW();
            // time small amounts with ticks, large with uS
            if(RWD_Sleep_Period > MAX_TIMER5_TICKS)
                Delay_us(CONVERT_TICKS_TO_US(RWD_Sleep_Period));
            else
            {
                WriteTimer5(0);
                while(GetTimer_ticks(NO_RESET) < RWD_Sleep_Period)
                    ;
            }
            count= 0;
            RWD_State= RWD_STATE_WAKING;
            // restart clock only if we have a wake period
            if(RWD_Wake_Period)
                READER_CLOCK_ENABLE_ON();
            break;

        case RWD_STATE_WAKING:
            //DEBUG_PIN_4= !DEBUG_PIN_4;
            // leave coil running for wakeup period
            if(count == RWD_Wake_Period)
            {
                count= 0;
                bcount = 0;
                if(*RWD_Command_ThisBit != '*')
                    RWD_State= RWD_STATE_START_SEND;
                else
                    RWD_State= RWD_STATE_ACTIVE;
            }
            else
                count++;
            break;

        case RWD_STATE_START_SEND:
            //DEBUG_PIN_4= !DEBUG_PIN_4;
            // send initial gap
            // stop modulation of coil and wait
            READER_CLOCK_ENABLE_OFF();
            COIL_OUT_LOW();
            count= 0;
            if(RWD_Barrier)
		RWD_State= RWD_STATE_SENDING_BARRIER_LOW;
            else
                RWD_State= RWD_STATE_SENDING_BIT_LOW;
            //DEBUG_PIN_4= !DEBUG_PIN_4;
            // restart clock
            //READER_CLOCK_ENABLE_ON();
            break;

        case RWD_STATE_SENDING_BIT_HIGH:
            //DEBUG_PIN_4= !DEBUG_PIN_4;
            // clock running for bit period, then wait for gap period
            if((*RWD_Command_ThisBit && count == RWD_One_Period) || (!*RWD_Command_ThisBit && count == RWD_Zero_Period))
            {                    
		count= 0;
                if(*RWD_Command_ThisBit == '*')
                    RWD_State= RWD_STATE_POST_WAIT;
		else if(RWD_Barrier && bcount == 7)
		    RWD_State= RWD_STATE_SENDING_BARRIER_LOW;
                else
                    RWD_State= RWD_STATE_SENDING_BIT_LOW;
		READER_CLOCK_ENABLE_OFF();
                COIL_OUT_LOW();
                bcount++;
                if(bcount == 8)
                   bcount = 0;
		          
            }
            else
                count++;
            break;

	case RWD_STATE_SENDING_BIT_LOW:

            if((*RWD_Command_ThisBit && count == RWD_One_Gap_Period) || (!*RWD_Command_ThisBit && count == RWD_Zero_Gap_Period))
            {
		
                ++RWD_Command_ThisBit;
                count= 0;

                RWD_State= RWD_STATE_SENDING_BIT_HIGH;
                // restart clock

               READER_CLOCK_ENABLE_ON();
            }
            else
                count++;
            break;

	case RWD_STATE_SENDING_BARRIER_HIGH:

            if(count == RWD_One_Barrier_Period){
                count= 0;
                RWD_State= RWD_STATE_SENDING_BIT_LOW;
		READER_CLOCK_ENABLE_OFF();
                COIL_OUT_LOW();
	    }else
                count++;
            break;

	case RWD_STATE_SENDING_BARRIER_LOW:

            if(count == RWD_Zero_Barrier_Period){
                count= 0;
                RWD_State= RWD_STATE_SENDING_BARRIER_HIGH;
		READER_CLOCK_ENABLE_ON();
	    }else
                count++;
            break;

        case RWD_STATE_POST_WAIT:
            //DEBUG_PIN_4= !DEBUG_PIN_4;
            // coil running for forced post-command wait period
            if(count == RWD_Post_Wait)
            {
                count= 0;
                RWD_State= RWD_STATE_ACTIVE;
            }
            else
                count++;
            break;

        default:
            break;
    }
}
Beispiel #7
0
// raw timer wait - for things that don't want any delays...
// 1us == x timer ticks where x is what MHz chip is running at (e.g. 80 for 80MHz)
// note that we reset on the way out to ensure external code action is included in
// the timing.
void TimerWait(unsigned long ticks)
{
    while (ReadTimer5() < ticks)
        ;
    WriteTimer5(0);
}