#include "mfrc522.h" #include "driver/gpio.h" #include "esp_log.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include #include static const char *TAG = "MFRC522"; #define SPI_MASTER_FREQ_HZ 1000000 // 1MHz mfrc522_handle_t* mfrc522_init(int sck_pin, int mosi_pin, int miso_pin, int cs_pin, int rst_pin) { mfrc522_handle_t *handle = (mfrc522_handle_t *)malloc(sizeof(mfrc522_handle_t)); if (!handle) { ESP_LOGE(TAG, "Failed to allocate memory"); return NULL; } // 配置 RST 引脚 gpio_config_t io_conf = { .pin_bit_mask = (1ULL << rst_pin), .mode = GPIO_MODE_OUTPUT, .pull_up_en = GPIO_PULLUP_DISABLE, .pull_down_en = GPIO_PULLDOWN_DISABLE, .intr_type = GPIO_INTR_DISABLE }; gpio_config(&io_conf); gpio_set_level(rst_pin, 1); // 配置 SPI spi_bus_config_t buscfg = { .miso_io_num = miso_pin, .mosi_io_num = mosi_pin, .sclk_io_num = sck_pin, .quadwp_io_num = -1, .quadhd_io_num = -1, .max_transfer_sz = 4096, }; spi_device_interface_config_t devcfg = { .mode = 0, .clock_speed_hz = SPI_MASTER_FREQ_HZ, .spics_io_num = cs_pin, .queue_size = 7, }; esp_err_t ret = spi_bus_initialize(HSPI_HOST, &buscfg, SPI_DMA_CH_AUTO); if (ret != ESP_OK) { ESP_LOGE(TAG, "Failed to initialize SPI bus"); free(handle); return NULL; } ret = spi_bus_add_device(HSPI_HOST, &devcfg, &handle->spi); if (ret != ESP_OK) { ESP_LOGE(TAG, "Failed to add SPI device"); free(handle); return NULL; } handle->uid_len = 0; memset(handle->uid, 0, sizeof(handle->uid)); // 复位 MFRC522 mfrc522_reset(handle); ESP_LOGI(TAG, "MFRC522 initialized successfully"); return handle; } void mfrc522_reset(mfrc522_handle_t *handle) { mfrc522_write_reg(handle, MFRC522_REG_COMMAND, MFRC522_CMD_RESETPHASE); vTaskDelay(pdMS_TO_TICKS(50)); // 初始化寄存器 mfrc522_write_reg(handle, MFRC522_REG_MODE, 0x3D); // CRC初始值 mfrc522_write_reg(handle, MFRC522_REG_TX_CONTROL, 0x83); // 打开TX1和TX2输出 mfrc522_write_reg(handle, MFRC522_REG_TX_AUTO, 0x40); // 自动 RF 开启 mfrc522_write_reg(handle, MFRC522_REG_COMMAND, MFRC522_CMD_IDLE); } void mfrc522_write_reg(mfrc522_handle_t *handle, uint8_t reg, uint8_t val) { uint8_t tx_data[2]; tx_data[0] = ((reg << 1) & 0x7E) | 0x00; // 写操作 tx_data[1] = val; spi_transaction_t t = { .length = 16, .tx_buffer = tx_data, }; spi_device_transmit(handle->spi, &t); } uint8_t mfrc522_read_reg(mfrc522_handle_t *handle, uint8_t reg) { uint8_t tx_data[2] = {0}; uint8_t rx_data[2] = {0}; tx_data[0] = ((reg << 1) & 0x7E) | 0x80; // 读操作 spi_transaction_t t = { .length = 16, .tx_buffer = tx_data, .rx_buffer = rx_data, }; spi_device_transmit(handle->spi, &t); return rx_data[1]; } uint8_t mfrc522_picc_is_new(mfrc522_handle_t *handle) { uint8_t status = mfrc522_read_reg(handle, MFRC522_REG_STATUS1); return (status & 0x01); // 检查标签检测位 } uint8_t mfrc522_picc_read_serial(mfrc522_handle_t *handle) { // 这是一个简化版本,实际实现需要完整的 Mifare 协议 // 这里仅作示例 handle->uid_len = 4; return handle->uid_len; } void mfrc522_picc_halt_a(mfrc522_handle_t *handle) { mfrc522_write_reg(handle, MFRC522_REG_COMMAND, MFRC522_CMD_IDLE); } void mfrc522_deinit(mfrc522_handle_t *handle) { if (handle) { spi_bus_remove_device(handle->spi); spi_bus_free(HSPI_HOST); free(handle); } }