Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
125 changes: 125 additions & 0 deletions examples/arduino_example/arduino_example_15693.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
/*
The MIT License (MIT)

Copyright (c) 2016 Ivor Wanders

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/

#include <Arduino.h>
#include <SPI.h>
#include <mfrc630.h>

/*


This example shows how to use the library on Arduino platform, it was tested with Arduino Nano


In the setup() function, there are some custom register settings which are you probably have to uncomment or change
such that they are in the correct configuration for your hardware.
The hardware I used had three switchable antenna's, so modification of there parameters is likely to get it to work.

If all goes well, a ISO15693 Tag/Card will print something like:

Tag with valid UID was found! UID: UID:00 02 F4 CF 31 1E 66 24 16 E0 ..waiting 1s for next read


Onto the serial port.

*/


// Pin to select the hardware, the NSS pin.
#define CHIP_SELECT 10

// Pins MOSI, MISO and SCK are connected to the default pins, and are manipulated through the SPI object.
// By default that means MOSI=11, MISO=12, SCK=13.


// Implement the HAL functions on an Arduino compatible system.
void mfrc630_SPI_transfer(const uint8_t* tx, uint8_t* rx, uint16_t len) {
for (uint16_t i=0; i < len; i++){
rx[i] = SPI.transfer(tx[i]);
}
}

// Select the chip and start an SPI transaction.
void mfrc630_SPI_select() {
SPI.beginTransaction(SPISettings(10000000, MSBFIRST, SPI_MODE0)); // gain control of SPI bus
digitalWrite(CHIP_SELECT, LOW);
}

// Unselect the chip and end the transaction.
void mfrc630_SPI_unselect() {
digitalWrite(CHIP_SELECT, HIGH);
SPI.endTransaction(); // release the SPI bus
}

// Hex print for blocks without printf.
void print_block(uint8_t * block,uint8_t length){
for (uint8_t i=0; i<length; i++){
if (block[i] < 16){
Serial.print("0");
Serial.print(block[i], HEX);
} else {
Serial.print(block[i], HEX);
}
Serial.print(" ");
}
}


void mfrc630_ISO15693_example_dump_arduino(){
uint8_t uid[10]={0}; //variable for 10byte UID
uint8_t status = mfrc630_ISO15693_readTag(uid);

if(status==10){
Serial.print("Tag with valid UID was found! UID: ");
print_block(uid,10);
Serial.println(" ..waiting 1s for next read");
}
else{
Serial.println("Failure, No Tag found or Reader Problem!");
}
}
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nitpick, this function has tabs, not spaces.





void setup(){
// Start serial communication.
Serial.begin(9600);

// Set the chip select pin to output.
pinMode(CHIP_SELECT, OUTPUT);

// Start the SPI bus.
SPI.begin();

// Set the registers of the MFRC630 into the default.
mfrc630_AN1102_recommended_registers(MFRC630_PROTO_ISO15693_1_OF_4_SSC);

}

void loop(){
// call the above function until infinity.
mfrc630_ISO15693_example_dump_arduino();
delay(1000);
}
165 changes: 165 additions & 0 deletions mfrc630.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
*/

#include "mfrc630.h"
#include "Arduino.h"
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't want this dependency here, it rules out using this driver outside of the arduino ecosystem.


/** @file */

Expand Down Expand Up @@ -279,6 +280,24 @@ void mfrc630_AN1102_recommended_registers_skip(uint8_t protocol, uint8_t skip) {
mfrc630_write_regs(MFRC630_REG_DRVMOD+skip, buf+skip, sizeof(buf)-skip);
}
break;
case MFRC630_PROTO_ISO15693_1_OF_4_SSC:
{
const uint8_t buf[] = MFRC630_RECOM_15693_ID1_SSC26;
mfrc630_ISO15693_init(MFRC630_PROTO_ISO15693_1_OF_4_SSC,buf);
}
break;
case MFRC630_PROTO_ISO15693_1_OF_4_DSC:
{
const uint8_t buf[] = MFRC630_RECOM_15693_ID1_DSC;
mfrc630_write_regs(MFRC630_REG_DRVMOD+skip, buf+skip, sizeof(buf)-skip);
}
break;
case MFRC630_PROTO_ISO15693_1_OF_256_SSC:
{
const uint8_t buf[] = MFRC630_RECOM_15693_ID1_SSC52;
mfrc630_write_regs(MFRC630_REG_DRVMOD+skip, buf+skip, sizeof(buf)-skip);
}
break;
}
}
void mfrc630_AN1102_recommended_registers(uint8_t protocol) {
Expand Down Expand Up @@ -931,3 +950,149 @@ void mfrc630_MF_example_dump() {
MFRC630_PRINTF("No answer to REQA, no cards?\n");
}
}

