Maker Pro
Maker Pro

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

vv7

Jul 20, 2018
2
Joined
Jul 20, 2018
Messages
2
Dear Arduino,

I don't know where to ask so, I'll try to ask here because MFRC522 module is arduino related (maybe) so might be that someone who worked with it could give some idea. Hope so.

A module ( MFRC522 ):

F4Cgm.png


Schematic:

8Sj7s.png


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
omW2Ghh.png
) ).

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

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):

ZyixM.png


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?

p9EMy.jpg


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

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 ):

yHWrz.png


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

hTxWu.png


or (with immediate MOSI zero, to easier view)

dMcLw.png


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

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

CSHlE.png


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

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:

mUHcr.png


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:

H3uX9.png


and with "immediate zero":

wmt8g.png


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

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!
 

kellys_eye

Jun 25, 2010
6,514
Joined
Jun 25, 2010
Messages
6,514
The data line is bi-directional. How well does your 'voltage divider' method work when the input to the divider is 'coming from the other direction'?
 

vv7

Jul 20, 2018
2
Joined
Jul 20, 2018
Messages
2
Sorry for a late reply.

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

EB7dOUu.jpg


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

Best regards
 
Top