cancel
Showing results for 
Search instead for 
Did you mean: 

help with spi setup with rc522 module

gecono
Associate
Posted on February 05, 2014 at 17:35

Hi-

I'm quite new to stm32 and emededded development so please bear with me.

I've purchased a Sain Smart RC522 RFID reader/writer (

https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&cad=rja&ved=0CDwQFjAA&url=http://www.nxp.com/documents/data_sheet/MFRC522.pdf&ei=uVfyUqd3i7SxBJ-zgfAI&usg=AFQjCNGIP5OuVPk-sObD-ZpLGioCFvUUMg&sig2=g_vdTzuL3Vd5VZbUoqXFnw&bvm=bv.60799247%2cd.cWc

) which has a MFRC522 chip. The chip supports uart, spi and i2c and auto configures by sensing the logic levels on the control pins after a reset as described in the datasheet section 8.1.1. 

After reading through the datasheet i'm attempting to hook it up to my ST-Discovery F4 board using SPI1 as follows:

RC522   STM32F4

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

SDA      PA4

SCK      PA5

MOSI     PA6

MISO     PA7

IRQ      NC

GND      GND

RST      3.3

3.3      3.3

I'm having difficulty figuring out the values to use when initializing SPI1 from the datasheet. Currently I have the following :

GPIO_InitTypeDef GPIO_InitStruct;

SPI_InitTypeDef SPI_InitStruct;

/* configure pins used by SPI1

 * PA5 = SCK

 * PA6 = MISO

 * PA7 = MOSI

 */

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);

GPIO_InitStruct.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;

GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;

GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;

GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;

GPIO_Init(GPIOA, &GPIO_InitStruct);

GPIO_PinAFConfig(GPIOA, GPIO_PinSource5, GPIO_AF_SPI1);

GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_SPI1);

GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_SPI1);

// SPI1 nss

GPIO_InitStruct.GPIO_Pin = GPIO_Pin_4;

GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_InitStruct.GPIO_Mode = GPIO_OType_PP;

GPIO_Init(GPIOA, &GPIO_InitStruct);

RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);

SPI_Cmd(SPI1, DISABLE);

SPI_InitStruct.SPI_Direction = SPI_Direction_2Lines_FullDuplex;

SPI_InitStruct.SPI_Mode = SPI_Mode_Master;

SPI_InitStruct.SPI_DataSize = SPI_DataSize_8b;

SPI_InitStruct.SPI_CPOL = SPI_CPOL_Low;

SPI_InitStruct.SPI_CPHA = SPI_CPHA_1Edge;

SPI_InitStruct.SPI_NSS = SPI_NSS_Soft;

SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_32;

SPI_InitStruct.SPI_FirstBit = SPI_FirstBit_MSB;

SPI_InitStruct.SPI_CRCPolynomial=7;

SPI_Init(SPI1,&SPI_InitStruct);

SPI_SSOutputCmd(SPI1, ENABLE);

SPI_Cmd(SPI1,ENABLE); 

// initialzation of RC522 omitted

I've also have functions that reads and write to rc522 register:

uint8_t rfid_readWriteByte(uint8_t data){

    while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);

    SPI_I2S_SendData(SPI1,data);

    while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);

    return SPI_I2S_ReceiveData(SPI1);

}

uint8_t rfid_readFromRegister(uint8_t addr) {

  SPI_NSSInternalSoftwareConfig(SPI1,SPI_NSSInternalSoft_Set);

  rfid_readWriteByte(((addr<<1)&0x7E) | 0x80);

  uint8_t val = rfid_readWriteByte(0x00);

  SPI_NSSInternalSoftwareConfig(SPI1,SPI_NSSInternalSoft_Reset);

  return val;

}

I've put together a simple program that initializes the spi interface and attempts to read the firmware version from RC522 register using the code above. The  register read always comes back as 0XFF. 

I'm trying to narrow done where the problem is by looking at the initialzation of the RC522 first and how it is hooked up. Does anyone see anything wrong with my initialization routine and basic read/write methods?

#metoo-not-quite
15 REPLIES 15
chen
Associate II
Posted on February 07, 2014 at 18:25

Hi

Welcome.

I have not looked at your code.

I have some questions :

Is the code trying to communicate with the Sain Smart RC522 RFID reader/writer immediately in the main loop?

Are you testing be power the Sain Smart RC522 RFID reader/writer through the Discovery board and powering the discovery board expecting it to work?

If so, Try putting in a large delay (50ms or more) into the start before you start to communicate.

You need to allow some time for the power to settle and for both devices to come out of reset.

gecono
Associate
Posted on February 24, 2014 at 00:02

Thanks for reply. I tried adding the delay as suggested but I'm still having troubles.

I've just gotten back to this project, and ported it to my STMF429I discovery board so I could use lcd for diagnostic display. I've been porting a rc522 library that works on arduino (code can be found

https://github.com/miguelbalboa/rfid

). I've verified that the library and reader work with an arduino. I have a feeling it is with my initialization code.

