Over 10 years we help companies reach their financial and branding goals. Engitech is a values-driven technology agency dedicated.

Gallery

Contacts

411 University St, Seattle, USA

engitech@oceanthemes.net

+1 -800-456-478-23

NFC/RFID Sensor/Module Interfacing Sensors and Modules Tech

Read and Write to a Rfid Tag

In the previous blogs we discussed how to read uid of different tags . Now as discussed in the applications of the rfid cards , the rfid tags can be used to store employee information so as to access certain restricted area. The rfid tags can also be used by retail stores to store customer information and points earned with each shopping. In this blog we’ll be learning how data reading or writing works by looking at the memory map of MIFARE 1K Tag and how to read and write the data using rc522.

UNDERSTANDING THE MEMORY MAP OF MIFARE 1K TAG

The memory of the MIFARE 1K Tag is divided into 15 sectors and each sector is divided into 4 blocks , within each block 16 bytes of data is stored 

Hence 16 Sectors * 4 Blocks * 16 Bytes=1024 Bytes = 1K 

The 0th Block of Sector 0 is used to store manufacturer data , this is usually 4 Byte UID(MIFARE 1K TAG, MIFARE Mini Tag) certain tags are available such as MIFARE Plus , MIFARE Desfire etc that has 7 Byte UID

There are 3 data blocks presents in each sector and the last block in each sector is known as sector trailer.The 3 data blocks are used to store user data and the trailer block is used to deter mine the access conditions for all the blocks of the sector . The access conditions include Read , Write , Increment , Decrement ,Transfer and Restore.

Each sector trailer consists of following information:-

FUNCTIONAL DESCRIPTION

This function takes in 2 arguments the address to which the data has to be written and the array or buffer in which data  is stored lets say this to be writedata array.

A 8 bit  array of 18 length is also intialized to store data which will be transferred to the memory block.

Intially CRC is checked using CalculateCRC function using which takes in 3 arguments array in ( whose first 2 values are PICC Write and blockAddress ), len and output array that stores 2 values CRCResultRegL , CRCResultRegM .

Next MFRC522_ToCard function is called which takes in 5 arguments command (in this case that will be PCD_Transceive), send data , send length , back length, back data according to various commands processing is done and according to switch cases status is sent

Finally  MFRC522_ToCard in again called (with  PCD_Transceive) and the data is transferred to the FIFODataReg to return with the correct status and finally the PCD is set to idle

This function is used to read data from a memory block and and put it into a buffer or array hence the argument recvData

Similar to uint8_t MFRC522_Write initially the CRC is calculated and MFRC522_ToCard  is called.

In MFRC522_ToCard the command argument is set to PCD_TRANSCEIVE due to which the code enter the for loop in which the data that was in FIFODataReg is populated in the recvData Buffer.

Finally  MFRC522_ToCard in again called (with  PCD_Transceive) and the data is transferred to the FIFODataReg to return with the correct status and finally the PCD is set to idle

This function is used to control the MFRC522 according to the command arguments that can be

  • PCD_AUTHENT
  • PCD_TRANSCEIVE

Both these commands have different irqEn ,waitIRq that are written into CommIEnReg block which is then cleared using clear bit mask function 

After finally setting bit mask the PCD is set to idle state

The function writes the data in FIFODataReg to the backData buffer and returns the status which is OK in case of no errors

STM32CUBE IDE CONFIGURATION

FIG 1- PINOUT CONFIGURATION

FIG 2 – CONFIGURING THE SPI1 PERIPHERAL

CODE

				
					#include "main.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "stdio.h"
#include "stm32f1_rc522.h"
#include "stdio.h"
#include "string.h"
#include "fonts.h"
#include "ssd1306.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 ---------------------------------------------------------*/
I2C_HandleTypeDef hi2c1;

SPI_HandleTypeDef hspi1;

UART_HandleTypeDef huart1;

/* USER CODE BEGIN PV */
void uprintf(char *str)
{
	HAL_UART_Transmit(&huart1,(uint8_t *)str,strlen(str),100);
}
//uint8_t i;
uint8_t status;
uint8_t str[5]; // Max_LEN = 16


uint8_t serNum[5];






uint8_t  KEY[] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
uint8_t  KEY2[]={1,2,3,4,5,6};

uint8_t W[]="PRATYUSH";/STEP 1/
uint8_t R[10]="";/STEP 2/
uint8_t test;


/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_SPI1_Init(void);
static void MX_USART1_UART_Init(void);
static void MX_I2C1_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();
  MX_USART1_UART_Init();
  MX_I2C1_Init();
  /* USER CODE BEGIN 2 */
  MFRC522_Init();
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */

  while (1)
  {

		status = MFRC522_Request(PICC_REQIDL, str);	//MFRC522_Request(0x26, str)
		status = MFRC522_Anticoll(str);
		memcpy(serNum, str, 5);


		HAL_Delay(1000);
		MFRC522_SelectTag(str);
		test =	MFRC522_Auth(PICC_AUTHENT1A,24,KEY,serNum);/STEP 3/

        MFRC522_Write((uint8_t)24 , W);/STEP 4/
        HAL_Delay(1000);
        MFRC522_Read(24, R);/STEP 5/
        HAL_Delay(1000);





		if (status == MI_OK)
				{

			MFRC522_SelectTag(str);
		    test =	MFRC522_Auth(PICC_AUTHENT1A,2,KEY,serNum);


/*if((str[0]==0) && (str[1]==0) && (str[2]==0) && (str[3]==0) && (str[4]==0) ){
	SSD1306_Init();
			        	 SSD1306_Clear();

}


if((str[0]==197) && (str[1]==32) && (str[2]==169) && (str[3]==67) && (str[4]==161) )
					{
	               status = MFRC522_Write((uint8_t)24 , W);
					}
else if((str[0]==165) && (str[1]==32) && (str[2]==253) && (str[3]==108) && (str[4]==7) ){
	status = MFRC522_Read( 24, R);
		         }

else{
		        	 SSD1306_Init();
		        	 SSD1306_Clear();

		         }*/




				}



  }

    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */

  /* USER CODE END 3 */
}

