// 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; }
// low level pulse timer unsigned int GetTimer_us(BYTE reset) { unsigned int time; time= ReadTimer5(); if(reset) WriteTimer5(0L); return time / TimeScaler; }
// 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(); } }
// 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); }