# Can't get MFRC522 (RFID) to work with PIC18F452 and SPI bus

Status
Not open for further replies.

#### vv7

##### New Member
I don't know where to ask but I was wondering if someone here has worked with it and could give some idea. Hope so.

A module ( MFRC522 ):

Schematic:

An MCU ( PIC18F452 ) is powered with 5V, module is powered from 5V(DC) -> 3.3V(DC) converter and all logic pins ( SS(SDA), SCK, MOSI, MISO and RST ) are connected using voltage dividers ( 3K and 1K6 resistors were used ( because
) ).

---------------------------------------------------------------

We know that I2C and EA pins of RC522 chip should be connected to 0 and 1 respectively to enable SPI interface mode for MFRC522 module as in datasheet is written (Table 5):

I've checked with multi-meter and I2C is shorted to GND and EA is shorted to 3.3V so SPI mode should be ON, isn't it?

---------------------------------------------------------------

Here's some code which should initiate an MFRC522 module and print a module's version on LCD:

Code:
// configuration and LCD libraries
... ( LCD works properly )
...

// RFID MFRC522 pins
#define rf_ss  LATAbits.LA0
#define rf_sck  LATAbits.LA1
#define rf_mosi LATAbits.LA2
#define rf_rst  LATAbits.LA3
#define rf_miso PORTAbits.RA5 // input

// A custom function to send data to SPI bus
unsigned char SPI_WB( unsigned char d ) {
__delay_us( 500 );
unsigned char r = 0; // to get a MISO values
for ( unsigned char i = 0; i < 8; i++ ) {
rf_mosi = ( d >> i ) & 0x01;
__delay_us( 100 );
rf_sck = 1;
__delay_us( 100 );
r = ( ( rf_miso << i ) | r );
__delay_us( 100 );
rf_sck = 0;
__delay_us( 1000 );
}
__delay_us( 100 );
return r;
}

// A custom function to write data to register
void SPI_WR( unsigned char a, unsigned char v ) {
rf_ss = 0;
SPI_WB( ( a << 1 ) & 0x7E ); // Address format: 0XXXXXX0
SPI_WB( v );
rf_ss = 1;
}

unsigned char SPI_RR( unsigned char a ) {
rf_ss = 0;
SPI_WB( ( ( a << 1 ) & 0x7E ) | 0x80 );
rf_ss = 1;
return SPI_WB( 0x00 );
}

#define MFRC522_CR 0x01 // Command register
#define MFRC522_SR 0x0F // MFRC522 Soft Reset command
#define MFRC522_V 0x37 // MFRC522 Version register

void main( ) {
rf_ss = 1;
__delay_us( 1000 );
SPI_WR( CommandReg, MFRC522_SR ); // A result of logic picture is below
unsigned char str;
sprintf( str, "Version: 0x%x", SPI_RR( MFRC522_V ) ); LCD_W( str ); // Unfortunately returns "Version: 0x0"
while( 1 ) { }
}
...
---------------------------------------------------------------

Logic ( SS( SDA), SCK and MOSI pins at the start of MCU ):

Full Logic ( SCK, MOSI and MISO pins at the start of MCU ):

or (with immediate MOSI zero, to easier view)

---------------------------------------------------------------

As you could see, there's no answer from module:

---------------------------------------------------------------

Yes, PIC18F452 has special pins for SPI protocol (PORTC), but, unfortunately, I can't use these in this project.

All in all, no return from MFRC522_V register ( At the end an LCD is populated by " Version: 0x0" ).

Is a logic and communication itself right?

---------------------------------------------------------------

Edit 1:

I've seen an interesting picture in MFRC522 datasheet:

Does it show that byte should be sent from left to right rather than I've sent from right to left? For example, 0x63 should be sent as [ 0,1,1,0,0,0,1,1 ] rather than [ 1,1,0,0,0,1,1,0 ], is it?

In case that I've changed function **SPI_WB** to be:

Code:
unsigned char SPI_WB( unsigned char d ) {
__delay_us( 500 );
unsigned char r = 0;
//  for ( unsigned char i = 0; i < 8; i++ ) {
for ( unsigned char i = 8; i > 0; i-- ) {
//  rf_mosi = ( d >> i ) & 0x01;
rf_mosi = ( d >> ( i - 1 ) ) & 0x01;
__delay_us( 100 );
rf_sck = 1;
__delay_us( 100 );
//  r = ( ( rf_miso << i ) | r );
r = ( ( rf_miso << ( i - 1 ) ) | r );
__delay_us( 100 );
rf_sck = 0;
//  rf_mosi = 0; // immediate zero
__delay_us( 1000 );
}
__delay_us( 100 );
return r;
}
And the result in analyzer looks like:

and with "immediate zero":

---------------------------------------------------------------

As you could see, ... unfortunately, there's no result on MISO pin.

1. Do you have any idea why MISO doesn't have any data?
2. Is it okay to use bit banged SPI and if so, does speed depend then (will it work with custom delays)?
3. Is really set to SPI mode?
4. Is it possible to get MFRC522 firmware version by reading version's register at power on only (without module initializing) and if no, then which are significant for initialize?

---------------------------------------------------------------

Thank you very much for your help, really!

#### atferrari

##### Well-Known Member
Something I always do prior starting with a new micro is checking the erratas for my silicon version in use.

Saved some grief thanks to that.

#### dr pepper

##### Well-Known Member
Do you know for sure that the resistor level shifter you have shown will work bi directional?
Also you have sda connected, in standard spi you wouldnt need this connected as its i2c.

#### vv7

##### New Member
Do you know for sure that the resistor level shifter you have shown will work bi directional?
Also you have sda connected, in standard spi you wouldnt need this connected as its i2c.
Thank you! This module uses SPI protocol, so there's no need for bi-directional converter, also SDA -> SS in SPI. As you could see above ( I've checked with multi-meter and I2C is shorted to GND and EA is shorted to 3.3V so SPI mode should be ON, isn't it? ):

#### dr pepper

##### Well-Known Member
Looks like you have a tricky one.

#### vv7

##### New Member

So, a troublemaker was a DC-DC Converter MP1584EN which was used as power for RC522 ( 5V to 3.3 ):

It was probably too noisy for RC522.
Thank you very much for trying.

Best regards

Status
Not open for further replies.