/**
  * @brief System Clock Configuration
   * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }

  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
  {
    Error_Handler();
  }
}

/**
  * @brief I2C1 Initialization Function
  * @param None
  * @retval None
  */
static void MX_I2C1_Init(void)
{

  /* USER CODE BEGIN I2C1_Init 0 */

  /* USER CODE END I2C1_Init 0 */

  /* USER CODE BEGIN I2C1_Init 1 */

  /* USER CODE END I2C1_Init 1 */
  hi2c1.Instance = I2C1;
  hi2c1.Init.ClockSpeed = 400000;
  hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;
  hi2c1.Init.OwnAddress1 = 0;
  hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
  hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
  hi2c1.Init.OwnAddress2 = 0;
  hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
  hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
  if (HAL_I2C_Init(&hi2c1) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN I2C1_Init 2 */

  /* USER CODE END I2C1_Init 2 */

}

/**
  * @brief SPI1 Initialization Function
  * @param None
  * @retval None
  */
static void MX_SPI1_Init(void)
{

  /* USER CODE BEGIN SPI1_Init 0 */

  /* USER CODE END SPI1_Init 0 */

  /* USER CODE BEGIN SPI1_Init 1 */

  /* USER CODE END SPI1_Init 1 */
  /* SPI1 parameter configuration*/
  hspi1.Instance = SPI1;
  hspi1.Init.Mode = SPI_MODE_MASTER;
  hspi1.Init.Direction = SPI_DIRECTION_2LINES;
  hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
  hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
  hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
  hspi1.Init.NSS = SPI_NSS_SOFT;
  hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8;
  hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
  hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
  hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
  hspi1.Init.CRCPolynomial = 10;
  if (HAL_SPI_Init(&hspi1) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN SPI1_Init 2 */

  /* USER CODE END SPI1_Init 2 */

}

/**
  * @brief USART1 Initialization Function
  * @param None
  * @retval None
  */
static void MX_USART1_UART_Init(void)
{

  /* USER CODE BEGIN USART1_Init 0 */

  /* USER CODE END USART1_Init 0 */

  /* USER CODE BEGIN USART1_Init 1 */

  /* USER CODE END USART1_Init 1 */
  huart1.Instance = USART1;
  huart1.Init.BaudRate = 115200;
  huart1.Init.WordLength = UART_WORDLENGTH_8B;
  huart1.Init.StopBits = UART_STOPBITS_1;
  huart1.Init.Parity = UART_PARITY_NONE;
  huart1.Init.Mode = UART_MODE_TX_RX;
  huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart1.Init.OverSampling = UART_OVERSAMPLING_16;
  if (HAL_UART_Init(&huart1) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN USART1_Init 2 */

  /* USER CODE END USART1_Init 2 */

}

/**
  * @brief GPIO Initialization Function
  * @param None
  * @retval None
  */
static void MX_GPIO_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
/* USER CODE BEGIN MX_GPIO_Init_1 */
/* USER CODE END MX_GPIO_Init_1 */

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOC_CLK_ENABLE();
  __HAL_RCC_GPIOD_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_GPIOB_CLK_ENABLE();

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET);

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET);

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_RESET);

  /*Configure GPIO pin : PC13 */
  GPIO_InitStruct.Pin = GPIO_PIN_13;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

  /*Configure GPIO pin : PA4 */
  GPIO_InitStruct.Pin = GPIO_PIN_4;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  /*Configure GPIO pin : PB0 */
  GPIO_InitStruct.Pin = GPIO_PIN_0;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

  /*Configure GPIO pins : PA11 PA12 */
  GPIO_InitStruct.Pin = GPIO_PIN_11|GPIO_PIN_12;
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

/* USER CODE BEGIN MX_GPIO_Init_2 */
/* USER CODE END MX_GPIO_Init_2 */
}

/* USER CODE BEGIN 4 */

/* USER CODE END 4 */

/**
  * @brief  This function is executed in case of error occurrence.
  * @retval None
  */
void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */

  /* USER CODE END Error_Handler_Debug */
}

#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t *file, uint32_t line)
{
  /* USER CODE BEGIN 6 */
  /* User can add his own implementation to report the file name and line number,
     tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

				
			

CODE EXPLAIN

We are declaring a buffer that is to be written in the desired memory block , the data that is to be written is also declared.

The buffer that will store the read data from the memory block after being written by MFRC522_Write function

In this step using the authorize function once the rfid tag is authorised the data is written to the desired memory block

In this block using the MFRC522_Write function the data is written to 24 memory block the data written is in the W array and is the second argument

In this step the data is read using MFRC522_Read function and is written back to the R buffer

Author

Kunal

Leave a comment

Stay Updated With Us

Error: Contact form not found.

    Blog