void Iso14443bFindTag(void) { Trf797xTurnRfOn(); Trf797xWriteIsoControl(0x0C); // When a PICC is exposed to an unmodulated operating field // it shall be able to accept a quest within 5 ms. // PCDs should periodically present an unmodulated field of at least // 5,1 ms duration. (ISO14443-3) McuDelayMillisecond(6); iso14443bAnticollision(0xB0, 0x04); // 16 slots (0xB0, then 0x04 for 16 slots or 0x00 for 1 slot) Trf797xTurnRfOff(); Trf797xResetIrqStatus(); }
void hydranfc_tag_emul_init(void) { uint8_t data_buf[4]; Trf797xInitialSettings(); Trf797xReset(); /* ISO Control */ data_buf[0] = ISO_CONTROL; data_buf[1] = 0x24; /* ISO14443A */ Trf797xWriteSingle(data_buf, 2); /* Configure RX */ data_buf[0] = RX_SPECIAL_SETTINGS; data_buf[1] = 0x3C; Trf797xWriteSingle(data_buf, 2); /* Configure Adjustable FIFO IRQ Levels Register (96B RX & 32B TX) */ data_buf[0] = 0x14; data_buf[1] = 0x0F; Trf797xWriteSingle(data_buf, 2); /* Configure NFC Target Detection Level Register */ /* RF field level required for system wakeup to max */ data_buf[0] = NFC_TARGET_LEVEL; data_buf[1] = NFC_TARGET_LEVEL; data_buf[2] = 0x16; // NFC_LOW_DETECTION data_buf[3] = BIT0; // read the NFCTargetLevel register Trf797xReadSingle(&data_buf[1], 1); data_buf[1] |= BIT2 + BIT1 + BIT0; switch(tag_uid_len) { case 4: data_buf[1] &= ~(BIT7 + BIT6); break; case 7: data_buf[1] &= ~BIT7; data_buf[1] |= BIT6; break; case 10: data_buf[1] &= ~BIT6; data_buf[1] |= BIT7; break; default: break; } data_buf[1] |= BIT5; /* SDD Enabled */ Trf797xWriteSingle(data_buf, 2); data_buf[0] = ISO_14443B_OPTIONS; data_buf[1] = ISO_14443B_OPTIONS; Trf797xReadSingle(&data_buf[1], 1); data_buf[1] |= BIT0; // set 14443A - 4 compliant bit data_buf[2] = CHIP_STATE_CONTROL; data_buf[3] = 0x21; Trf797xWriteSingle(data_buf, 4); /* Configure Test Register */ /* MOD Pin becomes receiver digitized subcarrier output */ /* data_buf[0] = TEST_SETTINGS_1; data_buf[1] = 0x40; Trf797xWriteSingle(data_buf, 2); data_buf[0] = MODULATOR_CONTROL; data_buf[1] = MODULATOR_CONTROL; Trf797xReadSingle(&data_buf[1], 1); data_buf[1] |= BIT3; Trf797xWriteSingle(data_buf, 2); */ write_emul_tag_uid(tag_uid); Trf797xResetIrqStatus(); Trf797xReset(); Trf797xStopDecoders(); Trf797xRunDecoders(); }
void TagIRQ(int irq_status) { uint8_t data_buf[32]; int fifo_size; // RF collision avoidance error if( (irq_status & BIT0) == BIT0) { hydranfc_tag_emul_init(); return; } /* RF field level */ if( (irq_status & BIT2) == BIT2) { // printf_dbg("RF\r\n"); } /* SDD OK */ if( (irq_status & BIT3) == BIT3) { Tag14443A(); // printf_dbg("SDD OK\r\n"); } /* Communication error */ if( (irq_status & BIT4) == BIT4) { hydranfc_tag_emul_init(); return; /* data_buf[0] = RX_SPECIAL_SETTINGS; //check filter and gain Trf797xReadSingle(data_buf, 1); Trf797xStopDecoders(); return; */ } /* RX */ if( (irq_status & BIT6) == BIT6) { data_buf[0] = FIFO_CONTROL; Trf797xReadSingle(data_buf, 1); // determine the number of bytes left in FIFO fifo_size = data_buf[0] & 0x7F; /* Clear Flag FIFO Overflow */ fifo_size = fifo_size & 0x1F; /* Limit Fifo size to 31bytes */ /* Receive data from FIFO */ if(fifo_size > 0) { data_buf[0] = FIFO; Trf797xReadCont(data_buf, fifo_size); /* printf_dbg("RX: "); for(i=0; i<fifo_size; i++) { printf_dbg("0x%02X ", data_buf[i]); } printf_dbg("\r\n"); */ Trf797xReset(); //reset the FIFO after last byte has been read out Trf797xResetIrqStatus(); /* Reply ATS (DESFire EV1) */ /* data_buf[0] = 0x06; data_buf[1] = 0x75; data_buf[2] = 0x81; data_buf[3] = 0x02; data_buf[4] = 0x80; if(emul_14443a_tx_rawdata(data_buf, 5, 0) == 5) { error=0; } else error=1; */ } hydranfc_tag_emul_init(); return; } /* TX complete */ if( (irq_status & BIT7) == BIT7) { Trf797xReset(); // reset the FIFO } }
//----------------------------------------------// //The NFCActiveMain function calls the other NFC// //functions for Felica (active) mode. // //----------------------------------------------// u08_t NfcMain(u08_t *pbuf, u08_t tag) { u08_t i = 0, command[2]; u08_t code = 0; #if DBG_NFC command[0] = TEST_SETTINGS_1; //subcarrier output command[1] = 0x40; Trf797xWriteSingle(command, 2); command[0] = MODULATOR_CONTROL; //analog output command[1] = MODULATOR_CONTROL; Trf797xReadSingle(&command[1], 1); command[1] |= BIT3; Trf797xWriteSingle(command, 2); #endif reader_mode = 0xFF; //rxdataPointer = 0; //RXlen = 0; Trf797xResetIrqStatus(); //function call for single address read IRQ_ON; /* if ((*(pbuf + 2) == 0x00) || (*(pbuf + 2) == 0x02) || (*(pbuf + 2) == 0x04) || (*(pbuf + 2) == 0x06) || (*(pbuf + 2) == 0x08) || (*(pbuf + 2) == 0x0A) || (*(pbuf + 2) == 0x16)) { command[0] = ISOControl; command[1] = NFCIso; WriteSingle(command, 2); } */ switch(*(pbuf + 2)) { case 0x00: //ATR_REQ //send_cstring("ATR\r\n"); do { i++; if(i > 3) { code = 1; goto EXIT; } InitiatorRequest(pbuf); }while((i_reg != 0xFF) && (buf[1] != 0xD5) && (buf[2] != 0x01)); break; case 0x02: //WUP_REQ //send_cstring("WUP\r\n"); do { i++; if(i > 3) { code = 1; goto EXIT; } InitiatorRequest(pbuf); }while((i_reg != 0xFF) && (buf[1] != 0xD5) && (buf[2] != 0x03)); break; case 0x04: //PSL_REQ //send_cstring("PSL\r\n"); do { i++; if(i > 3) { code = 1; goto EXIT; } InitiatorRequest(pbuf); }while((i_reg != 0xFF) && (buf[1] != 0xD5) && (buf[2] != 0x05)); break; case 0x06: //DEP_REQ //send_cstring("DEP\r\n"); while(!InitiatorDepRequest(pbuf)) { i++; if(i > 1) { code = 1; goto EXIT; } }//while break; case 0x08: //DSL_REQ //send_cstring("DSL\r\n"); do { i++; if(i > 3) { code = 1; goto EXIT; } InitiatorRequest(pbuf); }while((i_reg != 0xFF) && (buf[1] != 0xD5) && (buf[2] != 0x09)); break; case 0x0A: //RLS_REQ //send_cstring("RLS\r\n"); do { i++; if(i > 3) { code = 1; goto EXIT; } InitiatorRequest(pbuf); }while((i_reg != 0xFF) && (buf[1] != 0xD5) && (buf[1] != 0x0B)); break; case 0x0C: //Select target mode, CID is recieved with the command //send_cstring("target\r\n"); nfc_iso = ISO_CONTROL; Trf797xReadSingle(&nfc_iso, 1); reader_mode = 0xF0; //set for target iterrupt handling TargetAnticollision(pbuf, tag); break; case 0x16: //Data excahange //kputchar('v'); //kputchar('v'); do { i++; if(i > 1) { code = 1; goto EXIT; } //kputchar('x'); //kputchar('x'); InitiatorRequest(pbuf); //kputchar('w'); //Put_byte(NFCstate); //kputchar('w'); //Put_byte(i_reg); //Put_byte(buf[1]); //Put_byte(buf[2]); //kputchar('w'); }while((i_reg != 0xFF) && (buf[1] != 0xD5) && (buf[2] != 0x09)); //kputchar('z'); //kputchar('z'); break; case 0xF0: //select initiator for passive operation active = 0x00; //NFCIso = ISOControl; //ReadSingle(&NFCIso, 1); #if DBG_NFC command[0] = TEST_SETTINGS_1; //subcarrier output command[1] = 0x40; Trf797xWriteSingle(command, 2); command[0] = MODULATOR_CONTROL; //analog output command[1] = MODULATOR_CONTROL; Trf797xReadSingle(&command[1], 1); command[1] |= BIT3; Trf797xWriteSingle(command, 2); #endif break; case 0xF1: //select initiator for active operation active = 0xFF; //NFCIso = ISOControl; //ReadSingle(&NFCIso, 1); //send_cstring("active\r\n"); command[0] = CHIP_STATE_CONTROL; command[1] = 0x01; Trf797xWriteSingle(command, 2); break; default: break; }//switch IRQ_OFF; UartSendCString("[00]"); return(code); EXIT: IRQ_OFF; UartSendCString("[]"); return(code); }//NfcMain
//---------------------------------------------------------------------- //Performs the initial RF collision avoidance. The modulation //has to be OOK at start and after it completes it has to //switch to 10-30% AM modulation. //---------------------------------------------------------------------- u08_t NfcRfCollisionAvoidance(u08_t mode) { u08_t command = 0x00, Register = 0xFF, i = 0x00; i_reg = 0x01; Trf797xResetIrqStatus(); //IRQ status register has to be read while((Register & 0xC0) != 0x00) //Check external RF field. { if(i == 0x10) //alow the loop only 15 times { return 0; } Register = NFC_TARGET_PROTOCOL; //The register 0x19 bit7 and bit6 Trf797xReadSingle(&Register, 1); //If it is below the LOW level i++; //transmition can begin. }//while switch(mode) { case 0x00: command = INITIAL_RF_COLLISION; break; case 0x01: command = RESPONSE_RF_COLLISION_N; break; case 0x02: command = RESPONSE_RF_COLLISION_0; break; }//switch Trf797xDirectCommand(&command); //performs RF collision avoidance while(i_reg == 0x01) //wait for completition of RF collision avoidance { McuCounterSet(); //TimerA set COUNT_VALUE = 0xF000; //74ms START_COUNTER; //start timer up mode irq_flag = 0x00; while(irq_flag == 0x00) { } /* if(i_reg != 0x01) break; CounterSet(); //TimerA set CountValue = 0xF000; //74ms startCounter; //start timer up mode LPM0; break; */ } switch(i_reg) { //If an error occures during RF collision avoidance case 0x00: break; //the function terminates. case 0x02: return 0; default: return 1; }//switch /* if(mode != 0x00){ CounterSet(); //TimerA set CountValue = 0x352; //1ms startCounter; //start timer up mode LPM0; }*/ return 1; }//RFCollisionAvoidance
//------------------------------------------------------- //This is the main NFC send function that has to follow //the RFAnticollisionAvoidance function - in active mode. //------------------------------------------------------- u08_t NfcSend(u08_t *pbuf) { u08_t length, k = 0; IRQ_OFF; Trf797xReset(); nfc_state = *pbuf; //nfc_state global variable is the main transmit counter length = *pbuf; if(length > FIFO_LEN) { length = FIFO_LEN; } //kputchar('S'); //Put_byte(length); //kputchar('S'); *(pbuf - 5) = 0x8f; *(pbuf - 4) = 0x91; //buffer setup for FIFO writing *(pbuf - 3) = 0x3d; *(pbuf - 2) = (char)(nfc_state >> 4); *(pbuf - 1) = (char)(nfc_state << 4); //RAWwrite(command, 5, 1, 0); //send the request using RAW writing Trf797xRawWrite((pbuf - 5), (length + 5)); IRQ_ON; /* *(pbuf - 1) = 0x1F; WriteCont(pbuf - 1, length + 1); //send the request using RAW writing //Write FIFO_LEN bytes the first time you write to FIFO */ nfc_state = nfc_state - FIFO_LEN; i_reg = 0x01; pbuf += length; irq_flag = 0x00; while(nfc_state > 0) { McuCounterSet(); //TimerA set COUNT_VALUE = 0xf000; //74ms START_COUNTER; //start timer up mode while(irq_flag == 0x00) { } if(irq_flag == 0x03) // Timer Event { buf[0] = 0x00; buf[1] = 0x01; Trf797xWriteSingle(buf, 2); Trf797xResetIrqStatus(); return 0; } if(nfc_state > FIFO_MORE) //the number of unsent bytes is in the NFCstate global { length = FIFO_MORE + 1; //count variable has to be 10 : 9 bytes for FIFO and 1 address } else if(nfc_state < 1) { break; //return from interrupt if all bytes have been sent to FIFO } else { length = nfc_state + 1; //all data has been sent out }//if *(pbuf - 1) = FIFO; //writes FIFO_MORE or less bytes to FIFO for transmitting Trf797xWriteCont(pbuf - 1, length); nfc_state = nfc_state - FIFO_MORE;//write FIFO_MORE bytes to FIFO pbuf += FIFO_MORE; }//while i_reg = 0x01; while(i_reg != 0x00 && k < 2){ //end of TX recieved k++; McuCounterSet(); //TimerA set COUNT_VALUE = 0xf000; //74ms START_COUNTER; //start timer up mode irq_flag = 0x00; while(irq_flag == 0x00) { } } Trf797xResetIrqStatus(); //kputchar('='); //kputchar('='); return 1; }//NFCSend