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
16 REPLIES 16
chuanut4
Associate II
Posted on December 24, 2014 at 03:22

This is axactly problem from my spi configuration.

I have fixed my proble but forgot thanking you.

Thanks alot.

djtilava
Associate II
Posted on July 31, 2015 at 15:38

Hello

shiftybits,

Have You got any solutions to your problem??

If you got then plz help me because i have same problem as you have.

I am using STM32F0308Discovery kit..

Posted on July 31, 2015 at 18:29

Two posts from over a year ago, on a different board/processor, kind of grasping at straws there.

I for one wouldn't attach the RST pin to the rail.

Suggest you formulate your question around what you actually have in terms of connectivity, and software configuration. And then what behaviour and testing you have observed and done.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on September 20, 2017 at 21:13

Hello.

First. I have tested one python script with one raspberry and the MFRC522 works fine. It detects UID, it does SelectTag process as ok, it does Authentication process and It reads sector. All rights

https://github.com/mxgxw/MFRC522-python/blob/master/MFRC522.py

 

I have started to have problem when I have migrated this code to STM32F030CC microcontroller. Migrating code was easy. Only SPI process was a little more complicated. Finally I did two versions: one version by simulating MISO, MOSI, SCK and CS with GPIO and another one using SPI1. MISO, MOSI, SCK with SPI1 and CS manually with GPIO.

With these two versions I can read any register from MFRC522, I can detect card and get UID serial number, problem is that output for SelectTAG process is MI_NOTAGERR instead MI_OK, and process for Authentication process is MI_ERR instead MI_OK. First process for detect card  requires to send to FIFO_DATA_REGISTER into MFRC522 only 1 byte, for getting UID serial requires to send to FIFO_DATA_REGISTER 2 bytes. For rest of process the number of bytes are more than 2 bytes (9 or more). 

Someone has worked with this, and knows the problem?

Best regards!

Francis.

MINT
Associate

I am facing the same issue with the STM32L476RG controller i have configured the SPI but i am still not getting any response from RC522 module can anyone help me out what can be the exact issue,

I have converted the Arduino method into STM32L476 and replicated the steps,

i am getting output on Arduino but not on STM32L476.

Thankyou in advance,

MINT

liaifat85
Senior III

Here is a tutorial on how to use MFRC522 with STM32F446 Nucleo board. How can see it for help.

https://blog.embeddedexpert.io/?p=768

siddhant5100
Associate

I am facing the same issue of my STM32F407-DISC1 is not being able to communicate with MFRC522. I am using the libraries with apt hardware connections and config.  connections are as

SDA = PA4

SCK = pa5

MISO = PA6

MOSI = PA7

RST = PA3

3v3 = 3v

GND = GND 

configs are = RCC = highspeed crys osc

PS = 8

Hardware NSS = disabled

data size 8 bits

first bit = MSB first , cpol = low, cpha = 1Edge,  NSS signal type = software.

#include "main.h"

 

/* Private includes ----------------------------------------------------------*/

/* USER CODE BEGIN Includes */

#include "RC522.h"

#include "string.h"

#include "string.h"

/* USER CODE END Includes */

 

/* Private typedef -----------------------------------------------------------*/

/* USER CODE BEGIN PTD */

 

/* USER CODE END PTD */

 

/* Private define ------------------------------------------------------------*/

/* USER CODE BEGIN PD */

 

/* USER CODE END PD */

 

/* Private macro -------------------------------------------------------------*/

/* USER CODE BEGIN PM */

 

/* USER CODE END PM */

 

/* Private variables ---------------------------------------------------------*/

SPI_HandleTypeDef hspi1;

 

/* USER CODE BEGIN PV */

uint8_t status;

uint8_t str[16];

uint8_t sNum[5];

 

uint8_t spiStatus;

uint8_t version;

/* USER CODE END PV */

 

/* Private function prototypes -----------------------------------------------*/

void SystemClock_Config(void);

static void MX_GPIO_Init(void);

static void MX_SPI1_Init(void);

/* USER CODE BEGIN PFP */

 

/* USER CODE END PFP */

 

/* Private user code ---------------------------------------------------------*/

/* USER CODE BEGIN 0 */

 

/* USER CODE END 0 */

 

/**

* @brief The application entry point.

* @retval int

*/

int main(void)

