Merged in raiden00/nuttx_l0f0 (pull request #848)
Fixes for MFRC522 drivers/contactless/mfrc522.c: in mfrc522_read uid.sak must be different from 0x04 not as before from 0x00. SAK == 0x00 is a valid PICC type drivers/contactless/mfrc522.c: add interface to read MIFARE Ultralight data configs/nucleo-l073rz: add mfrc522 support Approved-by: Gregory Nutt <gnutt@nuttx.org>
This commit is contained in:
parent
0b3375cb78
commit
a234b909bc
@ -175,12 +175,18 @@
|
||||
#define GPIO_I2C1_SCL GPIO_I2C1_SCL_2 /* D15 - PB8 */
|
||||
#define GPIO_I2C1_SDA GPIO_I2C1_SDA_2 /* D14 - PB9 */
|
||||
|
||||
/* SPI */
|
||||
/* SPI1 */
|
||||
|
||||
#define GPIO_SPI1_MISO GPIO_SPI1_MISO_2 /* D12 - PA6 */
|
||||
#define GPIO_SPI1_MOSI GPIO_SPI1_MOSI_2 /* D11 - PA7 */
|
||||
#define GPIO_SPI1_SCK GPIO_SPI1_SCK_1 /* D13 - PA5 */
|
||||
|
||||
/* SPI2 */
|
||||
|
||||
#define GPIO_SPI2_MISO GPIO_SPI2_MISO_1 /* PB14 */
|
||||
#define GPIO_SPI2_MOSI GPIO_SPI2_MOSI_1 /* PB15 */
|
||||
#define GPIO_SPI2_SCK GPIO_SPI2_SCK_1 /* PB10 */
|
||||
|
||||
/* USART */
|
||||
|
||||
/* By default the USART2 is connected to STLINK Virtual COM Port:
|
||||
|
@ -64,4 +64,8 @@ ifeq ($(CONFIG_LPWAN_SX127X),y)
|
||||
CSRCS += stm32_sx127x.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_CL_MFRC522),y)
|
||||
CSRCS += stm32_mfrc522.c
|
||||
endif
|
||||
|
||||
include $(TOPDIR)/configs/Board.mk
|
||||
|
@ -111,6 +111,16 @@
|
||||
#define GPIO_SX127X_DIO0 (GPIO_INPUT | GPIO_FLOAT | GPIO_EXTI | \
|
||||
GPIO_PORTA | GPIO_PIN10)
|
||||
|
||||
/* MFRC522
|
||||
* CS - PB4
|
||||
* RESET - PB11
|
||||
*/
|
||||
|
||||
#define GPIO_MFRC522_CS (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_HIGH| \
|
||||
GPIO_OUTPUT_SET|GPIO_PORTB|GPIO_PIN4)
|
||||
#define GPIO_MFRC522_RESET (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_HIGH| \
|
||||
GPIO_OUTPUT_SET|GPIO_PORTB|GPIO_PIN11)
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
@ -119,7 +129,7 @@
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/************************************************************************************
|
||||
/*****************************************************************************
|
||||
* Name: stm32_bringup
|
||||
*
|
||||
* Description:
|
||||
@ -135,13 +145,13 @@
|
||||
|
||||
int stm32_bringup(void);
|
||||
|
||||
/************************************************************************************
|
||||
/*****************************************************************************
|
||||
* Name: stm32_spidev_initialize
|
||||
*
|
||||
* Description:
|
||||
* Called to configure SPI chip select GPIO pins for the Nucleo-H743ZI board.
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_STM32F0L0_SPI
|
||||
void stm32_spidev_initialize(void);
|
||||
@ -169,4 +179,16 @@ int stm32_wlinitialize(void);
|
||||
int stm32_lpwaninitialize(void);
|
||||
#endif
|
||||
|
||||
/*****************************************************************************
|
||||
* Name: stm32_mfrc522initialize
|
||||
*
|
||||
* Description:
|
||||
* Function used to initialize the MFRC522 RFID Transceiver
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_CL_MFRC522
|
||||
int stm32_mfrc522initialize(FAR const char *devpath);
|
||||
#endif
|
||||
|
||||
#endif /* __CONFIGS_NUCLEO_L073RZ_SRC_NUCLEO_L073RZ_H */
|
||||
|
@ -151,6 +151,14 @@ int stm32_bringup(void)
|
||||
}
|
||||
#endif /* CONFIG_LPWAN_SX127X */
|
||||
|
||||
#ifdef CONFIG_CL_MFRC522
|
||||
ret = stm32_mfrc522initialize("/dev/rfid0");
|
||||
if (ret < 0)
|
||||
{
|
||||
syslog(LOG_ERR, "ERROR: stm32_mfrc522initialize() failed: %d\n", ret);
|
||||
}
|
||||
#endif /* CONFIG_CL_MFRC522 */
|
||||
|
||||
UNUSED(ret);
|
||||
return OK;
|
||||
}
|
||||
|
110
configs/nucleo-l073rz/src/stm32_mfrc522.c
Normal file
110
configs/nucleo-l073rz/src/stm32_mfrc522.c
Normal file
@ -0,0 +1,110 @@
|
||||
/************************************************************************************
|
||||
* configs/nucleo-l073rz/src/stm32_mfrc522.c
|
||||
*
|
||||
* Copyright (C) 2019 Gregory Nutt. All rights reserved.
|
||||
* Author: Mateusz Szafoni <raiden00@railab.me>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
/************************************************************************************
|
||||
* Included Files
|
||||
************************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/spi/spi.h>
|
||||
#include <nuttx/contactless/mfrc522.h>
|
||||
|
||||
#include "stm32.h"
|
||||
#include "stm32_spi.h"
|
||||
#include "nucleo-l073rz.h"
|
||||
|
||||
#if defined(CONFIG_SPI) && defined(CONFIG_STM32F0L0_SPI2) && defined(CONFIG_CL_MFRC522)
|
||||
|
||||
/************************************************************************************
|
||||
* Pre-processor Definitions
|
||||
************************************************************************************/
|
||||
|
||||
#define MFRC522_SPI_PORTNO 2 /* On SPI2 */
|
||||
|
||||
/************************************************************************************
|
||||
* Public Functions
|
||||
************************************************************************************/
|
||||
|
||||
/************************************************************************************
|
||||
* Name: stm32_mfrc522initialize
|
||||
*
|
||||
* Description:
|
||||
* Initialize and register the MFRC522 RFID driver.
|
||||
*
|
||||
* Input Parameters:
|
||||
* devpath - The full path to the driver to register. E.g., "/dev/rfid0"
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) on success; a negated errno value on failure.
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
int stm32_mfrc522initialize(FAR const char *devpath)
|
||||
{
|
||||
FAR struct spi_dev_s *spi;
|
||||
int ret;
|
||||
|
||||
/* Configure MFRC522 reset */
|
||||
|
||||
stm32_configgpio(GPIO_MFRC522_RESET);
|
||||
|
||||
/* MFRC522 hardware reset on rising edge */
|
||||
|
||||
stm32_gpiowrite(GPIO_MFRC522_RESET, true);
|
||||
|
||||
/* Initialize SPI */
|
||||
|
||||
spi = stm32_spibus_initialize(MFRC522_SPI_PORTNO);
|
||||
if (!spi)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* Then register the MFRC522 */
|
||||
|
||||
ret = mfrc522_register(devpath, spi);
|
||||
if (ret < 0)
|
||||
{
|
||||
snerr("ERROR: Error registering MFRC522\n");
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_SPI && CONFIG_MFRC522 */
|
@ -113,6 +113,15 @@ void stm32_spidev_initialize(void)
|
||||
# endif
|
||||
|
||||
#endif /* CONFIG_STM32F0L0_SPI1 */
|
||||
|
||||
#ifdef CONFIG_STM32F0L0_SPI2
|
||||
/* Configure the SPI-based MFRC522 chip select GPIO */
|
||||
|
||||
# ifdef CONFIG_CL_MFRC522
|
||||
(void)stm32_configgpio(GPIO_MFRC522_CS);
|
||||
# endif
|
||||
|
||||
#endif /* CONFIG_STM32F0L0_SPI2 */
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -213,11 +222,42 @@ void stm32_spi2select(FAR struct spi_dev_s *dev, uint32_t devid,
|
||||
bool selected)
|
||||
{
|
||||
spiinfo("devid: %d CS: %s\n", (int)devid, selected ? "assert" : "de-assert");
|
||||
|
||||
switch (devid)
|
||||
{
|
||||
#ifdef CONFIG_CL_MFRC522
|
||||
case SPIDEV_CONTACTLESS(0):
|
||||
{
|
||||
stm32_gpiowrite(GPIO_MFRC522_CS, !selected);
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t stm32_spi2status(FAR struct spi_dev_s *dev, uint32_t devid)
|
||||
{
|
||||
return 0;
|
||||
uint8_t status = 0;
|
||||
|
||||
switch (devid)
|
||||
{
|
||||
#ifdef CONFIG_CL_MFRC522
|
||||
case SPIDEV_CONTACTLESS(0):
|
||||
{
|
||||
status |= SPI_STATUS_PRESENT;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
#endif /* CONFIG_STM32F0L0_SPI2 */
|
||||
|
||||
|
@ -772,7 +772,7 @@ int mfrc522_picc_select(FAR struct mfrc522_dev_s *dev,
|
||||
|
||||
/* The number of known UID bits in the current Cascade Level. */
|
||||
|
||||
uint8_t curr_level_known_bits;
|
||||
int8_t curr_level_known_bits;
|
||||
|
||||
/* The SELECT/ANTICOLLISION uses a 7 byte standard frame + 2 bytes CRC_A */
|
||||
|
||||
@ -1225,6 +1225,51 @@ void mfrc522_setantennagain(FAR struct mfrc522_dev_s *dev, uint8_t mask)
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mfrc522_mifare_read
|
||||
****************************************************************************/
|
||||
|
||||
int mfrc522_mifare_read(FAR struct mfrc522_dev_s *dev,
|
||||
FAR struct mifare_tag_data_s *data)
|
||||
{
|
||||
uint8_t buffer[18];
|
||||
uint8_t command[4];
|
||||
uint8_t length = 18;
|
||||
uint8_t validbits = 0;
|
||||
int ret = OK;
|
||||
|
||||
/* Read block from address */
|
||||
|
||||
command[0] = PICC_CMD_MF_READ;
|
||||
command[1] = data->address;
|
||||
|
||||
/* Get CRC */
|
||||
|
||||
ret = mfrc522_calc_crc(dev, command, 2, &command[2]);
|
||||
if (ret != OK)
|
||||
{
|
||||
goto errout;
|
||||
}
|
||||
|
||||
/* Send data and read response.
|
||||
* We read back 16 bytes block data nad 2 bytes CRC.
|
||||
*/
|
||||
|
||||
ret = mfrc522_transcv_data(dev, command, 4, buffer, &length,
|
||||
&validbits, 0, false);
|
||||
if (ret < 0)
|
||||
{
|
||||
goto errout;
|
||||
}
|
||||
|
||||
/* Copy block data */
|
||||
|
||||
memcpy(data->data, buffer, 16);
|
||||
|
||||
errout:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mfrc522_init
|
||||
*
|
||||
@ -1464,8 +1509,10 @@ static ssize_t mfrc522_read(FAR struct file *filep, FAR char *buffer,
|
||||
|
||||
mfrc522_picc_select(dev, &uid, 0);
|
||||
|
||||
if (uid.sak != 0)
|
||||
if (uid.sak != PICC_TYPE_NOT_COMPLETE)
|
||||
{
|
||||
/* TODO: double/triple UID */
|
||||
|
||||
if (buffer)
|
||||
{
|
||||
snprintf(buffer, buflen, "0x%02X%02X%02X%02X",
|
||||
@ -1517,29 +1564,59 @@ static int mfrc522_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
|
||||
|
||||
switch (cmd)
|
||||
{
|
||||
case MFRC522IOC_GET_PICC_UID:
|
||||
{
|
||||
struct picc_uid_s *uid = (struct picc_uid_s *)arg;
|
||||
case MFRC522IOC_GET_PICC_UID:
|
||||
{
|
||||
FAR struct picc_uid_s *uid = (FAR struct picc_uid_s *)arg;
|
||||
|
||||
/* Is a card near? */
|
||||
/* Is a card near? */
|
||||
|
||||
if (mfrc522_picc_detect(dev))
|
||||
{
|
||||
ret = mfrc522_picc_select(dev, uid, 0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
ret = mfrc522_picc_detect(dev);
|
||||
if (ret < 0)
|
||||
{
|
||||
goto errout;
|
||||
}
|
||||
|
||||
case MFRC522IOC_GET_STATE:
|
||||
ret = dev->state;
|
||||
break;
|
||||
/* Get UID and select card */
|
||||
|
||||
default:
|
||||
mfrc522err("ERROR: Unrecognized cmd: %d\n", cmd);
|
||||
ret = -ENOTTY;
|
||||
break;
|
||||
ret = mfrc522_picc_select(dev, uid, 0);
|
||||
if (ret < 0)
|
||||
{
|
||||
goto errout;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case CLIOC_READ_MIFARE_DATA:
|
||||
{
|
||||
FAR struct mifare_tag_data_s *data = (struct mifare_tag_data_s *)arg;
|
||||
|
||||
/* We assume that tag is selected!
|
||||
*
|
||||
* TODO: authentication for MIFARE Classic.
|
||||
* Without authentication this will works only for MIFARE Ultralight.
|
||||
*/
|
||||
|
||||
ret = mfrc522_mifare_read(dev, data);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case MFRC522IOC_GET_STATE:
|
||||
{
|
||||
ret = dev->state;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
mfrc522err("ERROR: Unrecognized cmd: %d\n", cmd);
|
||||
ret = -ENOTTY;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
errout:
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -64,10 +64,45 @@
|
||||
#define PN532IOC_READ_TAG_DATA _CLIOC(0x000a)
|
||||
#define PN532IOC_WRITE_TAG_DATA _CLIOC(0x000b)
|
||||
|
||||
/* Contactless common IOCTL Commands ****************************************/
|
||||
|
||||
#define CLIOC_READ_MIFARE_DATA _CLIOC(0x000c)
|
||||
#define CLIOC_WRITE_MIFARE_DATA _CLIOC(0x000d)
|
||||
|
||||
/****************************************************************************
|
||||
* Public Types
|
||||
****************************************************************************/
|
||||
|
||||
struct picc_uid_s
|
||||
{
|
||||
uint8_t size; /* Number of bytes in the UID. 4, 7 or 10 */
|
||||
uint8_t uid_data[10];
|
||||
uint8_t sak; /* The SAK (Select Acknowledge) return by the PICC */
|
||||
};
|
||||
|
||||
/* Coding of Select Acknowledge (SAK) according to:
|
||||
* http://www.nxp.com/documents/application_note/AN10833.pdf
|
||||
*/
|
||||
|
||||
enum picc_cardid_e
|
||||
{
|
||||
PICC_TYPE_NOT_COMPLETE = 0x04, /* UID not complete */
|
||||
PICC_TYPE_ISO_14443_4 = 0x20, /* PICC compliant with ISO/IEC 14443-4 */
|
||||
PICC_TYPE_ISO_18092 = 0x40, /* PICC compliant with ISO/IEC 18092 (NFC) */
|
||||
PICC_TYPE_MIFARE_MINI = 0x09,
|
||||
PICC_TYPE_MIFARE_1K = 0x08,
|
||||
PICC_TYPE_MIFARE_4K = 0x18,
|
||||
PICC_TYPE_MIFARE_UL = 0x00,
|
||||
PICC_TYPE_MIFARE_PLUS = 0x11,
|
||||
PICC_TYPE_TNP3XXX = 0x01
|
||||
};
|
||||
|
||||
struct mifare_tag_data_s
|
||||
{
|
||||
uint8_t data[16];
|
||||
uint8_t address;
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
@ -67,13 +67,6 @@ enum mfrc522_state_e
|
||||
|
||||
struct mfrc522_dev_s;
|
||||
|
||||
struct picc_uid_s
|
||||
{
|
||||
uint8_t size; /* Number of bytes in the UID. 4, 7 or 10 */
|
||||
uint8_t uid_data[10];
|
||||
uint8_t sak; /* The SAK (Select Acknowledge) return by the PICC */
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
Loading…
Reference in New Issue
Block a user