#include "nfcbord.h" #include #include #include #include #include #include "writepin.h" NfcBoard nfcBoard; extern char buffer[SNPRINTF_BUFFER_SIZE]; ISR(PCINT1_vect, ISR_NOBLOCK) { if(readPin(&PINC, PC3)) { uint8_t* data = nfcBoard.irqReg.read(); for(uint8_t i = 0; i < NFC_PORTS; ++i) { if(*data & (1 << i)) { for(uint8_t j = 0; j < nfcBoard.readers.count(); ++j) { if(nfcBoard.irqPins[j] == i) { nfcBoard.readers[j].irq(); } } } } } } NfcBoard::NfcBoard(): csReg(&PORTC, PC1, PC2, PC0), irqReg(&PORTC, &PINB, PC5, PB1, PC4) { DDRC |= (1 << PC0) | (1 << PC1) | (1 << PC2) | (1 << PC4) | (1 << PC5); DDRB |= (1 << PB4) | (1 << PB3); PCMSK1 |= 1 << PCINT11; PCICR |= 1 << PCIE1; csReg.clear(true); irqReg.read(); probe(); } uint8_t NfcBoard::csToIrq(uint8_t cs) { switch(cs) { case 0: return 3; case 1: return 2; case 2: return 1; case 3: return 7; case 4: return 7; case 5: return 6; case 6: return 5; case 7: return 3; default: return 8; } } void NfcBoard::probe() { readers.clear(); irqPins.clear(); for(uint8_t i = 0; i < NFC_PORTS; ++i) { if(Mfrc522::probe(&spim, &csReg, i)) { readers.push_back(Mfrc522(&spim, &csReg, i)); irqPins.push_back(csToIrq(i)); } } } void NfcBoard::printNfcDevices(Serial* serial) { serial->write_p(PSTR("NFC DEVICES:\n")); for(uint8_t i = 0; i < readers.count(); ++i) { snprintf_P(buffer, SNPRINTF_BUFFER_SIZE, PSTR("NFC NUMBER: %u IRQ: %x\n"), i, irqPins[i]); serial->write(buffer, SNPRINTF_BUFFER_SIZE); } } int NfcBoard::dispatch(char* inBuffer, Serial* serial) { if(strcmp(inBuffer, "debug") == 0) { Mfrc522::serial = serial; return 0; } else if(strcmp(inBuffer, "quiet") == 0 ) { Mfrc522::serial = nullptr; return 0; } else if(strcmp(inBuffer, "irqs") == 0 ) { PCMSK1 &= ~(1 << PCINT11); PCICR &= ~(1 << PCIE1); serial->write_p(PSTR("Irq pin detection test\n")); while(!serial->dataIsWaiting()) { uint8_t* data = irqReg.read(); for(uint8_t i = 0; i < NFC_PORTS; ++i) { if(*data & (1 << i)) { serial->write("IRQ: "); serial->write((int)i); serial->putChar('\n'); } } } serial->write_p(PSTR("Finished\n")); PCMSK1 |= 1 << PCINT11; PCICR |= 1 << PCIE1; return 0; } else if(strcmp(inBuffer, "detect") == 0 ) { serial->write_p(PSTR("Runing tag detection test\n")); while(!serial->dataIsWaiting()) { bool present = readers[0].cardPresent(); if(present) { Mfrc522::Uid uid; uint8_t res = readers[0].selectTag(&uid); if(res != 0) continue; serial->write_p(PSTR("Uid: ")); for(uint8_t i = 0; i < uid.size; ++i) { serial->write((int)uid.uidByte[i]); if(i < uid.size-1) serial->putChar(':'); } serial->putChar('\n'); } _delay_ms(100); } serial->write_p(PSTR("Finished\n")); return 0; } else if(strcmp(inBuffer, "fastdetect") == 0 ) { serial->write_p(PSTR("Runing fast tag detection test\n")); while(!serial->dataIsWaiting()) { bool present = readers[0].cardPresent(); if(present) { Mfrc522::Uid uid; uint8_t res = readers[0].getUid(&uid); if(res != 0) continue; serial->write_p(PSTR("Uid: ")); for(uint8_t i = 0; i < uid.size; ++i) { serial->write((int)uid.uidByte[i]); if(i < uid.size-1) serial->putChar(':'); } serial->putChar('\n'); } } serial->write_p(PSTR("Finished\n")); return 0; } else if(strcmp(inBuffer, "fifotst") == 0 ) { serial->write_p(PSTR("Runing fifo test\n")); Mfrc522::serial = serial; readers[0].testFifo(); Mfrc522::serial = nullptr; serial->write_p(PSTR("Finished\n")); return 0; } else if(strcmp(inBuffer, "enable") == 0 ) { for(uint8_t i = 0; i < readers.count(); ++i) { readers[i].detectAsync(detectCb, serial); } serial->write_p(PSTR("Nfc tag listening enabled\n")); return 0; } else if(strcmp(inBuffer, "status") == 0 ) { printNfcDevices(serial); return 0; } else if(strcmp(inBuffer, "wake") == 0 ) { uint8_t bufferATQA[2]; uint8_t len = sizeof(bufferATQA); uint8_t res = readers[0].wakeupTag(bufferATQA, &len); snprintf_P(buffer, SNPRINTF_BUFFER_SIZE, PSTR("wakeupTag returned: %u Buffer: 0x%x 0x%x len %u\n"), res, bufferATQA[0], bufferATQA[1], len); serial->write(buffer, SNPRINTF_BUFFER_SIZE); return 0; } else if(strcmp(inBuffer, "probe") == 0 ) { probe(); printNfcDevices(serial); return 0; } return -3; } void NfcBoard::detectCb(Mfrc522* reader, void* data) { Serial* serial = reinterpret_cast(data); static Mfrc522* oldReader = nullptr; static Mfrc522::Uid oldUid = {0}; Mfrc522::Uid uid; if(reader->getUid(&uid) == 0 && (uid != oldUid || reader != oldReader)) { serial->write("TAG: "); for(uint8_t i = 0; i < uid.size; ++i) { serial->write((int)uid.uidByte[i]); if(i < uid.size-1) serial->putChar(':'); } serial->putChar('\n'); oldUid = uid; oldReader = reader; } reader->detectAsync(detectCb, serial); }