{

 

/* USER CODE BEGIN 1 */

 

/* USER CODE END 1 */

 

/* MCU Configuration--------------------------------------------------------*/

 

/* Reset of all peripherals, Initializes the Flash interface and the Systick. */

HAL_Init();

 

/* USER CODE BEGIN Init */

 

/* USER CODE END Init */

 

/* Configure the system clock */

SystemClock_Config();

 

/* USER CODE BEGIN SysInit */

 

/* USER CODE END SysInit */

 

/* Initialize all configured peripherals */

MX_GPIO_Init();

MX_SPI1_Init();

/* USER CODE BEGIN 2 */

MFRC522_Init();

/* USER CODE END 2 */

 

/* Infinite loop */

/* USER CODE BEGIN WHILE */

while (1)

{

/* USER CODE END WHILE */

 

/* USER CODE BEGIN 3 */

 

 

status = MFRC522_Request(PICC_REQIDL, str);

status = MFRC522_Anticoll(str);

memcpy(sNum,str,5);

HAL_Delay(500);

}

/* USER CODE END 3 */

}


I am always recieving 2 in the status variable that means communication error. why is it so? i have tried debugging the error register of rc522 shows up FF also when i read from rc522 Read_MFRC522(CommIEnReg); = 255.

/*

* Function Name: MFRC522_ToCard

* Description: RC522 and ISO14443 card communication

* Input Parameters: command - MF522 command word,

* sendData--RC522 sent to the card by the data

* sendLen--Length of data sent

* backData--Received the card returns data,

* backLen--Return data bit length

* Return value: the successful return MI_OK

*/

uchar MFRC522_ToCard(uchar command, uchar *sendData, uchar sendLen, uchar *backData, uint *backLen)

{

uchar status = MI_ERR;

uchar irqEn = 0x00;

uchar waitIRq = 0x00;

uchar lastBits;

 

uchar n;

uint i;

 

switch (command)

{

case PCD_AUTHENT: // Certification cards close

{

irqEn = 0x12;

waitIRq = 0x10;

break;

}

case PCD_TRANSCEIVE: // Transmit FIFO data

{

irqEn = 0x77;

waitIRq = 0x30;

break;

}

default:

break;

}

 

Write_MFRC522(CommIEnReg, irqEn|0x80); // Interrupt request

ClearBitMask(CommIrqReg, 0x80); // Clear all interrupt request bit

SetBitMask(FIFOLevelReg, 0x80); // FlushBuffer=1, FIFO Initialization

 

Write_MFRC522(CommandReg, PCD_IDLE); // NO action; Cancel the current command

 

// Writing data to the FIFO

for (i=0; i<sendLen; i++)

{

Write_MFRC522(FIFODataReg, sendData[i]);

}

 

// Execute the command

Write_MFRC522(CommandReg, command);

if (command == PCD_TRANSCEIVE)

{

SetBitMask(BitFramingReg, 0x80); // StartSend=1,transmission of data starts

}

 

// Waiting to receive data to complete

i = 2000; // i according to the clock frequency adjustment, the operator M1 card maximum waiting time 25ms

do

{

//CommIrqReg[7..0]

//Set1 TxIRq RxIRq IdleIRq HiAlerIRq LoAlertIRq ErrIRq TimerIRq

n = Read_MFRC522(CommIrqReg);

i--;

}

while ((i!=0) && !(n&0x01) && !(n&waitIRq));

 

ClearBitMask(BitFramingReg, 0x80); //StartSend=0

 

if (i != 0)

{

if(!(Read_MFRC522(ErrorReg) & 0x1B)) //BufferOvfl Collerr CRCErr ProtecolErr

{

status = MI_OK;

if (n & irqEn & 0x01)

{

status = MI_NOTAGERR;

}

 

if (command == PCD_TRANSCEIVE)

{

n = Read_MFRC522(FIFOLevelReg);

lastBits = Read_MFRC522(ControlReg) & 0x07;

if (lastBits)

{

*backLen = (n-1)*8 + lastBits;

}

else

{

*backLen = n*8;

}

 

if (n == 0)

{

n = 1;

}

if (n > MAX_LEN)

{

n = MAX_LEN;

}

 

// Reading the received data in FIFO

for (i=0; i<n; i++)

{

backData[i] = Read_MFRC522(FIFODataReg);

}

}

}

else

{

status = MI_ERR;

}

 

}

 

//SetBitMask(ControlReg,0x80); //timer stops

//Write_MFRC522(CommandReg, PCD_IDLE);

 

return status;

}

in this function after reading the error register it returns error. 

i have spent a lot of time on this. Also i am new to this platform. Please help with effective solution.