// 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); }
// 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); }
// 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); }
// 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; } }