From 7f808fb6d689d82db8c01c652aa723e5e4ddf59d Mon Sep 17 00:00:00 2001 From: Selamanse Date: Thu, 3 Oct 2024 21:26:37 +0200 Subject: [PATCH] Add gain setting for rc522 component --- esphome/components/rc522/__init__.py | 16 ++++++++++++ esphome/components/rc522/rc522.cpp | 29 ++++++++++++++++++++++ esphome/components/rc522/rc522.h | 19 ++++++++++++++ tests/components/rc522_spi/test.esp32.yaml | 1 + 4 files changed, 65 insertions(+) diff --git a/esphome/components/rc522/__init__.py b/esphome/components/rc522/__init__.py index 1a1e641623..c135b9e1cb 100644 --- a/esphome/components/rc522/__init__.py +++ b/esphome/components/rc522/__init__.py @@ -3,6 +3,7 @@ import esphome.config_validation as cv from esphome import automation, pins from esphome.components import i2c from esphome.const import ( + CONF_GAIN, CONF_ON_TAG, CONF_ON_TAG_REMOVED, CONF_TRIGGER_ID, @@ -20,6 +21,18 @@ RC522Trigger = rc522_ns.class_( "RC522Trigger", automation.Trigger.template(cg.std_string) ) +RC522Gain = rc522_ns.enum("RC522Gain") +GAIN = { + "18dB": RC522Gain.RC522_GAIN_18DB, + "23dB": RC522Gain.RC522_GAIN_23DB, + "18dB_a": RC522Gain.RC522_GAIN_18DBA, + "23dB_a": RC522Gain.RC522_GAIN_23DBA, + "33dB": RC522Gain.RC522_GAIN_33DB, + "38dB": RC522Gain.RC522_GAIN_38DB, + "43dB": RC522Gain.RC522_GAIN_43DB, + "48dB": RC522Gain.RC522_GAIN_48DB, +} + RC522_SCHEMA = cv.Schema( { cv.GenerateID(): cv.declare_id(RC522), @@ -34,6 +47,7 @@ RC522_SCHEMA = cv.Schema( cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(RC522Trigger), } ), + cv.Optional(CONF_GAIN, default="38dB"): cv.enum(GAIN, string=True), } ).extend(cv.polling_component_schema("1s")) @@ -54,3 +68,5 @@ async def setup_rc522(var, config): trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID]) cg.add(var.register_ontagremoved_trigger(trigger)) await automation.build_automation(trigger, [(cg.std_string, "x")], conf) + + cg.add(var.set_gain(config[CONF_GAIN])) diff --git a/esphome/components/rc522/rc522.cpp b/esphome/components/rc522/rc522.cpp index e2146dd14e..7d8f6e97a8 100644 --- a/esphome/components/rc522/rc522.cpp +++ b/esphome/components/rc522/rc522.cpp @@ -37,6 +37,29 @@ std::string format_uid(std::vector &uid) { return std::string(buf); } +const LogString *rc522_gain_to_string(RC522Gain gain) { + switch (gain) { + case RC522Gain::RC522_GAIN_18DB: + return LOG_STR("18dB"); + case RC522Gain::RC522_GAIN_18DBA: + return LOG_STR("18dB_a"); + case RC522Gain::RC522_GAIN_23DB: + return LOG_STR("23dB"); + case RC522Gain::RC522_GAIN_23DBA: + return LOG_STR("23dB_a"); + case RC522Gain::RC522_GAIN_33DB: + return LOG_STR("33dB"); + case RC522Gain::RC522_GAIN_38DB: + return LOG_STR("38dB"); + case RC522Gain::RC522_GAIN_43DB: + return LOG_STR("43dB"); + case RC522Gain::RC522_GAIN_48DB: + return LOG_STR("48dB"); + default: + return LOG_STR("UNKNOWN"); + } +} + void RC522::setup() { state_ = STATE_SETUP; // Pull device out of power down / reset state. @@ -82,6 +105,10 @@ void RC522::initialize_() { pcd_write_register(T_MODE_REG, 0x80); // TAuto=1; timer starts automatically at the end of the transmission in all // communication modes at all speeds + pcd_clear_register_bit_mask_(RF_CFG_REG, (0x07 << 4)); + pcd_write_register(RF_CFG_REG, gain_ & (0x07 << 4)); + ESP_LOGI(TAG, "Gain Setting: %s", LOG_STR_ARG(rc522_gain_to_string(this->gain_))); + // TPreScaler = TModeReg[3..0]:TPrescalerReg, ie 0x0A9 = 169 => f_timer=40kHz, ie a timer period of 25μs. pcd_write_register(T_PRESCALER_REG, 0xA9); pcd_write_register(T_RELOAD_REG_H, 0x03); // Reload timer with 0x3E8 = 1000, ie 25ms before timeout. @@ -107,6 +134,8 @@ void RC522::dump_config() { LOG_PIN(" RESET Pin: ", this->reset_pin_); + ESP_LOGCONFIG(TAG, "Gain Setting: %s", LOG_STR_ARG(rc522_gain_to_string(this->gain_))); + LOG_UPDATE_INTERVAL(this); for (auto *child : this->binary_sensors_) { diff --git a/esphome/components/rc522/rc522.h b/esphome/components/rc522/rc522.h index c6c5e119f0..ced6457666 100644 --- a/esphome/components/rc522/rc522.h +++ b/esphome/components/rc522/rc522.h @@ -4,12 +4,29 @@ #include "esphome/core/hal.h" #include "esphome/core/automation.h" #include "esphome/components/binary_sensor/binary_sensor.h" +#include "esphome/core/log.h" #include +#include namespace esphome { namespace rc522 { +// based on register bit descriptions in 9.3.3.6 Table 98. https://www.nxp.com/docs/en/data-sheet/MFRC522.pdf +enum RC522Gain { + RC522_GAIN_18DB = 0x00 << 4, + RC522_GAIN_23DB = 0x01 << 4, + RC522_GAIN_18DBA = 0x02 << 4, + RC522_GAIN_23DBA = 0x03 << 4, + RC522_GAIN_33DB = 0x04 << 4, + RC522_GAIN_38DB = 0x05 << 4, + RC522_GAIN_43DB = 0x06 << 4, + RC522_GAIN_48DB = 0x07 << 4, +}; + +/// Convert the given Gain config value to a human-readable string. +const LogString *rc522_gain_to_string(RC522Gain gain); + class RC522BinarySensor; class RC522Trigger; class RC522 : public PollingComponent { @@ -28,6 +45,7 @@ class RC522 : public PollingComponent { void register_ontagremoved_trigger(RC522Trigger *trig) { this->triggers_ontagremoved_.push_back(trig); } void set_reset_pin(GPIOPin *reset) { this->reset_pin_ = reset; } + void set_gain(RC522Gain gain) { this->gain_ = gain; } protected: // Return codes from the functions in this class. Remember to update GetStatusCodeName() if you add more. @@ -238,6 +256,7 @@ class RC522 : public PollingComponent { uint8_t error_counter_ = 0; // to reset if unresponsive uint8_t rx_align_; uint8_t *valid_bits_; + RC522Gain gain_; GPIOPin *reset_pin_{nullptr}; uint8_t reset_count_{0}; diff --git a/tests/components/rc522_spi/test.esp32.yaml b/tests/components/rc522_spi/test.esp32.yaml index 5c0b698a08..eb0b763d89 100644 --- a/tests/components/rc522_spi/test.esp32.yaml +++ b/tests/components/rc522_spi/test.esp32.yaml @@ -7,6 +7,7 @@ spi: rc522_spi: id: rc522_nfcc cs_pin: 12 + gain: 48dB binary_sensor: - platform: rc522