void mfrc630_ISO15693_init(uint8_t protocol, uint8_t buf){
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sgtJohnny I think there's a bug here - buf should be a uint8_t* type. This also means that your implementation on line 972 mfrc630_AN1102_recommended_registers(buf); does not do what you expect it to.


// Configure Timers
mfrc630_write_reg(MFRC630_REG_T0CONTROL,0x98); //configure T0
mfrc630_write_reg(MFRC630_REG_T1CONTROL,0x92); //configure T1 and cascade it with T0
mfrc630_write_reg(MFRC630_REG_T2CONTROL,0x20); //Configure T2 for LFO Autotrimm
mfrc630_write_reg(MFRC630_REG_T2RELOADHI,0x03); //T2 reload value for LFO AutoTrimm
mfrc630_write_reg(MFRC630_REG_T2RELOADLO,0xFF); //T2 reload value high
mfrc630_write_reg(MFRC630_REG_T3CONTROL,0x00); //Configure T3 (for LPCD /Autotrimm)

//Configure FiFo
mfrc630_write_reg(MFRC630_REG_FIFOCONTROL,0x90); //Set Fifo-Size and Waterlevel
mfrc630_write_reg(MFRC630_REG_WATERLEVEL,0xFE); //Set Waterlevel

//Configure RXBITCTRL
mfrc630_write_reg(MFRC630_REG_RXBITCTRL,0x80); //Set RXBITCTLR register

//set the Protocol
mfrc630_AN1102_recommended_registers(buf); //Write buffered values

mfrc630_cmd_idle(); //Cancel any commands
mfrc630_flush_fifo(); //Flush Fifo
mfrc630_clear_irq0(); //Clear IRQ0
mfrc630_clear_irq1(); //Clear IRQ1

//Set Timers
mfrc630_write_reg(MFRC630_REG_T0RELOADHI,0x18); //T0 Reload Hi
mfrc630_write_reg(MFRC630_REG_T0RELOADLO,0x86); //T0 Reload Lo
mfrc630_write_reg(MFRC630_REG_T1RELOADHI,0x00); //T1 Reload Hi
mfrc630_write_reg(MFRC630_REG_T1RELOADLO,0x00); //T1 Reload Lo

// Write in FIFO "Load protocol" params(TxProtocol=Iso15693(0a), RxProtocol=Iso15693(0a),
mfrc630_write_reg(MFRC630_REG_FIFODATA,protocol);
mfrc630_write_reg(MFRC630_REG_FIFODATA,protocol);

mfrc630_write_reg(MFRC630_REG_IRQ0EN, MFRC630_IRQ0EN_IDLE_IRQEN); // Enable IRQ0 interrupt source
mfrc630_write_reg(MFRC630_REG_IRQ1EN, MFRC630_IRQ1EN_IRQ_PINEN); // Enable IRQ1 interrupt source
mfrc630_write_reg(MFRC630_REG_COMMAND,MFRC630_CMD_LOADPROTOCOL); // Execute Rc663 command: "Load protocol"

mfrc630_write_reg(MFRC630_REG_IRQ0EN, MFRC630_IRQ0EN_CLEAR); //Disable IRQ
mfrc630_write_reg(MFRC630_REG_IRQ1EN, MFRC630_IRQ1EN_CLEAR); //Disable IRQ

mfrc630_flush_fifo(); //Flush Fifo

//> Apply RegisterSet
mfrc630_write_reg(MFRC630_REG_TXCRCPRESET,0x7B);
mfrc630_write_reg(MFRC630_REG_RXCRCCON,0x7B);
mfrc630_write_reg(MFRC630_REG_TXDATANUM,0x08);
mfrc630_write_reg(MFRC630_REG_TXMODWIDTH,0x00);
mfrc630_write_reg(MFRC630_REG_TXSYM10BURSTLEN,0x00);
mfrc630_write_reg(MFRC630_REG_TXWAITCTRL,0x00);
mfrc630_write_reg(MFRC630_REG_FRAMECON,0x0F);
mfrc630_write_reg(MFRC630_REG_RXCTRL,0x02);
mfrc630_write_reg(MFRC630_REG_RXTHRESHOLD,0x4E);
mfrc630_write_reg(MFRC630_REG_RXANA,0x04);
mfrc630_write_reg(MFRC630_REG_RXWAIT,0x8C); // Set the RxWait register
mfrc630_write_reg(MFRC630_REG_TXWAITCTRL,0xC0);
mfrc630_write_reg(MFRC630_REG_TXWAITLO,0x00);

// Write Timer-0, Timer-1 reload values(high,low)
mfrc630_write_reg(MFRC630_REG_T0RELOADHI,0x18);
mfrc630_write_reg(MFRC630_REG_T0RELOADLO,0x86);
mfrc630_write_reg(MFRC630_REG_T1RELOADHI,0x00);
mfrc630_write_reg(MFRC630_REG_T1RELOADLO,0x00);
mfrc630_write_reg(MFRC630_REG_TXAMP,0x0A);
mfrc630_write_reg(MFRC630_REG_DRVMOD,0x81);
mfrc630_write_reg(MFRC630_REG_STATUS,0x00); // Disable MIFARE Crypto1
//Set Driver
}