#include ''main.h''
#include ''rc5h''
#define CS_PORT GPIOC
#define CS_PIN GPIO_Pin_5
#define RESET_PORT GPIOC
#define RESET_PIN GPIO_Pin_4
/**
* Configure pins used by SPI1
* PA5 = SCK
* PA6 = MISO
* PA7 = MOSI
* PC4 = RESET
* PC5 = SDA
*/
void rc522_init()
{
// spi1 gpio init
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource5, GPIO_AF_SPI1);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_SPI1);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_SPI1);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
GPIO_InitStruct.GPIO_Pin = RESET_PIN|CS_PIN;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOC, &GPIO_InitStruct);
GPIO_SetBits(CS_PORT, CS_PIN);
GPIO_ResetBits(RESET_PORT, RESET_PIN);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
SPI_I2S_DeInit(SPI1);
SPI_InitTypeDef SPI_InitStruct;
SPI_InitStruct.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI_InitStruct.SPI_Mode = SPI_Mode_Master;
SPI_InitStruct.SPI_DataSize = SPI_DataSize_8b;
SPI_InitStruct.SPI_CPOL = SPI_CPOL_Low;
SPI_InitStruct.SPI_CPHA = SPI_CPHA_1Edge;
SPI_InitStruct.SPI_NSS = SPI_NSS_Soft;
SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16;
SPI_InitStruct.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStruct.SPI_CRCPolynomial=7;
SPI_Init(SPI1,&SPI_InitStruct);
SPI_Cmd(SPI1,ENABLE);
}
void rc522_start()
{
// is the MFRC522 chip is in power down mode?
if (GPIO_ReadOutputDataBit(RESET_PORT, RESET_PIN) == 0)
{
logmsg( (uint8_t*)''detected power down mode'');
GPIO_SetBits(RESET_PORT, RESET_PIN);
delay(100);
}
else
{
rc522_reset();
}
rc522_writeToRegister(TModeReg, 0x80); // TAuto=1; timer starts automatically at the end of the transmission in all communication modes at all speeds
rc522_writeToRegister(TPrescalerReg, 0xA9); // TPreScaler = TModeReg[3..0]:TPrescalerReg, ie 0x0A9 = 169 => f_timer=40kHz, ie a timer period of 25�s.
rc522_writeToRegister(TReloadRegH, 0x03); // Reload timer with 0x3E8 = 1000, ie 25ms before timeout.
rc522_writeToRegister(TReloadRegL, 0xE8);
rc522_writeToRegister(TxAutoReg, 0x40); // 100%ASK
rc522_writeToRegister(ModeReg, 0x3D); // CRC initial value 0x6363
rc522_antennaOn();
}

The RC522 datasheet says the SPI interface supports 10Mbits/s. The working arduino library configures the data mode to Mode0 so I think I configured CPOL and CPHA correctly. I do have question about the chip select. The rc522 datasheet says it should be hooked up to nss. However, the arduino library I am porting treats the pin as a normal chip select and it does work fine on arduino. Based on how I configure the pupd of the SPI pins, I either get 0 or 255 when I do read. Any pointers on how to troubleshoot?
chen
Associate II
Posted on February 24, 2014 at 15:55

Hi

''I do have question about the chip select. The rc522 datasheet says it should be hooked up to nss. However, the arduino library I am porting treats the pin as a normal chip select and it does work fine on arduino.''

nss - means 'negative slave select' - the Slave select is active low (high normally, goes low when talking to the device).

''The working arduino library configures the data mode to Mode0 so I think I configured  CPOL and CPHA correctly.  ''

''Any pointers on how to troubleshoot?''

If you can - use a oscilloscope or logic analyser to compare the working Arduino SPI waveforms to the STM32.

CPOL and CPHA are the 2 different ways to have the clock timing :

http://en.wikipedia.org/wiki/SPI_bus

It can only be one or the other!

Some devices are very sensitive to the clock timing, some are not.

tranvanduy
Associate II
Posted on June 02, 2014 at 18:18

Hi all, I make RFID RC522 module using RC522 on stm32f4 Discovery board.

Thanks all!

laszbuis
Associate
Posted on July 06, 2014 at 21:02

Hey there.

I have been trying to get the RC522 to work with my stm32f4 discovery board for a while now to no avail. I am getting the same error that you have. Have you perhaps found a solution to this problem yet? And if so, would you please let me know how you solved it.

Thanks in advance 

chuanut4
Associate II
Posted on August 29, 2014 at 12:43

Im trying to comunicate with RC522 by my stm32f103RC. But when i try to use SPI_send_data, I'm stuck in while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_TXE)== RESET); loop

As usally, I still use this loop to check flag when communicate by SPI protocol with nRF24L01. But I dont know why, it doesnt work here.

Please explain it if you know!

Thanks

Posted on August 29, 2014 at 13:48

Please explain it if you know!

Not much to work with here. Sounds like you might have forgotten to enable the peripheral clock.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
chuanut4
Associate II
Posted on September 04, 2014 at 13:11

Thank you very much!

I'm already fix it as you say. My SPI has worked.

But I always get value of 0 when I try to read any Register on RC522. And I can't read any data from this module. I already put delay before and after send data through SPI to RC522.

If any one know about it, please let me know how to work with RC522 by SPI communication.

Thanks so much!

Andrew Neil
Evangelist
Posted on September 08, 2014 at 11:27

My SPI has worked.

How did you verify that?

But I always get value of 0 when I try to read any Register on RC522.

So have you verified that you're getting the correct signals & timing on the actual SPI connections - using an oscilloscope, logic analyser, or whatever?