2014-02-05 8:35 AM
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 () 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 PA4SCK PA5MOSI PA6MISO PA7IRQ NCGND GNDRST 3.33.3 3.3I'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 nssGPIO_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 omittedI'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-quite2014-12-23 6:22 PM
This is axactly problem from my spi configuration.
I have fixed my proble but forgot thanking you.Thanks alot.2015-07-31 6:38 AM
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..2015-07-31 9:29 AM
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.2017-09-20 12:13 PM
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.
2023-10-12 4:59 AM
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
2023-10-12 5:26 AM
Here is a tutorial on how to use MFRC522 with STM32F446 Nucleo board. How can see it for help.
2025-03-12 9:54 PM
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.