feat(firmware): add MFRC522 driver implementation and configuration

This commit is contained in:
2025-11-24 11:40:57 +08:00
parent c0c32cb9a7
commit a54bd62491
6 changed files with 315 additions and 65 deletions

View File

@@ -0,0 +1,142 @@
#include "mfrc522.h"
#include "driver/gpio.h"
#include "esp_log.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include <stdlib.h>
#include <string.h>
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);
}
}