コード例 #1
0
ファイル: ask.c プロジェクト: 10to7/RFIDler
// h/w clock ASK emulator - initialise data pointers for ISR and start timer 2
// args: clock pulsewidth (NOT period!), data as array of 0/1, repeat
void write_ASK_HW_clock(unsigned int pulse, BYTE *data, unsigned int tpb, unsigned int repeat)
{
    // convert to ticks
    pulse= CONVERT_TO_TICKS(pulse);
    // we only need to tick once per bit
    pulse *= (unsigned long) tpb;

    // point globals at data for ISR
    EMU_ThisBit= *data;
    EMU_Data= data + 1;
    EMU_Reset_Data= data;
    EMU_DataBitRate= 1;
    EMU_SubCarrier_T0= 1;

    EMU_Repeat= repeat;

    // if we're manchester or bi-phase encoding, we want to clock twice as fast so we can toggle on half-bit
    if(RFIDlerConfig.Manchester || RFIDlerConfig.BiPhase)
    {
        pulse /= 2;
        EMU_SubCarrier_T0 *= 2;
        EMU_DataBitRate *= 2;
    }

    // make sure no clock is running
    stop_HW_clock();
    
    // set mode
    EmulationMode= MOD_MODE_ASK_OOK;

    // make sure nobody's using our timer
    CloseTimer3();

    // tri-state on, clock low
    READER_CLOCK_ENABLE_ON();
    CLOCK_COIL= LOW;

    // emulator mode
    COIL_MODE_EMULATOR();

    // this is also a semaphore so the rest of the code knows we're running
    mLED_Emulate_On();

    // start timer - ISR will send data
    OpenTimer3( T3_ON | T3_PS_1_1 | T3_SOURCE_INT, pulse - 1L);
    mT3SetIntPriority(6);
    mT3ClearIntFlag();
    mT3IntEnable(TRUE);
}
コード例 #2
0
ファイル: rwd.c プロジェクト: natashenka/RFIDler
// this routine accepts either binary arrays or binary strings
BOOL rwd_send(unsigned char *command, unsigned int length, BOOL reset, BOOL block, BYTE initial_state, unsigned long fc, unsigned long sleep, unsigned int wake, unsigned int pw0, unsigned int pw1, unsigned int gap, unsigned int post_wait)
{
    unsigned int i;
    RWD_Fc= fc;
    // convert FCs to system ticks
    RWD_Sleep_Period= CONVERT_TO_TICKS(sleep * fc);
    RWD_Gap_Period= gap * 2;
    RWD_One_Gap_Period= gap * 2;
    RWD_Zero_Gap_Period= gap * 2;
    // convert FCs to OCM ticks
    RWD_Wake_Period= wake * 2;
    RWD_Zero_Period= pw0 * 2;
    RWD_One_Period= pw1 * 2;
    RWD_Post_Wait= post_wait * 2;
    if(!RWD_Zero_Period || !RWD_One_Period || !RWD_Gap_Period)
        return FALSE;
    // convert ascii string to bin if required
    if(command[0] == '0' || command[0] == '1')
    {
        if(!binstringtobinarray(RWD_Command_Buff, command))
            return FALSE;
    }
    else
        memcpy(RWD_Command_Buff, command, length);
    RWD_Command_Buff[length]= '*';
    RWD_Command_ThisBit= RWD_Command_Buff;
    // start clock and wait for TAG to wake if not already running
    // this is needed in case a non-resetting RWD command is issued before any other action has woken tag
    if(mGetLED_Clock() == mLED_OFF)
    {
        RWD_State= RWD_STATE_INACTIVE;
        InitHWReaderClock(OC_TOGGLE_PULSE, RWD_Fc / 2L, RWD_Fc, RWD_State);
        if(!reset)
            Delay_us((RFIDlerConfig.FrameClock * RFIDlerConfig.RWD_Wake_Period) / 100);
    }
    if(reset)
        RWD_State= RWD_STATE_GO_TO_SLEEP;
    else
        RWD_State= initial_state;
    // see if ISR has flagged RWD command finished
    if(block)
        while(RWD_State != RWD_STATE_ACTIVE)
            ;
    return TRUE;
}
コード例 #3
0
ファイル: psk.c プロジェクト: zhihuawang/RFIDler
void read_PSK1_HW_clock(unsigned int period, unsigned int ticks, BYTE *data, unsigned int bits, unsigned int timeout_us, unsigned int min_pulse_us)
{
    // point globals at data for ISR
    EMU_Data= data;
    HW_Bits= bits;
    PSK_Min_Pulse= min_pulse_us;
    PSK_Read_Error= FALSE;

    memset(EMU_Data, '\0', bits);

    // stop USB interfering
    USBMaskInterrupts();

    // start clock if not already running
    if(!mGetLED_Clock() == mLED_ON)
    {
        InitHWReaderClock(OC_TOGGLE_PULSE, period / 2L, period, RWD_STATE_ACTIVE);

        // give reader time to wake up and settle
        Delay_us((RFIDlerConfig.FrameClock * RFIDlerConfig.RWD_Wake_Period) / 100);
    }

    // reset timer for timeout
    GetTimer_us(RESET);

    // align ourselves to reader's bit period by finding start of a pulse
    while(READER_DATA)
        if(timeout_us)
            if (GetTimer_us(NO_RESET) > timeout_us)
                return;
    while(!READER_DATA)
        if(timeout_us)
            if (GetTimer_us(NO_RESET) > timeout_us)
                return;

    // reset timer for external timeouts
    GetTimer_us(RESET);

    // start ISR to read PSK data
    InitHWReaderISR(CONVERT_TO_TICKS(period) * ticks - 1L, TRUE);
}
コード例 #4
0
ファイル: psk.c プロジェクト: zhihuawang/RFIDler
// h/w clock PSK emulator - initialise data pointers for ISR and start timer 2
// args: clock period, data as array of 0/1, fc per bit, sub-carrier ticks, repeat
void write_PSK1_HW_clock(unsigned int period, BYTE *data, unsigned int fcpb, unsigned int c0, unsigned int repeat)
{
    // convert to ticks
    period= CONVERT_TO_TICKS(period);
    // for psk we want a full clock cycle, not a tick
    period *= 2;

    // point globals at data for ISR
    EMU_ThisBit= *data;
    EMU_Data= data + 1;
    EMU_Reset_Data= data;
    EMU_DataBitRate= fcpb;
    EMU_SubCarrier_T0= c0;
    EMU_Repeat= repeat;

    // set mode
    EmulationMode= MOD_MODE_PSK1;

    // make sure no clock is running
    stop_HW_clock();

    // make sure nobody's using our timers
    CloseTimer3();

    // tri-state on, clock low
    READER_CLOCK_ENABLE_ON();
    CLOCK_COIL= LOW;

    // emulator mode
    COIL_MODE_EMULATOR();

    // this is also a semaphore so the rest of the code knows we're running
    mLED_Emulate_On();

    // start timer - ISR will send data
    OpenTimer3( T3_ON | T3_PS_1_1 | T3_SOURCE_INT, period / 2L - 1L);
    mT3SetIntPriority(6);
    mT3ClearIntFlag();
    mT3IntEnable(TRUE);
}
コード例 #5
0
ファイル: fsk.c プロジェクト: 10to7/RFIDler
// h/w clock FSK emulator - initialise data pointers for ISR and start timer 2
// args: clock pulsewidth (NOT period!), data as array of 0/1, T0 sub-carrier ticks, T1 sub-carrier ticks, repeat
void write_FSK_HW_clock(unsigned long pulse, BYTE *data, unsigned int tpb, unsigned int t0, unsigned int t1, unsigned int repeat)
{
    // convert to ticks
    pulse= CONVERT_TO_TICKS(pulse);

    // point globals at data for ISR
    EMU_ThisBit= *data;
    EMU_Data= data + 1;
    EMU_Reset_Data= data;
    EMU_Repeat= repeat;
    EMU_DataBitRate= tpb;
    EMU_SubCarrier_T0= t0;
    EMU_SubCarrier_T1= t1;

    // set mode
    EmulationMode= MOD_MODE_FSK;

    // make sure no clock is running
    stop_HW_clock();

    // make sure nobody's using our timer
    CloseTimer3();

    // emulator mode
    COIL_MODE_EMULATOR();

    // tri-state on, clock low
    READER_CLOCK_ENABLE_ON();
    CLOCK_COIL= LOW;

    // this is also a semaphore so the rest of the code knows we're running
    mLED_Emulate_On();

    // start timer - ISR will send data
    OpenTimer3( T3_ON | T3_PS_1_1 | T3_SOURCE_INT, pulse - 1L);
    mT3SetIntPriority(6);
    mT3ClearIntFlag();
    mT3IntEnable(TRUE);
}
コード例 #6
0
ファイル: ask.c プロジェクト: 10to7/RFIDler
// h/w clock reader - initialise data pointers for ISR and start timers
// timer2 creates clock output for external reader
// timer4 reads data bit values
// period_us == clock for reader
// ticks == clock periods per bit
// bits == number of bits to read
// oneshot must be set if we are reading data in response to RWD, so no repeating stream
BOOL read_ASK_HW_clock(unsigned int period, unsigned int ticks, BYTE *data, unsigned int bits, unsigned int timeout_us, BOOL oneshot)
{
    unsigned long dwell, time;
    BYTE count;
    
    Manchester_Error= FALSE;

    // if we're manchester or bi-phase encoding, we want to clock twice as fast so we can read both halves of the bit
    if(RFIDlerConfig.Manchester || RFIDlerConfig.BiPhase)
    {
        ticks /= 2;
        HW_Bits= (unsigned long) bits * 2;
    }
    else
       HW_Bits= (unsigned long) bits;

    // point globals at data for ISR
    EMU_Data= data;

    memset(EMU_Data, '\0', bits);

    // stop USB interfering
    USBMaskInterrupts();

    // start clock if not already running
    if(!mGetLED_Clock() == mLED_ON)
    {
        InitHWReaderClock(OC_TOGGLE_PULSE, period / 2L, period, RWD_STATE_ACTIVE);

        // give reader time to wake up and settle
        Delay_us((RFIDlerConfig.FrameClock * RFIDlerConfig.RWD_Wake_Period) / 100);
    }

    // align ourselves to reader's bit period by waiting until the end of a pulse
    GetTimer_us(RESET);
    count= READER_DATA;
    while(count == READER_DATA)
        if(GetTimer_us(NO_RESET) > timeout_us)
            return FALSE;

    // convert to ticks
    period= CONVERT_TO_TICKS(period);

    // biphase cannot auto-align when it detects a half-bit error, so we must align
    // on a full bit before we start
    if(!oneshot && RFIDlerConfig.BiPhase)
    {
        dwell= period * ticks * 2;
        count= 0;
        while((time= get_reader_gap(timeout_us)))
        {
            if(!time || count == 255)
                return;
            else
                if(approx(time, dwell, 10))
                    break;
            ++count;
        }
    }

    // wait for half the bit period so we sample mid-tick, not just as bit is toggling
    dwell= ((period * ticks) / 2L);
    GetTimer_ticks(RESET);
    //DEBUG_PIN_2= HIGH;
    while(GetTimer_ticks(NO_RESET) < dwell)
            ;

    // reset timer for external timeouts
    GetTimer_us(RESET);

    //DEBUG_PIN_2= LOW;
    
    // re-start reader ISR to read this bit if required
    InitHWReaderISR(period * ticks - 1L, TRUE);

    return TRUE;
}
コード例 #7
0
ファイル: fsk.c プロジェクト: 10to7/RFIDler
BOOL read_FSK_HW_clock(unsigned int period, unsigned int ticks, BYTE *data, unsigned int bits, unsigned int timeout_us)
{
    unsigned int gaplength;

    // point globals at data for ISR
    EMU_Data= data;
    HW_Bits= bits;

    memset(EMU_Data, '\0', bits);

    // stop USB interfering
    USBMaskInterrupts();

    // start clock if not already running
    if(!mGetLED_Clock() == mLED_ON)
    {
        InitHWReaderClock(OC_TOGGLE_PULSE, period / 2L, period, RWD_STATE_ACTIVE);

        // give reader time to wake up and settle
        Delay_us((RFIDlerConfig.FrameClock * RFIDlerConfig.RWD_Wake_Period) / 100);
    }

    // reset timer for timeout
    GetTimer_us(RESET);

    // align ourselves to reader's bit period by finding the end of a pulse train.
    // we can do this by measuring the gaps. when they become significantly different
    // sized (more than 25%), we have just switched frequency.

    // find the start of a pulse
    while(READER_DATA)
        if(timeout_us)
            if (GetTimer_us(NO_RESET) > timeout_us)
                return FALSE;
    while(!READER_DATA)
        if(timeout_us)
            if (GetTimer_us(NO_RESET) > timeout_us)
                return FALSE;
    while(READER_DATA)
        if(timeout_us)
            if (GetTimer_us(NO_RESET) > timeout_us)
                return FALSE;

    // reset timer so we can meausure gap period
    GetTimer_us(RESET);
    while(!READER_DATA)
        if(timeout_us)
            if (GetTimer_us(NO_RESET) > timeout_us)
                return FALSE;
    gaplength= GetTimer_us(RESET);
    
    // now look for a gap that doesn't match
    while(42)
    {
        while(READER_DATA)
            if(timeout_us)
                if (GetTimer_us(NO_RESET) > timeout_us)
                    return FALSE;
        GetTimer_us(TRUE);
        while(!READER_DATA)
            if(timeout_us)
                if (GetTimer_us(NO_RESET) > timeout_us)
                    return FALSE;
        if(!approx(GetTimer_us(NO_RESET), gaplength, FSK_TOLERANCE))
            break;
    }

    // reset timer for external timeouts
    GetTimer_us(RESET);

    // start ISR to read FSK data
    InitHWReaderISR(CONVERT_TO_TICKS(period) * ticks - 1L, TRUE);

    return TRUE;
}
コード例 #8
0
ファイル: isr.c プロジェクト: natashenka/RFIDler
// 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();
    }
}