from esphome import pins import esphome.codegen as cg from esphome.components.zephyr.const import zephyr_ns import esphome.config_validation as cv from esphome.const import ( CONF_ANALOG, CONF_ID, CONF_INVERTED, CONF_MODE, CONF_NUMBER, PLATFORM_NRF52, ) from .const import AIN_TO_GPIO, EXTRA_ADC ZephyrGPIOPin = zephyr_ns.class_("ZephyrGPIOPin", cg.InternalGPIOPin) def _translate_pin(value): if value in AIN_TO_GPIO: return AIN_TO_GPIO[value] if isinstance(value, dict) or value is None: raise cv.Invalid( "This variable only supports pin numbers, not full pin schemas " "(with inverted and mode)." ) if isinstance(value, int): return value try: return int(value) except ValueError: pass # e.g. P0.27 if len(value) >= len("P0.0") and value[0] == "P" and value[2] == ".": return cv.int_(value[len("P")].strip()) * 32 + cv.int_( value[len("P0.") :].strip() ) raise cv.Invalid(f"Invalid pin: {value}") def validate_gpio_pin(value): if value in EXTRA_ADC: return value value = _translate_pin(value) if value < 0 or value > (32 + 16): raise cv.Invalid(f"NRF52: Invalid pin number: {value}") return value def validate_supports(value): num = value[CONF_NUMBER] mode = value[CONF_MODE] is_analog = mode[CONF_ANALOG] if is_analog: if num in EXTRA_ADC: return value if num not in AIN_TO_GPIO.values(): raise cv.Invalid(f"Cannot use {num} as analog pin") return value NRF52_PIN_SCHEMA = cv.All( pins.gpio_base_schema( ZephyrGPIOPin, validate_gpio_pin, modes=pins.GPIO_STANDARD_MODES + (CONF_ANALOG,), ), validate_supports, ) @pins.PIN_SCHEMA_REGISTRY.register(PLATFORM_NRF52, NRF52_PIN_SCHEMA) async def nrf52_pin_to_code(config): num = config[CONF_NUMBER] port = num // 32 pin_name_prefix = f"P{port}." var = cg.new_Pvariable( config[CONF_ID], cg.RawExpression(f"DEVICE_DT_GET_OR_NULL(DT_NODELABEL(gpio{port}))"), 32, pin_name_prefix, ) cg.add(var.set_pin(num)) # Only set if true to avoid bloating setup() function # (inverted bit in pin_flags_ bitfield is zero-initialized to false) if config[CONF_INVERTED]: cg.add(var.set_inverted(True)) cg.add(var.set_flags(pins.gpio_flags_expr(config[CONF_MODE]))) return var