mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-30 22:53:59 +00:00 
			
		
		
		
	making SPI CS optional (#988)
* making SPI CS optional * CS pin should be declared as optional or required in CONFIG_SCHEMA * changed SPI_DEVICE_SCHEMA to a function, like i2c * added spi_device_schema() to pcd8544, lint fixes * updated max31856 with new spi_device_schema() * cleanup imports Co-authored-by: Ilya Goldberg <iggie@mac.com>
This commit is contained in:
		| @@ -10,8 +10,8 @@ as3935_spi_ns = cg.esphome_ns.namespace('as3935_spi') | ||||
| SPIAS3935 = as3935_spi_ns.class_('SPIAS3935Component', as3935.AS3935, spi.SPIDevice) | ||||
|  | ||||
| CONFIG_SCHEMA = cv.All(as3935.AS3935_SCHEMA.extend({ | ||||
|     cv.GenerateID(): cv.declare_id(SPIAS3935) | ||||
| }).extend(cv.COMPONENT_SCHEMA).extend(spi.SPI_DEVICE_SCHEMA)) | ||||
|     cv.GenerateID(): cv.declare_id(SPIAS3935), | ||||
| }).extend(cv.COMPONENT_SCHEMA).extend(spi.spi_device_schema(CS_PIN_required=True))) | ||||
|  | ||||
|  | ||||
| def to_code(config): | ||||
|   | ||||
| @@ -55,7 +55,7 @@ CONFIG_SCHEMA = cv.Schema({ | ||||
|     cv.Required(CONF_LINE_FREQUENCY): cv.enum(LINE_FREQS, upper=True), | ||||
|     cv.Optional(CONF_CURRENT_PHASES, default='3'): cv.enum(CURRENT_PHASES, upper=True), | ||||
|     cv.Optional(CONF_GAIN_PGA, default='2X'): cv.enum(PGA_GAINS, upper=True), | ||||
| }).extend(cv.polling_component_schema('60s')).extend(spi.SPI_DEVICE_SCHEMA) | ||||
| }).extend(cv.polling_component_schema('60s')).extend(spi.spi_device_schema()) | ||||
|  | ||||
|  | ||||
| def to_code(config): | ||||
|   | ||||
| @@ -11,7 +11,7 @@ CONFIG_SCHEMA = sensor.sensor_schema(UNIT_CELSIUS, ICON_THERMOMETER, 1).extend({ | ||||
|     cv.GenerateID(): cv.declare_id(MAX31855Sensor), | ||||
|     cv.Optional(CONF_REFERENCE_TEMPERATURE): | ||||
|         sensor.sensor_schema(UNIT_CELSIUS, ICON_THERMOMETER, 2), | ||||
| }).extend(cv.polling_component_schema('60s')).extend(spi.SPI_DEVICE_SCHEMA) | ||||
| }).extend(cv.polling_component_schema('60s')).extend(spi.spi_device_schema()) | ||||
|  | ||||
|  | ||||
| def to_code(config): | ||||
|   | ||||
| @@ -16,7 +16,7 @@ FILTER = { | ||||
| CONFIG_SCHEMA = sensor.sensor_schema(UNIT_CELSIUS, ICON_THERMOMETER, 1).extend({ | ||||
|     cv.GenerateID(): cv.declare_id(MAX31856Sensor), | ||||
|     cv.Optional(CONF_MAINS_FILTER, default='60HZ'): cv.enum(FILTER, upper=True, space=''), | ||||
| }).extend(cv.polling_component_schema('60s')).extend(spi.SPI_DEVICE_SCHEMA) | ||||
| }).extend(cv.polling_component_schema('60s')).extend(spi.spi_device_schema()) | ||||
|  | ||||
|  | ||||
| def to_code(config): | ||||
|   | ||||
| @@ -20,7 +20,7 @@ CONFIG_SCHEMA = sensor.sensor_schema(UNIT_CELSIUS, ICON_THERMOMETER, 2).extend({ | ||||
|     cv.Required(CONF_RTD_NOMINAL_RESISTANCE): cv.All(cv.resistance, cv.Range(min=100, max=1000)), | ||||
|     cv.Optional(CONF_MAINS_FILTER, default='60HZ'): cv.enum(FILTER, upper=True, space=''), | ||||
|     cv.Optional(CONF_RTD_WIRES, default=4): cv.int_range(min=2, max=4), | ||||
| }).extend(cv.polling_component_schema('60s')).extend(spi.SPI_DEVICE_SCHEMA) | ||||
| }).extend(cv.polling_component_schema('60s')).extend(spi.spi_device_schema()) | ||||
|  | ||||
|  | ||||
| def to_code(config): | ||||
|   | ||||
| @@ -9,7 +9,7 @@ MAX6675Sensor = max6675_ns.class_('MAX6675Sensor', sensor.Sensor, cg.PollingComp | ||||
|  | ||||
| CONFIG_SCHEMA = sensor.sensor_schema(UNIT_CELSIUS, ICON_THERMOMETER, 1).extend({ | ||||
|     cv.GenerateID(): cv.declare_id(MAX6675Sensor), | ||||
| }).extend(cv.polling_component_schema('60s')).extend(spi.SPI_DEVICE_SCHEMA) | ||||
| }).extend(cv.polling_component_schema('60s')).extend(spi.spi_device_schema()) | ||||
|  | ||||
|  | ||||
| def to_code(config): | ||||
|   | ||||
| @@ -14,7 +14,7 @@ CONFIG_SCHEMA = display.BASIC_DISPLAY_SCHEMA.extend({ | ||||
|  | ||||
|     cv.Optional(CONF_NUM_CHIPS, default=1): cv.int_range(min=1, max=255), | ||||
|     cv.Optional(CONF_INTENSITY, default=15): cv.int_range(min=0, max=15), | ||||
| }).extend(cv.polling_component_schema('1s')).extend(spi.SPI_DEVICE_SCHEMA) | ||||
| }).extend(cv.polling_component_schema('1s')).extend(spi.spi_device_schema()) | ||||
|  | ||||
|  | ||||
| def to_code(config): | ||||
|   | ||||
| @@ -17,7 +17,7 @@ CONFIG_SCHEMA = cv.All(display.FULL_DISPLAY_SCHEMA.extend({ | ||||
|     cv.Required(CONF_DC_PIN): pins.gpio_output_pin_schema, | ||||
|     cv.Required(CONF_RESET_PIN): pins.gpio_output_pin_schema, | ||||
|     cv.Required(CONF_CS_PIN): pins.gpio_output_pin_schema,  # CE | ||||
| }).extend(cv.polling_component_schema('1s')).extend(spi.SPI_DEVICE_SCHEMA), | ||||
| }).extend(cv.polling_component_schema('1s')).extend(spi.spi_device_schema()), | ||||
|                        cv.has_at_most_one_key(CONF_PAGES, CONF_LAMBDA)) | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -17,7 +17,7 @@ CONFIG_SCHEMA = cv.Schema({ | ||||
|     cv.Optional(CONF_ON_TAG): automation.validate_automation({ | ||||
|         cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(PN532Trigger), | ||||
|     }), | ||||
| }).extend(cv.polling_component_schema('1s')).extend(spi.SPI_DEVICE_SCHEMA) | ||||
| }).extend(cv.polling_component_schema('1s')).extend(spi.spi_device_schema()) | ||||
|  | ||||
|  | ||||
| def to_code(config): | ||||
|   | ||||
| @@ -31,6 +31,7 @@ void PN532::setup() { | ||||
|   //    (this may time out, but that's ok) | ||||
|   // 3. Send SAM config command with normal mode without waiting for ready bit (IRQ not initialized yet) | ||||
|   // 4. Probably optional, send SAM config again, this time checking ACK and return value | ||||
|   if (this->cs_) | ||||
|     this->cs_->digital_write(false); | ||||
|   delay(10); | ||||
|  | ||||
|   | ||||
| @@ -34,15 +34,25 @@ def to_code(config): | ||||
|         cg.add(var.set_mosi(mosi)) | ||||
|  | ||||
|  | ||||
| SPI_DEVICE_SCHEMA = cv.Schema({ | ||||
| def spi_device_schema(CS_PIN_required=False): | ||||
|     """Create a schema for an SPI device. | ||||
|     :param CS_PIN_required: If true, make the CS_PIN required in the config. | ||||
|     :return: The SPI device schema, `extend` this in your config schema. | ||||
|     """ | ||||
|     schema = { | ||||
|         cv.GenerateID(CONF_SPI_ID): cv.use_id(SPIComponent), | ||||
|     cv.Required(CONF_CS_PIN): pins.gpio_output_pin_schema, | ||||
| }) | ||||
|     } | ||||
|     if CS_PIN_required: | ||||
|         schema[cv.Required(CONF_CS_PIN)] = pins.gpio_output_pin_schema | ||||
|     else: | ||||
|         schema[cv.Optional(CONF_CS_PIN)] = pins.gpio_output_pin_schema | ||||
|     return cv.Schema(schema) | ||||
|  | ||||
|  | ||||
| @coroutine | ||||
| def register_spi_device(var, config): | ||||
|     parent = yield cg.get_variable(config[CONF_SPI_ID]) | ||||
|     cg.add(var.set_spi_parent(parent)) | ||||
|     if CONF_CS_PIN in config: | ||||
|         pin = yield cg.gpio_pin_expression(config[CONF_CS_PIN]) | ||||
|         cg.add(var.set_cs_pin(pin)) | ||||
|   | ||||
| @@ -12,10 +12,12 @@ void ICACHE_RAM_ATTR HOT SPIComponent::disable() { | ||||
|   if (this->hw_spi_ != nullptr) { | ||||
|     this->hw_spi_->endTransaction(); | ||||
|   } | ||||
|   if (this->active_cs_) { | ||||
|     ESP_LOGVV(TAG, "Disabling SPI Chip on pin %u...", this->active_cs_->get_pin()); | ||||
|     this->active_cs_->digital_write(true); | ||||
|     this->active_cs_ = nullptr; | ||||
|   } | ||||
| } | ||||
| void SPIComponent::setup() { | ||||
|   ESP_LOGCONFIG(TAG, "Setting up SPI bus..."); | ||||
|   this->clk_->setup(); | ||||
|   | ||||
| @@ -127,6 +127,7 @@ class SPIComponent : public Component { | ||||
|  | ||||
|   template<SPIBitOrder BIT_ORDER, SPIClockPolarity CLOCK_POLARITY, SPIClockPhase CLOCK_PHASE, uint32_t DATA_RATE> | ||||
|   void enable(GPIOPin *cs) { | ||||
|     if (cs) { | ||||
|       SPIComponent::debug_enable(cs->get_pin()); | ||||
|  | ||||
|       if (this->hw_spi_ != nullptr) { | ||||
| @@ -141,6 +142,7 @@ class SPIComponent : public Component { | ||||
|       this->active_cs_ = cs; | ||||
|       this->active_cs_->digital_write(false); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   void disable(); | ||||
|  | ||||
| @@ -174,9 +176,11 @@ class SPIDevice { | ||||
|   void set_cs_pin(GPIOPin *cs) { cs_ = cs; } | ||||
|  | ||||
|   void spi_setup() { | ||||
|     if (this->cs_) { | ||||
|       this->cs_->setup(); | ||||
|       this->cs_->digital_write(true); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   void enable() { this->parent_->template enable<BIT_ORDER, CLOCK_POLARITY, CLOCK_PHASE, DATA_RATE>(this->cs_); } | ||||
|  | ||||
|   | ||||
| @@ -13,7 +13,7 @@ SPISSD1306 = ssd1306_spi.class_('SPISSD1306', ssd1306_base.SSD1306, spi.SPIDevic | ||||
| CONFIG_SCHEMA = cv.All(ssd1306_base.SSD1306_SCHEMA.extend({ | ||||
|     cv.GenerateID(): cv.declare_id(SPISSD1306), | ||||
|     cv.Required(CONF_DC_PIN): pins.gpio_output_pin_schema, | ||||
| }).extend(cv.COMPONENT_SCHEMA).extend(spi.SPI_DEVICE_SCHEMA), | ||||
| }).extend(cv.COMPONENT_SCHEMA).extend(spi.spi_device_schema()), | ||||
|                        cv.has_at_most_one_key(CONF_PAGES, CONF_LAMBDA)) | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -13,7 +13,7 @@ SPISSD1325 = ssd1325_spi.class_('SPISSD1325', ssd1325_base.SSD1325, spi.SPIDevic | ||||
| CONFIG_SCHEMA = cv.All(ssd1325_base.SSD1325_SCHEMA.extend({ | ||||
|     cv.GenerateID(): cv.declare_id(SPISSD1325), | ||||
|     cv.Required(CONF_DC_PIN): pins.gpio_output_pin_schema, | ||||
| }).extend(cv.COMPONENT_SCHEMA).extend(spi.SPI_DEVICE_SCHEMA), | ||||
| }).extend(cv.COMPONENT_SCHEMA).extend(spi.spi_device_schema()), | ||||
|                        cv.has_at_most_one_key(CONF_PAGES, CONF_LAMBDA)) | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -11,6 +11,7 @@ void SPISSD1325::setup() { | ||||
|   ESP_LOGCONFIG(TAG, "Setting up SPI SSD1325..."); | ||||
|   this->spi_setup(); | ||||
|   this->dc_pin_->setup();  // OUTPUT | ||||
|   if (this->cs_) | ||||
|     this->cs_->setup();  // OUTPUT | ||||
|  | ||||
|   this->init_reset_(); | ||||
| @@ -27,18 +28,23 @@ void SPISSD1325::dump_config() { | ||||
|   LOG_UPDATE_INTERVAL(this); | ||||
| } | ||||
| void SPISSD1325::command(uint8_t value) { | ||||
|   if (this->cs_) | ||||
|     this->cs_->digital_write(true); | ||||
|   this->dc_pin_->digital_write(false); | ||||
|   delay(1); | ||||
|   this->enable(); | ||||
|   if (this->cs_) | ||||
|     this->cs_->digital_write(false); | ||||
|   this->write_byte(value); | ||||
|   if (this->cs_) | ||||
|     this->cs_->digital_write(true); | ||||
|   this->disable(); | ||||
| } | ||||
| void HOT SPISSD1325::write_display_data() { | ||||
|   if (this->cs_) | ||||
|     this->cs_->digital_write(true); | ||||
|   this->dc_pin_->digital_write(true); | ||||
|   if (this->cs_) | ||||
|     this->cs_->digital_write(false); | ||||
|   delay(1); | ||||
|   this->enable(); | ||||
| @@ -56,6 +62,7 @@ void HOT SPISSD1325::write_display_data() { | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|   if (this->cs_) | ||||
|     this->cs_->digital_write(true); | ||||
|   this->disable(); | ||||
| } | ||||
|   | ||||
| @@ -50,7 +50,7 @@ CONFIG_SCHEMA = cv.All(display.FULL_DISPLAY_SCHEMA.extend({ | ||||
|     cv.Optional(CONF_RESET_PIN): pins.gpio_output_pin_schema, | ||||
|     cv.Optional(CONF_BUSY_PIN): pins.gpio_input_pin_schema, | ||||
|     cv.Optional(CONF_FULL_UPDATE_EVERY): cv.uint32_t, | ||||
| }).extend(cv.polling_component_schema('1s')).extend(spi.SPI_DEVICE_SCHEMA), | ||||
| }).extend(cv.polling_component_schema('1s')).extend(spi.spi_device_schema()), | ||||
|                        validate_full_update_every_only_type_a, | ||||
|                        cv.has_at_most_one_key(CONF_PAGES, CONF_LAMBDA)) | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user