Add gain setting for rc522 component

This commit is contained in:
Selamanse 2024-10-03 21:26:37 +02:00
parent d77ea46157
commit 7f808fb6d6
4 changed files with 65 additions and 0 deletions

View file

@ -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]))

View file

@ -37,6 +37,29 @@ std::string format_uid(std::vector<uint8_t> &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_) {

View file

@ -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 <vector>
#include <map>
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};

View file

@ -7,6 +7,7 @@ spi:
rc522_spi:
id: rc522_nfcc
cs_pin: 12
gain: 48dB
binary_sensor:
- platform: rc522