uint16_t mfrc630_ISO15693_readTag(uint8_t* uid){

//Set timeout for Timer0/Timer1, set reload values
mfrc630_write_reg(MFRC630_REG_T0RELOADHI,0x24);
mfrc630_write_reg(MFRC630_REG_T0RELOADLO,0xEB);
mfrc630_write_reg(MFRC630_REG_T1RELOADHI,0x00);
mfrc630_write_reg(MFRC630_REG_T1RELOADLO,0x00);

mfrc630_cmd_idle(); //cancel any commands
mfrc630_flush_fifo(); //clear the fifo
mfrc630_clear_irq0(); //clear irq0
mfrc630_clear_irq1(); //clear irq1

//Prepare instruction to send to fifo
uint8_t instruction[4] ={
MFRC630_ISO15693_FLAGS, //set the flags,
MFRC630_ISO15693_INVENTORY, //set "Inventory Command"
MFRC630_ISO15693_BlANK, //set blank
MFRC630_ISO15693_BlANK //set blank
};

//Send instruction to reader
mfrc630_write_reg(MFRC630_REG_DRVMOD,0x89); //Field on
mfrc630_cmd_transceive(instruction,4);

// clear interrupts
mfrc630_clear_irq0(); //clear irq0
mfrc630_clear_irq1(); //clear irq1

// Enable IRQ0,IRQ1 interrupt sources
mfrc630_write_reg(MFRC630_REG_IRQ0EN, MFRC630_IRQ0EN_IDLE_IRQEN | MFRC630_IRQ0EN_TX_IRQEN);
mfrc630_write_reg(MFRC630_REG_IRQ1EN, MFRC630_IRQ1EN_IRQ_PINEN | MFRC630_IRQ1EN_TIMER1_IRQEN );

// block until transmission ending
uint8_t irq0_value = 0;
uint8_t irq1_value = 0;
uint32_t timeout= millis() ;
while (!((irq0_value & 0x08)== 0x08)) {
irq0_value = mfrc630_irq0();
if(millis()>(timeout+50)){
break;
}
}
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any chance you could change this timeout handling to use the internal timer? like how's done in mfrc630_iso14443a_WUPA_REQA? this file is independent of Arduino at the moment, and I'd like to keep it that way.
This function has both spaces and tables on a single line, please make it uniform and match the already existing indentations.


//Wait for timer1 underflow (irq1(0x02) or RxIrQ irq0(0x04;
irq0_value =0;
timeout= millis();
while ( ((irq1_value & 0x02) !=0x02) && ((irq0_value & 0x04) !=0x04)){
irq1_value = mfrc630_irq1();
irq0_value = mfrc630_irq0();
if(millis()>(timeout+50)){
break;
}
}

//Check for error
if((irq1_value & 0x02)){
return 0x00; //return error!
};

//disable IRQ0,IRQ1
mfrc630_write_reg(MFRC630_REG_IRQ0EN,MFRC630_IRQ0EN_CLEAR);
mfrc630_write_reg(MFRC630_REG_IRQ1EN,MFRC630_IRQ1EN_CLEAR);

//see if a uid was found:
uint16_t fifo_len = mfrc630_fifo_length();
if(fifo_len != MFRC630_ISO15693_UID_LENGTH){
return 0x00; //return error - invalid uid size!
}

//transfer UID to variable
mfrc630_read_fifo(uid,fifo_len);
return fifo_len; //return state - valid
}

32 changes: 32 additions & 0 deletions mfrc630.h
Original file line number Diff line number Diff line change
Expand Up @@ -692,6 +692,38 @@ uint8_t mfrc630_MF_write_block(uint8_t block_address, const uint8_t* source);
void mfrc630_MF_example_dump();
//! @}

// ---------------------------------------------------------------------------
// ISO15693
// ---------------------------------------------------------------------------
/*! \defgroup iso15693 ISO15693
\brief Functions to interact with ISO15693 RFID tags / cards.


Basic functionallity to read uid
@{
*/
/*! \Initializes the reader for iso15693

Set all registers to the desired value for ISO15693 reading

\param [in] the specified protocol number for ISO15693, there are differnt values for 1/4 SSC or DSC or 1/256 SSC.
The right protocol for the desired card standart must be used
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Spelling mistakes in difernt and standart.


\param [in] the buffer with register values according to the selected protocol, see mfrc630_AN1102_recommended_registers_skip for more information

*/
void mfrc630_ISO15693_init(uint8_t protocol, uint8_t buf);

/*! \Reads ISO15693 tag

Try to Read ISO15693 tag. The device will send the command flags and the inventory command and tries to get a response

\param [out] uid: The UID of the card will be stored into this array.
\return length of uid in bytes, returns zero in case of failure. ISO15693 should normally return 10 for 10bytes of uid in Fifo
*/
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we add some more documentation here? What does the returned value mean?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is much better, please add a space between 10 and bytes, other than that this is clear now. 👍

uint16_t mfrc630_ISO15693_readTag(uint8_t *uid);

//! @}


#ifdef __cplusplus
Expand Down
Loading