mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-30 22:53:59 +00:00 
			
		
		
		
	Inkplate 6 support for ESPHome (#1283)
* Add Inkplate 6 support Inkplate 6 is e-paper display based on ESP32. This commit adds support for integrating Inkplate 6 into the ESPHome. Find more info here: inkplate.io * Greyscale working * Update inkplate.h * Fix formatting * Formatting * Update esphome/components/inkplate6/display.py Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com> * Update esphome/components/inkplate6/display.py Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com> * Fix some lint errors Ignore some lint errors Only allow on ESP32 * Update the codeowners file Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
This commit is contained in:
		| @@ -37,6 +37,7 @@ esphome/components/globals/* @esphome/core | ||||
| esphome/components/gpio/* @esphome/core | ||||
| esphome/components/homeassistant/* @OttoWinter | ||||
| esphome/components/i2c/* @esphome/core | ||||
| esphome/components/inkplate6/* @jesserockz | ||||
| esphome/components/integration/* @OttoWinter | ||||
| esphome/components/interval/* @esphome/core | ||||
| esphome/components/json/* @OttoWinter | ||||
|   | ||||
							
								
								
									
										1
									
								
								esphome/components/inkplate6/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								esphome/components/inkplate6/__init__.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| CODEOWNERS = ['@jesserockz'] | ||||
							
								
								
									
										141
									
								
								esphome/components/inkplate6/display.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										141
									
								
								esphome/components/inkplate6/display.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,141 @@ | ||||
| import esphome.codegen as cg | ||||
| import esphome.config_validation as cv | ||||
| from esphome import pins | ||||
| from esphome.components import display, i2c | ||||
| from esphome.const import CONF_FULL_UPDATE_EVERY, CONF_ID, CONF_LAMBDA, CONF_PAGES, \ | ||||
|     CONF_WAKEUP_PIN, ESP_PLATFORM_ESP32 | ||||
|  | ||||
| DEPENDENCIES = ['i2c'] | ||||
| ESP_PLATFORMS = [ESP_PLATFORM_ESP32] | ||||
|  | ||||
| CONF_DISPLAY_DATA_0_PIN = 'display_data_0_pin' | ||||
| CONF_DISPLAY_DATA_1_PIN = 'display_data_1_pin' | ||||
| CONF_DISPLAY_DATA_2_PIN = 'display_data_2_pin' | ||||
| CONF_DISPLAY_DATA_3_PIN = 'display_data_3_pin' | ||||
| CONF_DISPLAY_DATA_4_PIN = 'display_data_4_pin' | ||||
| CONF_DISPLAY_DATA_5_PIN = 'display_data_5_pin' | ||||
| CONF_DISPLAY_DATA_6_PIN = 'display_data_6_pin' | ||||
| CONF_DISPLAY_DATA_7_PIN = 'display_data_7_pin' | ||||
|  | ||||
| CONF_CL_PIN = 'cl_pin' | ||||
| CONF_CKV_PIN = 'ckv_pin' | ||||
| CONF_GREYSCALE = 'greyscale' | ||||
| CONF_GMOD_PIN = 'gmod_pin' | ||||
| CONF_GPIO0_ENABLE_PIN = 'gpio0_enable_pin' | ||||
| CONF_LE_PIN = 'le_pin' | ||||
| CONF_OE_PIN = 'oe_pin' | ||||
| CONF_PARTIAL_UPDATING = 'partial_updating' | ||||
| CONF_POWERUP_PIN = 'powerup_pin' | ||||
| CONF_SPH_PIN = 'sph_pin' | ||||
| CONF_SPV_PIN = 'spv_pin' | ||||
| CONF_VCOM_PIN = 'vcom_pin' | ||||
|  | ||||
|  | ||||
| inkplate6_ns = cg.esphome_ns.namespace('inkplate6') | ||||
| Inkplate6 = inkplate6_ns.class_('Inkplate6', cg.PollingComponent, i2c.I2CDevice, | ||||
|                                 display.DisplayBuffer) | ||||
|  | ||||
| CONFIG_SCHEMA = cv.All(display.FULL_DISPLAY_SCHEMA.extend({ | ||||
|     cv.GenerateID(): cv.declare_id(Inkplate6), | ||||
|     cv.Optional(CONF_GREYSCALE, default=False): cv.boolean, | ||||
|     cv.Optional(CONF_PARTIAL_UPDATING, default=True): cv.boolean, | ||||
|     cv.Optional(CONF_FULL_UPDATE_EVERY, default=10): cv.uint32_t, | ||||
|     # Control pins | ||||
|     cv.Required(CONF_CKV_PIN): pins.gpio_output_pin_schema, | ||||
|     cv.Required(CONF_GMOD_PIN): pins.gpio_output_pin_schema, | ||||
|     cv.Required(CONF_GPIO0_ENABLE_PIN): pins.gpio_output_pin_schema, | ||||
|     cv.Required(CONF_OE_PIN): pins.gpio_output_pin_schema, | ||||
|     cv.Required(CONF_POWERUP_PIN): pins.gpio_output_pin_schema, | ||||
|     cv.Required(CONF_SPH_PIN): pins.gpio_output_pin_schema, | ||||
|     cv.Required(CONF_SPV_PIN): pins.gpio_output_pin_schema, | ||||
|     cv.Required(CONF_VCOM_PIN): pins.gpio_output_pin_schema, | ||||
|     cv.Required(CONF_WAKEUP_PIN): pins.gpio_output_pin_schema, | ||||
|     cv.Optional(CONF_CL_PIN, default=0): pins.internal_gpio_output_pin_schema, | ||||
|     cv.Optional(CONF_LE_PIN, default=2): pins.internal_gpio_output_pin_schema, | ||||
|     # Data pins | ||||
|     cv.Optional(CONF_DISPLAY_DATA_0_PIN, default=4): pins.internal_gpio_output_pin_schema, | ||||
|     cv.Optional(CONF_DISPLAY_DATA_1_PIN, default=5): pins.internal_gpio_output_pin_schema, | ||||
|     cv.Optional(CONF_DISPLAY_DATA_2_PIN, default=18): pins.internal_gpio_output_pin_schema, | ||||
|     cv.Optional(CONF_DISPLAY_DATA_3_PIN, default=19): pins.internal_gpio_output_pin_schema, | ||||
|     cv.Optional(CONF_DISPLAY_DATA_4_PIN, default=23): pins.internal_gpio_output_pin_schema, | ||||
|     cv.Optional(CONF_DISPLAY_DATA_5_PIN, default=25): pins.internal_gpio_output_pin_schema, | ||||
|     cv.Optional(CONF_DISPLAY_DATA_6_PIN, default=26): pins.internal_gpio_output_pin_schema, | ||||
|     cv.Optional(CONF_DISPLAY_DATA_7_PIN, default=27): pins.internal_gpio_output_pin_schema, | ||||
| }).extend(cv.polling_component_schema('5s').extend(i2c.i2c_device_schema(0x48))), | ||||
|                        cv.has_at_most_one_key(CONF_PAGES, CONF_LAMBDA)) | ||||
|  | ||||
|  | ||||
| def to_code(config): | ||||
|     var = cg.new_Pvariable(config[CONF_ID]) | ||||
|  | ||||
|     yield cg.register_component(var, config) | ||||
|     yield display.register_display(var, config) | ||||
|     yield i2c.register_i2c_device(var, config) | ||||
|  | ||||
|     if CONF_LAMBDA in config: | ||||
|         lambda_ = yield cg.process_lambda(config[CONF_LAMBDA], [(display.DisplayBufferRef, 'it')], | ||||
|                                           return_type=cg.void) | ||||
|         cg.add(var.set_writer(lambda_)) | ||||
|  | ||||
|     cg.add(var.set_greyscale(config[CONF_GREYSCALE])) | ||||
|     cg.add(var.set_partial_updating(config[CONF_PARTIAL_UPDATING])) | ||||
|     cg.add(var.set_full_update_every(config[CONF_FULL_UPDATE_EVERY])) | ||||
|  | ||||
|     ckv = yield cg.gpio_pin_expression(config[CONF_CKV_PIN]) | ||||
|     cg.add(var.set_ckv_pin(ckv)) | ||||
|  | ||||
|     gmod = yield cg.gpio_pin_expression(config[CONF_GMOD_PIN]) | ||||
|     cg.add(var.set_gmod_pin(gmod)) | ||||
|  | ||||
|     gpio0_enable = yield cg.gpio_pin_expression(config[CONF_GPIO0_ENABLE_PIN]) | ||||
|     cg.add(var.set_gpio0_enable_pin(gpio0_enable)) | ||||
|  | ||||
|     oe = yield cg.gpio_pin_expression(config[CONF_OE_PIN]) | ||||
|     cg.add(var.set_oe_pin(oe)) | ||||
|  | ||||
|     powerup = yield cg.gpio_pin_expression(config[CONF_POWERUP_PIN]) | ||||
|     cg.add(var.set_powerup_pin(powerup)) | ||||
|  | ||||
|     sph = yield cg.gpio_pin_expression(config[CONF_SPH_PIN]) | ||||
|     cg.add(var.set_sph_pin(sph)) | ||||
|  | ||||
|     spv = yield cg.gpio_pin_expression(config[CONF_SPV_PIN]) | ||||
|     cg.add(var.set_spv_pin(spv)) | ||||
|  | ||||
|     vcom = yield cg.gpio_pin_expression(config[CONF_VCOM_PIN]) | ||||
|     cg.add(var.set_vcom_pin(vcom)) | ||||
|  | ||||
|     wakeup = yield cg.gpio_pin_expression(config[CONF_WAKEUP_PIN]) | ||||
|     cg.add(var.set_wakeup_pin(wakeup)) | ||||
|  | ||||
|     cl = yield cg.gpio_pin_expression(config[CONF_CL_PIN]) | ||||
|     cg.add(var.set_cl_pin(cl)) | ||||
|  | ||||
|     le = yield cg.gpio_pin_expression(config[CONF_LE_PIN]) | ||||
|     cg.add(var.set_le_pin(le)) | ||||
|  | ||||
|     display_data_0 = yield cg.gpio_pin_expression(config[CONF_DISPLAY_DATA_0_PIN]) | ||||
|     cg.add(var.set_display_data_0_pin(display_data_0)) | ||||
|  | ||||
|     display_data_1 = yield cg.gpio_pin_expression(config[CONF_DISPLAY_DATA_1_PIN]) | ||||
|     cg.add(var.set_display_data_1_pin(display_data_1)) | ||||
|  | ||||
|     display_data_2 = yield cg.gpio_pin_expression(config[CONF_DISPLAY_DATA_2_PIN]) | ||||
|     cg.add(var.set_display_data_2_pin(display_data_2)) | ||||
|  | ||||
|     display_data_3 = yield cg.gpio_pin_expression(config[CONF_DISPLAY_DATA_3_PIN]) | ||||
|     cg.add(var.set_display_data_3_pin(display_data_3)) | ||||
|  | ||||
|     display_data_4 = yield cg.gpio_pin_expression(config[CONF_DISPLAY_DATA_4_PIN]) | ||||
|     cg.add(var.set_display_data_4_pin(display_data_4)) | ||||
|  | ||||
|     display_data_5 = yield cg.gpio_pin_expression(config[CONF_DISPLAY_DATA_5_PIN]) | ||||
|     cg.add(var.set_display_data_5_pin(display_data_5)) | ||||
|  | ||||
|     display_data_6 = yield cg.gpio_pin_expression(config[CONF_DISPLAY_DATA_6_PIN]) | ||||
|     cg.add(var.set_display_data_6_pin(display_data_6)) | ||||
|  | ||||
|     display_data_7 = yield cg.gpio_pin_expression(config[CONF_DISPLAY_DATA_7_PIN]) | ||||
|     cg.add(var.set_display_data_7_pin(display_data_7)) | ||||
|  | ||||
|     cg.add_build_flag('-DBOARD_HAS_PSRAM') | ||||
							
								
								
									
										630
									
								
								esphome/components/inkplate6/inkplate.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										630
									
								
								esphome/components/inkplate6/inkplate.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,630 @@ | ||||
| #include "inkplate.h" | ||||
| #include "esphome/core/log.h" | ||||
| #include "esphome/core/application.h" | ||||
| #include "esphome/core/helpers.h" | ||||
|  | ||||
| #ifdef ARDUINO_ARCH_ESP32 | ||||
|  | ||||
| namespace esphome { | ||||
| namespace inkplate6 { | ||||
|  | ||||
| static const char *TAG = "inkplate"; | ||||
|  | ||||
| void Inkplate6::setup() { | ||||
|   this->initialize_(); | ||||
|  | ||||
|   this->vcom_pin_->setup(); | ||||
|   this->powerup_pin_->setup(); | ||||
|   this->wakeup_pin_->setup(); | ||||
|   this->gpio0_enable_pin_->setup(); | ||||
|   this->gpio0_enable_pin_->digital_write(true); | ||||
|  | ||||
|   this->cl_pin_->setup(); | ||||
|   this->le_pin_->setup(); | ||||
|   this->ckv_pin_->setup(); | ||||
|   this->gmod_pin_->setup(); | ||||
|   this->oe_pin_->setup(); | ||||
|   this->sph_pin_->setup(); | ||||
|   this->spv_pin_->setup(); | ||||
|  | ||||
|   this->display_data_0_pin_->setup(); | ||||
|   this->display_data_1_pin_->setup(); | ||||
|   this->display_data_2_pin_->setup(); | ||||
|   this->display_data_3_pin_->setup(); | ||||
|   this->display_data_4_pin_->setup(); | ||||
|   this->display_data_5_pin_->setup(); | ||||
|   this->display_data_6_pin_->setup(); | ||||
|   this->display_data_7_pin_->setup(); | ||||
|  | ||||
|   this->clean(); | ||||
|   this->display(); | ||||
| } | ||||
| void Inkplate6::initialize_() { | ||||
|   uint32_t buffer_size = this->get_buffer_length_(); | ||||
|  | ||||
|   if (this->partial_buffer_ != nullptr) { | ||||
|     free(this->partial_buffer_);  // NOLINT | ||||
|   } | ||||
|   if (this->partial_buffer_2_ != nullptr) { | ||||
|     free(this->partial_buffer_2_);  // NOLINT | ||||
|   } | ||||
|   if (this->buffer_ != nullptr) { | ||||
|     free(this->buffer_);  // NOLINT | ||||
|   } | ||||
|  | ||||
|   this->buffer_ = (uint8_t *) ps_malloc(buffer_size); | ||||
|   if (this->buffer_ == nullptr) { | ||||
|     ESP_LOGE(TAG, "Could not allocate buffer for display!"); | ||||
|     this->mark_failed(); | ||||
|     return; | ||||
|   } | ||||
|   if (!this->greyscale_) { | ||||
|     this->partial_buffer_ = (uint8_t *) ps_malloc(buffer_size); | ||||
|     if (this->partial_buffer_ == nullptr) { | ||||
|       ESP_LOGE(TAG, "Could not allocate partial buffer for display!"); | ||||
|       this->mark_failed(); | ||||
|       return; | ||||
|     } | ||||
|     this->partial_buffer_2_ = (uint8_t *) ps_malloc(buffer_size * 2); | ||||
|     if (this->partial_buffer_2_ == nullptr) { | ||||
|       ESP_LOGE(TAG, "Could not allocate partial buffer 2 for display!"); | ||||
|       this->mark_failed(); | ||||
|       return; | ||||
|     } | ||||
|     memset(this->partial_buffer_, 0, buffer_size); | ||||
|     memset(this->partial_buffer_2_, 0, buffer_size * 2); | ||||
|   } | ||||
|  | ||||
|   memset(this->buffer_, 0, buffer_size); | ||||
| } | ||||
| float Inkplate6::get_setup_priority() const { return setup_priority::PROCESSOR; } | ||||
| size_t Inkplate6::get_buffer_length_() { | ||||
|   if (this->greyscale_) { | ||||
|     return size_t(this->get_width_internal()) * size_t(this->get_height_internal()) / 2u; | ||||
|   } else { | ||||
|     return size_t(this->get_width_internal()) * size_t(this->get_height_internal()) / 8u; | ||||
|   } | ||||
| } | ||||
| void Inkplate6::update() { | ||||
|   this->do_update_(); | ||||
|  | ||||
|   if (this->full_update_every_ > 0 && this->partial_updates_ >= this->full_update_every_) { | ||||
|     this->block_partial_ = true; | ||||
|   } | ||||
|  | ||||
|   this->display(); | ||||
| } | ||||
| void HOT Inkplate6::draw_absolute_pixel_internal(int x, int y, Color color) { | ||||
|   if (x >= this->get_width_internal() || y >= this->get_height_internal() || x < 0 || y < 0) | ||||
|     return; | ||||
|  | ||||
|   if (this->greyscale_) { | ||||
|     int x1 = x / 2; | ||||
|     int x_sub = x % 2; | ||||
|     uint32_t pos = (x1 + y * (this->get_width_internal() / 2)); | ||||
|     uint8_t current = this->buffer_[pos]; | ||||
|  | ||||
|     // float px = (0.2126 * (color.red / 255.0)) + (0.7152 * (color.green / 255.0)) + (0.0722 * (color.blue / 255.0)); | ||||
|     // px = pow(px, 1.5); | ||||
|     // uint8_t gs = (uint8_t)(px*7); | ||||
|  | ||||
|     uint8_t gs = ((color.red * 2126 / 10000) + (color.green * 7152 / 10000) + (color.blue * 722 / 10000)) >> 5; | ||||
|     this->buffer_[pos] = (pixelMaskGLUT[x_sub] & current) | (x_sub ? gs : gs << 4); | ||||
|  | ||||
|   } else { | ||||
|     int x1 = x / 8; | ||||
|     int x_sub = x % 8; | ||||
|     uint32_t pos = (x1 + y * (this->get_width_internal() / 8)); | ||||
|     uint8_t current = this->partial_buffer_[pos]; | ||||
|     this->partial_buffer_[pos] = (~pixelMaskLUT[x_sub] & current) | (color.is_on() ? 0 : pixelMaskLUT[x_sub]); | ||||
|   } | ||||
| } | ||||
| void Inkplate6::dump_config() { | ||||
|   LOG_DISPLAY("", "Inkplate", this); | ||||
|   ESP_LOGCONFIG(TAG, "  Greyscale: %s", YESNO(this->greyscale_)); | ||||
|   ESP_LOGCONFIG(TAG, "  Partial Updating: %s", YESNO(this->partial_updating_)); | ||||
|   ESP_LOGCONFIG(TAG, "  Full Update Every: %d", this->full_update_every_); | ||||
|   // Log pins | ||||
|   LOG_PIN("  CKV Pin: ", this->ckv_pin_); | ||||
|   LOG_PIN("  CL Pin: ", this->cl_pin_); | ||||
|   LOG_PIN("  GPIO0 Enable Pin: ", this->gpio0_enable_pin_); | ||||
|   LOG_PIN("  GMOD Pin: ", this->gmod_pin_); | ||||
|   LOG_PIN("  LE Pin: ", this->le_pin_); | ||||
|   LOG_PIN("  OE Pin: ", this->oe_pin_); | ||||
|   LOG_PIN("  POWERUP Pin: ", this->powerup_pin_); | ||||
|   LOG_PIN("  SPH Pin: ", this->sph_pin_); | ||||
|   LOG_PIN("  SPV Pin: ", this->spv_pin_); | ||||
|   LOG_PIN("  VCOM Pin: ", this->vcom_pin_); | ||||
|   LOG_PIN("  WAKEUP Pin: ", this->wakeup_pin_); | ||||
|  | ||||
|   LOG_PIN("  Data 0 Pin: ", this->display_data_0_pin_); | ||||
|   LOG_PIN("  Data 1 Pin: ", this->display_data_1_pin_); | ||||
|   LOG_PIN("  Data 2 Pin: ", this->display_data_2_pin_); | ||||
|   LOG_PIN("  Data 3 Pin: ", this->display_data_3_pin_); | ||||
|   LOG_PIN("  Data 4 Pin: ", this->display_data_4_pin_); | ||||
|   LOG_PIN("  Data 5 Pin: ", this->display_data_5_pin_); | ||||
|   LOG_PIN("  Data 6 Pin: ", this->display_data_6_pin_); | ||||
|   LOG_PIN("  Data 7 Pin: ", this->display_data_7_pin_); | ||||
|  | ||||
|   LOG_UPDATE_INTERVAL(this); | ||||
| } | ||||
| void Inkplate6::eink_off_() { | ||||
|   ESP_LOGV(TAG, "Eink off called"); | ||||
|   unsigned long start_time = millis(); | ||||
|   if (panel_on_ == 0) | ||||
|     return; | ||||
|   panel_on_ = 0; | ||||
|   this->gmod_pin_->digital_write(false); | ||||
|   this->oe_pin_->digital_write(false); | ||||
|  | ||||
|   GPIO.out &= ~(get_data_pin_mask_() | (1 << this->cl_pin_->get_pin()) | (1 << this->le_pin_->get_pin())); | ||||
|  | ||||
|   this->sph_pin_->digital_write(false); | ||||
|   this->spv_pin_->digital_write(false); | ||||
|  | ||||
|   this->powerup_pin_->digital_write(false); | ||||
|   this->wakeup_pin_->digital_write(false); | ||||
|   this->vcom_pin_->digital_write(false); | ||||
|  | ||||
|   pins_z_state_(); | ||||
| } | ||||
| void Inkplate6::eink_on_() { | ||||
|   ESP_LOGV(TAG, "Eink on called"); | ||||
|   unsigned long start_time = millis(); | ||||
|   if (panel_on_ == 1) | ||||
|     return; | ||||
|   panel_on_ = 1; | ||||
|   pins_as_outputs_(); | ||||
|   this->wakeup_pin_->digital_write(true); | ||||
|   this->powerup_pin_->digital_write(true); | ||||
|   this->vcom_pin_->digital_write(true); | ||||
|  | ||||
|   this->write_byte(0x01, 0x3F); | ||||
|  | ||||
|   delay(40); | ||||
|  | ||||
|   this->write_byte(0x0D, 0x80); | ||||
|  | ||||
|   delay(2); | ||||
|  | ||||
|   this->read_byte(0x00, &temperature_, 0); | ||||
|  | ||||
|   this->le_pin_->digital_write(false); | ||||
|   this->oe_pin_->digital_write(false); | ||||
|   this->cl_pin_->digital_write(false); | ||||
|   this->sph_pin_->digital_write(true); | ||||
|   this->gmod_pin_->digital_write(true); | ||||
|   this->spv_pin_->digital_write(true); | ||||
|   this->ckv_pin_->digital_write(false); | ||||
|   this->oe_pin_->digital_write(true); | ||||
| } | ||||
| void Inkplate6::fill(Color color) { | ||||
|   ESP_LOGV(TAG, "Fill called"); | ||||
|   unsigned long start_time = millis(); | ||||
|  | ||||
|   if (this->greyscale_) { | ||||
|     uint8_t fill = ((color.red * 2126 / 10000) + (color.green * 7152 / 10000) + (color.blue * 722 / 10000)) >> 5; | ||||
|     for (uint32_t i = 0; i < this->get_buffer_length_(); i++) | ||||
|       this->buffer_[i] = (fill << 4) | fill; | ||||
|   } else { | ||||
|     uint8_t fill = color.is_on() ? 0x00 : 0xFF; | ||||
|     for (uint32_t i = 0; i < this->get_buffer_length_(); i++) | ||||
|       this->partial_buffer_[i] = fill; | ||||
|   } | ||||
|  | ||||
|   ESP_LOGV(TAG, "Fill finished (%lums)", millis() - start_time); | ||||
| } | ||||
| void Inkplate6::display() { | ||||
|   ESP_LOGV(TAG, "Display called"); | ||||
|   unsigned long start_time = millis(); | ||||
|  | ||||
|   if (this->greyscale_) { | ||||
|     this->display3b_(); | ||||
|   } else { | ||||
|     if (this->partial_updating_ && this->partial_update_()) { | ||||
|       ESP_LOGV(TAG, "Display finished (partial) (%lums)", millis() - start_time); | ||||
|       return; | ||||
|     } | ||||
|     this->display1b_(); | ||||
|   } | ||||
|   ESP_LOGV(TAG, "Display finished (full) (%lums)", millis() - start_time); | ||||
| } | ||||
| void Inkplate6::display1b_() { | ||||
|   ESP_LOGV(TAG, "Display1b called"); | ||||
|   unsigned long start_time = millis(); | ||||
|  | ||||
|   for (int i = 0; i < this->get_buffer_length_(); i++) { | ||||
|     this->buffer_[i] &= this->partial_buffer_[i]; | ||||
|     this->buffer_[i] |= this->partial_buffer_[i]; | ||||
|   } | ||||
|  | ||||
|   uint16_t pos; | ||||
|   uint32_t send; | ||||
|   uint8_t data; | ||||
|   uint8_t buffer_value; | ||||
|   eink_on_(); | ||||
|   clean_fast_(0, 1); | ||||
|   clean_fast_(1, 5); | ||||
|   clean_fast_(2, 1); | ||||
|   clean_fast_(0, 5); | ||||
|   clean_fast_(2, 1); | ||||
|   clean_fast_(1, 12); | ||||
|   clean_fast_(2, 1); | ||||
|   clean_fast_(0, 11); | ||||
|  | ||||
|   ESP_LOGV(TAG, "Display1b start loops (%lums)", millis() - start_time); | ||||
|   for (int k = 0; k < 3; k++) { | ||||
|     pos = this->get_buffer_length_() - 1; | ||||
|     vscan_start_(); | ||||
|     for (int i = 0; i < this->get_height_internal(); i++) { | ||||
|       buffer_value = this->buffer_[pos]; | ||||
|       data = LUTB[(buffer_value >> 4) & 0x0F]; | ||||
|       send = ((data & B00000011) << 4) | (((data & B00001100) >> 2) << 18) | (((data & B00010000) >> 4) << 23) | | ||||
|              (((data & B11100000) >> 5) << 25); | ||||
|       hscan_start_(send); | ||||
|       data = LUTB[buffer_value & 0x0F]; | ||||
|       send = ((data & B00000011) << 4) | (((data & B00001100) >> 2) << 18) | (((data & B00010000) >> 4) << 23) | | ||||
|              (((data & B11100000) >> 5) << 25); | ||||
|       GPIO.out_w1ts = (send) | (1 << this->cl_pin_->get_pin()); | ||||
|       GPIO.out_w1tc = get_data_pin_mask_() | (1 << this->cl_pin_->get_pin()); | ||||
|       pos--; | ||||
|  | ||||
|       for (int j = 0; j < (this->get_width_internal() / 8) - 1; j++) { | ||||
|         buffer_value = this->buffer_[pos]; | ||||
|         data = LUTB[(buffer_value >> 4) & 0x0F]; | ||||
|         send = ((data & B00000011) << 4) | (((data & B00001100) >> 2) << 18) | (((data & B00010000) >> 4) << 23) | | ||||
|                (((data & B11100000) >> 5) << 25); | ||||
|         GPIO.out_w1ts = (send) | (1 << this->cl_pin_->get_pin()); | ||||
|         GPIO.out_w1tc = get_data_pin_mask_() | (1 << this->cl_pin_->get_pin()); | ||||
|         data = LUTB[buffer_value & 0x0F]; | ||||
|         send = ((data & B00000011) << 4) | (((data & B00001100) >> 2) << 18) | (((data & B00010000) >> 4) << 23) | | ||||
|                (((data & B11100000) >> 5) << 25); | ||||
|         GPIO.out_w1ts = (send) | (1 << this->cl_pin_->get_pin()); | ||||
|         GPIO.out_w1tc = get_data_pin_mask_() | (1 << this->cl_pin_->get_pin()); | ||||
|         pos--; | ||||
|       } | ||||
|       GPIO.out_w1ts = (send) | (1 << this->cl_pin_->get_pin()); | ||||
|       GPIO.out_w1tc = get_data_pin_mask_() | (1 << this->cl_pin_->get_pin()); | ||||
|       vscan_end_(); | ||||
|     } | ||||
|     delayMicroseconds(230); | ||||
|   } | ||||
|   ESP_LOGV(TAG, "Display1b first loop x %d (%lums)", 3, millis() - start_time); | ||||
|  | ||||
|   pos = this->get_buffer_length_() - 1; | ||||
|   vscan_start_(); | ||||
|   for (int i = 0; i < this->get_height_internal(); i++) { | ||||
|     buffer_value = this->buffer_[pos]; | ||||
|     data = LUT2[(buffer_value >> 4) & 0x0F]; | ||||
|     send = ((data & B00000011) << 4) | (((data & B00001100) >> 2) << 18) | (((data & B00010000) >> 4) << 23) | | ||||
|            (((data & B11100000) >> 5) << 25); | ||||
|     hscan_start_(send); | ||||
|     data = LUT2[buffer_value & 0x0F]; | ||||
|     send = ((data & B00000011) << 4) | (((data & B00001100) >> 2) << 18) | (((data & B00010000) >> 4) << 23) | | ||||
|            (((data & B11100000) >> 5) << 25); | ||||
|     GPIO.out_w1ts = (send) | (1 << this->cl_pin_->get_pin()); | ||||
|     GPIO.out_w1tc = get_data_pin_mask_() | (1 << this->cl_pin_->get_pin()); | ||||
|     pos--; | ||||
|     for (int j = 0; j < (this->get_width_internal() / 8) - 1; j++) { | ||||
|       buffer_value = this->buffer_[pos]; | ||||
|       data = LUT2[(buffer_value >> 4) & 0x0F]; | ||||
|       send = ((data & B00000011) << 4) | (((data & B00001100) >> 2) << 18) | (((data & B00010000) >> 4) << 23) | | ||||
|              (((data & B11100000) >> 5) << 25); | ||||
|       GPIO.out_w1ts = (send) | (1 << this->cl_pin_->get_pin()); | ||||
|       GPIO.out_w1tc = get_data_pin_mask_() | (1 << this->cl_pin_->get_pin()); | ||||
|       data = LUT2[buffer_value & 0x0F]; | ||||
|       send = ((data & B00000011) << 4) | (((data & B00001100) >> 2) << 18) | (((data & B00010000) >> 4) << 23) | | ||||
|              (((data & B11100000) >> 5) << 25); | ||||
|       GPIO.out_w1ts = (send) | (1 << this->cl_pin_->get_pin()); | ||||
|       GPIO.out_w1tc = get_data_pin_mask_() | (1 << this->cl_pin_->get_pin()); | ||||
|       pos--; | ||||
|     } | ||||
|     GPIO.out_w1ts = (send) | (1 << this->cl_pin_->get_pin()); | ||||
|     GPIO.out_w1tc = get_data_pin_mask_() | (1 << this->cl_pin_->get_pin()); | ||||
|     vscan_end_(); | ||||
|   } | ||||
|   delayMicroseconds(230); | ||||
|   ESP_LOGV(TAG, "Display1b second loop (%lums)", millis() - start_time); | ||||
|  | ||||
|   vscan_start_(); | ||||
|   for (int i = 0; i < this->get_height_internal(); i++) { | ||||
|     buffer_value = this->buffer_[pos]; | ||||
|     data = 0b00000000; | ||||
|     send = ((data & B00000011) << 4) | (((data & B00001100) >> 2) << 18) | (((data & B00010000) >> 4) << 23) | | ||||
|            (((data & B11100000) >> 5) << 25); | ||||
|     hscan_start_(send); | ||||
|     GPIO.out_w1ts = (send) | (1 << this->cl_pin_->get_pin()); | ||||
|     GPIO.out_w1tc = get_data_pin_mask_() | (1 << this->cl_pin_->get_pin()); | ||||
|     for (int j = 0; j < (this->get_width_internal() / 8) - 1; j++) { | ||||
|       GPIO.out_w1ts = (send) | (1 << this->cl_pin_->get_pin()); | ||||
|       GPIO.out_w1tc = get_data_pin_mask_() | (1 << this->cl_pin_->get_pin()); | ||||
|       GPIO.out_w1ts = (send) | (1 << this->cl_pin_->get_pin()); | ||||
|       GPIO.out_w1tc = get_data_pin_mask_() | (1 << this->cl_pin_->get_pin()); | ||||
|     } | ||||
|     GPIO.out_w1ts = (send) | (1 << this->cl_pin_->get_pin()); | ||||
|     GPIO.out_w1tc = get_data_pin_mask_() | (1 << this->cl_pin_->get_pin()); | ||||
|     vscan_end_(); | ||||
|   } | ||||
|   delayMicroseconds(230); | ||||
|   ESP_LOGV(TAG, "Display1b third loop (%lums)", millis() - start_time); | ||||
|  | ||||
|   vscan_start_(); | ||||
|   eink_off_(); | ||||
|   this->block_partial_ = false; | ||||
|   this->partial_updates_ = 0; | ||||
|   ESP_LOGV(TAG, "Display1b finished (%lums)", millis() - start_time); | ||||
| } | ||||
| void Inkplate6::display3b_() { | ||||
|   ESP_LOGV(TAG, "Display3b called"); | ||||
|   unsigned long start_time = millis(); | ||||
|  | ||||
|   eink_on_(); | ||||
|   clean_fast_(0, 1); | ||||
|   clean_fast_(1, 12); | ||||
|   clean_fast_(2, 1); | ||||
|   clean_fast_(0, 11); | ||||
|   clean_fast_(2, 1); | ||||
|   clean_fast_(1, 12); | ||||
|   clean_fast_(2, 1); | ||||
|   clean_fast_(0, 11); | ||||
|  | ||||
|   for (int k = 0; k < 8; k++) { | ||||
|     uint32_t pos = this->get_buffer_length_() - 1; | ||||
|     uint32_t send; | ||||
|     uint8_t pix1; | ||||
|     uint8_t pix2; | ||||
|     uint8_t pix3; | ||||
|     uint8_t pix4; | ||||
|     uint8_t pixel; | ||||
|     uint8_t pixel2; | ||||
|  | ||||
|     vscan_start_(); | ||||
|     for (int i = 0; i < this->get_height_internal(); i++) { | ||||
|       pix1 = this->buffer_[pos--]; | ||||
|       pix2 = this->buffer_[pos--]; | ||||
|       pix3 = this->buffer_[pos--]; | ||||
|       pix4 = this->buffer_[pos--]; | ||||
|       pixel = (waveform3Bit[pix1 & 0x07][k] << 6) | (waveform3Bit[(pix1 >> 4) & 0x07][k] << 4) | | ||||
|               (waveform3Bit[pix2 & 0x07][k] << 2) | (waveform3Bit[(pix2 >> 4) & 0x07][k] << 0); | ||||
|       pixel2 = (waveform3Bit[pix3 & 0x07][k] << 6) | (waveform3Bit[(pix3 >> 4) & 0x07][k] << 4) | | ||||
|                (waveform3Bit[pix4 & 0x07][k] << 2) | (waveform3Bit[(pix4 >> 4) & 0x07][k] << 0); | ||||
|  | ||||
|       send = ((pixel & B00000011) << 4) | (((pixel & B00001100) >> 2) << 18) | (((pixel & B00010000) >> 4) << 23) | | ||||
|              (((pixel & B11100000) >> 5) << 25); | ||||
|       hscan_start_(send); | ||||
|       send = ((pixel2 & B00000011) << 4) | (((pixel2 & B00001100) >> 2) << 18) | (((pixel2 & B00010000) >> 4) << 23) | | ||||
|              (((pixel2 & B11100000) >> 5) << 25); | ||||
|       GPIO.out_w1ts = (send) | (1 << this->cl_pin_->get_pin()); | ||||
|       GPIO.out_w1tc = get_data_pin_mask_() | (1 << this->cl_pin_->get_pin()); | ||||
|  | ||||
|       for (int j = 0; j < (this->get_width_internal() / 8) - 1; j++) { | ||||
|         pix1 = this->buffer_[pos--]; | ||||
|         pix2 = this->buffer_[pos--]; | ||||
|         pix3 = this->buffer_[pos--]; | ||||
|         pix4 = this->buffer_[pos--]; | ||||
|         pixel = (waveform3Bit[pix1 & 0x07][k] << 6) | (waveform3Bit[(pix1 >> 4) & 0x07][k] << 4) | | ||||
|                 (waveform3Bit[pix2 & 0x07][k] << 2) | (waveform3Bit[(pix2 >> 4) & 0x07][k] << 0); | ||||
|         pixel2 = (waveform3Bit[pix3 & 0x07][k] << 6) | (waveform3Bit[(pix3 >> 4) & 0x07][k] << 4) | | ||||
|                  (waveform3Bit[pix4 & 0x07][k] << 2) | (waveform3Bit[(pix4 >> 4) & 0x07][k] << 0); | ||||
|  | ||||
|         send = ((pixel & B00000011) << 4) | (((pixel & B00001100) >> 2) << 18) | (((pixel & B00010000) >> 4) << 23) | | ||||
|                (((pixel & B11100000) >> 5) << 25); | ||||
|         GPIO.out_w1ts = (send) | (1 << this->cl_pin_->get_pin()); | ||||
|         GPIO.out_w1tc = get_data_pin_mask_() | (1 << this->cl_pin_->get_pin()); | ||||
|  | ||||
|         send = ((pixel2 & B00000011) << 4) | (((pixel2 & B00001100) >> 2) << 18) | (((pixel2 & B00010000) >> 4) << 23) | | ||||
|                (((pixel2 & B11100000) >> 5) << 25); | ||||
|         GPIO.out_w1ts = (send) | (1 << this->cl_pin_->get_pin()); | ||||
|         GPIO.out_w1tc = get_data_pin_mask_() | (1 << this->cl_pin_->get_pin()); | ||||
|       } | ||||
|       GPIO.out_w1ts = (send) | (1 << this->cl_pin_->get_pin()); | ||||
|       GPIO.out_w1tc = get_data_pin_mask_() | (1 << this->cl_pin_->get_pin()); | ||||
|       vscan_end_(); | ||||
|     } | ||||
|     delayMicroseconds(230); | ||||
|   } | ||||
|   clean_fast_(2, 1); | ||||
|   clean_fast_(3, 1); | ||||
|   vscan_start_(); | ||||
|   eink_off_(); | ||||
|   ESP_LOGV(TAG, "Display3b finished (%lums)", millis() - start_time); | ||||
| } | ||||
| bool Inkplate6::partial_update_() { | ||||
|   ESP_LOGV(TAG, "Partial update called"); | ||||
|   unsigned long start_time = millis(); | ||||
|   if (this->greyscale_) | ||||
|     return false; | ||||
|   if (this->block_partial_) | ||||
|     return false; | ||||
|  | ||||
|   this->partial_updates_++; | ||||
|  | ||||
|   uint16_t pos = this->get_buffer_length_() - 1; | ||||
|   uint32_t send; | ||||
|   uint8_t data; | ||||
|   uint8_t diffw, diffb; | ||||
|   uint32_t n = (this->get_buffer_length_() * 2) - 1; | ||||
|  | ||||
|   for (int i = 0; i < this->get_height_internal(); i++) { | ||||
|     for (int j = 0; j < (this->get_width_internal() / 8); j++) { | ||||
|       diffw = (this->buffer_[pos] ^ this->partial_buffer_[pos]) & ~(this->partial_buffer_[pos]); | ||||
|       diffb = (this->buffer_[pos] ^ this->partial_buffer_[pos]) & this->partial_buffer_[pos]; | ||||
|       pos--; | ||||
|       this->partial_buffer_2_[n--] = LUTW[diffw >> 4] & LUTB[diffb >> 4]; | ||||
|       this->partial_buffer_2_[n--] = LUTW[diffw & 0x0F] & LUTB[diffb & 0x0F]; | ||||
|     } | ||||
|   } | ||||
|   ESP_LOGV(TAG, "Partial update buffer built after (%lums)", millis() - start_time); | ||||
|  | ||||
|   eink_on_(); | ||||
|   for (int k = 0; k < 5; k++) { | ||||
|     vscan_start_(); | ||||
|     n = (this->get_buffer_length_() * 2) - 1; | ||||
|     for (int i = 0; i < this->get_height_internal(); i++) { | ||||
|       data = this->partial_buffer_2_[n--]; | ||||
|       send = ((data & B00000011) << 4) | (((data & B00001100) >> 2) << 18) | (((data & B00010000) >> 4) << 23) | | ||||
|              (((data & B11100000) >> 5) << 25); | ||||
|       hscan_start_(send); | ||||
|       for (int j = 0; j < (this->get_width_internal() / 4) - 1; j++) { | ||||
|         data = this->partial_buffer_2_[n--]; | ||||
|         send = ((data & B00000011) << 4) | (((data & B00001100) >> 2) << 18) | (((data & B00010000) >> 4) << 23) | | ||||
|                (((data & B11100000) >> 5) << 25); | ||||
|         GPIO.out_w1ts = (send) | (1 << this->cl_pin_->get_pin()); | ||||
|         GPIO.out_w1tc = get_data_pin_mask_() | (1 << this->cl_pin_->get_pin()); | ||||
|       } | ||||
|       GPIO.out_w1ts = (send) | (1 << this->cl_pin_->get_pin()); | ||||
|       GPIO.out_w1tc = get_data_pin_mask_() | (1 << this->cl_pin_->get_pin()); | ||||
|       vscan_end_(); | ||||
|     } | ||||
|     delayMicroseconds(230); | ||||
|     ESP_LOGV(TAG, "Partial update loop k=%d (%lums)", k, millis() - start_time); | ||||
|   } | ||||
|   clean_fast_(2, 2); | ||||
|   clean_fast_(3, 1); | ||||
|   vscan_start_(); | ||||
|   eink_off_(); | ||||
|  | ||||
|   for (int i = 0; i < this->get_buffer_length_(); i++) { | ||||
|     this->buffer_[i] = this->partial_buffer_[i]; | ||||
|   } | ||||
|   ESP_LOGV(TAG, "Partial update finished (%lums)", millis() - start_time); | ||||
|   return true; | ||||
| } | ||||
| void Inkplate6::vscan_start_() { | ||||
|   this->ckv_pin_->digital_write(true); | ||||
|   delayMicroseconds(7); | ||||
|   this->spv_pin_->digital_write(false); | ||||
|   delayMicroseconds(10); | ||||
|   this->ckv_pin_->digital_write(false); | ||||
|   delayMicroseconds(0); | ||||
|   this->ckv_pin_->digital_write(true); | ||||
|   delayMicroseconds(8); | ||||
|   this->spv_pin_->digital_write(true); | ||||
|   delayMicroseconds(10); | ||||
|   this->ckv_pin_->digital_write(false); | ||||
|   delayMicroseconds(0); | ||||
|   this->ckv_pin_->digital_write(true); | ||||
|   delayMicroseconds(18); | ||||
|   this->ckv_pin_->digital_write(false); | ||||
|   delayMicroseconds(0); | ||||
|   this->ckv_pin_->digital_write(true); | ||||
|   delayMicroseconds(18); | ||||
|   this->ckv_pin_->digital_write(false); | ||||
|   delayMicroseconds(0); | ||||
|   this->ckv_pin_->digital_write(true); | ||||
| } | ||||
| void Inkplate6::vscan_write_() { | ||||
|   this->ckv_pin_->digital_write(false); | ||||
|   this->le_pin_->digital_write(true); | ||||
|   this->le_pin_->digital_write(false); | ||||
|   delayMicroseconds(0); | ||||
|   this->sph_pin_->digital_write(false); | ||||
|   this->cl_pin_->digital_write(true); | ||||
|   this->cl_pin_->digital_write(false); | ||||
|   this->sph_pin_->digital_write(true); | ||||
|   this->ckv_pin_->digital_write(true); | ||||
| } | ||||
| void Inkplate6::hscan_start_(uint32_t d) { | ||||
|   this->sph_pin_->digital_write(false); | ||||
|   GPIO.out_w1ts = (d) | (1 << this->cl_pin_->get_pin()); | ||||
|   GPIO.out_w1tc = get_data_pin_mask_() | (1 << this->cl_pin_->get_pin()); | ||||
|   this->sph_pin_->digital_write(true); | ||||
| } | ||||
| void Inkplate6::vscan_end_() { | ||||
|   this->ckv_pin_->digital_write(false); | ||||
|   this->le_pin_->digital_write(true); | ||||
|   this->le_pin_->digital_write(false); | ||||
|   delayMicroseconds(1); | ||||
|   this->ckv_pin_->digital_write(true); | ||||
| } | ||||
| void Inkplate6::clean() { | ||||
|   ESP_LOGV(TAG, "Clean called"); | ||||
|   unsigned long start_time = millis(); | ||||
|  | ||||
|   eink_on_(); | ||||
|   clean_fast_(0, 1);   // White | ||||
|   clean_fast_(0, 8);   // White to White | ||||
|   clean_fast_(0, 1);   // White to Black | ||||
|   clean_fast_(0, 8);   // Black to Black | ||||
|   clean_fast_(2, 1);   // Black to White | ||||
|   clean_fast_(1, 10);  // White to White | ||||
|   ESP_LOGV(TAG, "Clean finished (%lums)", millis() - start_time); | ||||
| } | ||||
| void Inkplate6::clean_fast_(uint8_t c, uint8_t rep) { | ||||
|   ESP_LOGV(TAG, "Clean fast called with: (%d, %d)", c, rep); | ||||
|   unsigned long start_time = millis(); | ||||
|  | ||||
|   eink_on_(); | ||||
|   uint8_t data = 0; | ||||
|   if (c == 0)  // White | ||||
|     data = B10101010; | ||||
|   else if (c == 1)  // Black | ||||
|     data = B01010101; | ||||
|   else if (c == 2)  // Discharge | ||||
|     data = B00000000; | ||||
|   else if (c == 3)  // Skip | ||||
|     data = B11111111; | ||||
|  | ||||
|   uint32_t send = ((data & B00000011) << 4) | (((data & B00001100) >> 2) << 18) | (((data & B00010000) >> 4) << 23) | | ||||
|                   (((data & B11100000) >> 5) << 25); | ||||
|  | ||||
|   for (int k = 0; k < rep; k++) { | ||||
|     vscan_start_(); | ||||
|     for (int i = 0; i < this->get_height_internal(); i++) { | ||||
|       hscan_start_(send); | ||||
|       GPIO.out_w1ts = (send) | (1 << this->cl_pin_->get_pin()); | ||||
|       GPIO.out_w1tc = get_data_pin_mask_() | (1 << this->cl_pin_->get_pin()); | ||||
|       for (int j = 0; j < this->get_width_internal() / 8; j++) { | ||||
|         GPIO.out_w1ts = (send) | (1 << this->cl_pin_->get_pin()); | ||||
|         GPIO.out_w1tc = get_data_pin_mask_() | (1 << this->cl_pin_->get_pin()); | ||||
|         GPIO.out_w1ts = (send) | (1 << this->cl_pin_->get_pin()); | ||||
|         GPIO.out_w1tc = get_data_pin_mask_() | (1 << this->cl_pin_->get_pin()); | ||||
|       } | ||||
|       GPIO.out_w1ts = (send) | (1 << this->cl_pin_->get_pin()); | ||||
|       GPIO.out_w1tc = get_data_pin_mask_() | (1 << this->cl_pin_->get_pin()); | ||||
|       vscan_end_(); | ||||
|     } | ||||
|     delayMicroseconds(230); | ||||
|     ESP_LOGV(TAG, "Clean fast rep loop %d finished (%lums)", k, millis() - start_time); | ||||
|   } | ||||
|   ESP_LOGV(TAG, "Clean fast finished (%lums)", millis() - start_time); | ||||
| } | ||||
| void Inkplate6::pins_z_state_() { | ||||
|   this->ckv_pin_->pin_mode(INPUT); | ||||
|   this->sph_pin_->pin_mode(INPUT); | ||||
|  | ||||
|   this->oe_pin_->pin_mode(INPUT); | ||||
|   this->gmod_pin_->pin_mode(INPUT); | ||||
|   this->spv_pin_->pin_mode(INPUT); | ||||
|  | ||||
|   this->display_data_0_pin_->pin_mode(INPUT); | ||||
|   this->display_data_1_pin_->pin_mode(INPUT); | ||||
|   this->display_data_2_pin_->pin_mode(INPUT); | ||||
|   this->display_data_3_pin_->pin_mode(INPUT); | ||||
|   this->display_data_4_pin_->pin_mode(INPUT); | ||||
|   this->display_data_5_pin_->pin_mode(INPUT); | ||||
|   this->display_data_6_pin_->pin_mode(INPUT); | ||||
|   this->display_data_7_pin_->pin_mode(INPUT); | ||||
| } | ||||
| void Inkplate6::pins_as_outputs_() { | ||||
|   this->ckv_pin_->pin_mode(OUTPUT); | ||||
|   this->sph_pin_->pin_mode(OUTPUT); | ||||
|  | ||||
|   this->oe_pin_->pin_mode(OUTPUT); | ||||
|   this->gmod_pin_->pin_mode(OUTPUT); | ||||
|   this->spv_pin_->pin_mode(OUTPUT); | ||||
|  | ||||
|   this->display_data_0_pin_->pin_mode(OUTPUT); | ||||
|   this->display_data_1_pin_->pin_mode(OUTPUT); | ||||
|   this->display_data_2_pin_->pin_mode(OUTPUT); | ||||
|   this->display_data_3_pin_->pin_mode(OUTPUT); | ||||
|   this->display_data_4_pin_->pin_mode(OUTPUT); | ||||
|   this->display_data_5_pin_->pin_mode(OUTPUT); | ||||
|   this->display_data_6_pin_->pin_mode(OUTPUT); | ||||
|   this->display_data_7_pin_->pin_mode(OUTPUT); | ||||
| } | ||||
|  | ||||
| }  // namespace inkplate6 | ||||
| }  // namespace esphome | ||||
|  | ||||
| #endif | ||||
							
								
								
									
										157
									
								
								esphome/components/inkplate6/inkplate.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										157
									
								
								esphome/components/inkplate6/inkplate.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,157 @@ | ||||
| #pragma once | ||||
|  | ||||
| #include "esphome/core/component.h" | ||||
| #include "esphome/components/i2c/i2c.h" | ||||
| #include "esphome/components/display/display_buffer.h" | ||||
|  | ||||
| #ifdef ARDUINO_ARCH_ESP32 | ||||
|  | ||||
| namespace esphome { | ||||
| namespace inkplate6 { | ||||
|  | ||||
| class Inkplate6 : public PollingComponent, public display::DisplayBuffer, public i2c::I2CDevice { | ||||
|  public: | ||||
|   const uint8_t LUT2[16] = {B10101010, B10101001, B10100110, B10100101, B10011010, B10011001, B10010110, B10010101, | ||||
|                             B01101010, B01101001, B01100110, B01100101, B01011010, B01011001, B01010110, B01010101}; | ||||
|   const uint8_t LUTW[16] = {B11111111, B11111110, B11111011, B11111010, B11101111, B11101110, B11101011, B11101010, | ||||
|                             B10111111, B10111110, B10111011, B10111010, B10101111, B10101110, B10101011, B10101010}; | ||||
|   const uint8_t LUTB[16] = {B11111111, B11111101, B11110111, B11110101, B11011111, B11011101, B11010111, B11010101, | ||||
|                             B01111111, B01111101, B01110111, B01110101, B01011111, B01011101, B01010111, B01010101}; | ||||
|   const uint8_t pixelMaskLUT[8] = {B00000001, B00000010, B00000100, B00001000, | ||||
|                                    B00010000, B00100000, B01000000, B10000000}; | ||||
|   const uint8_t pixelMaskGLUT[2] = {B00001111, B11110000}; | ||||
|   const uint8_t waveform3Bit[8][8] = {{0, 0, 0, 0, 1, 1, 1, 0}, {1, 2, 2, 2, 1, 1, 1, 0}, {0, 1, 2, 1, 1, 2, 1, 0}, | ||||
|                                       {0, 2, 1, 2, 1, 2, 1, 0}, {0, 0, 0, 1, 1, 1, 2, 0}, {2, 1, 1, 1, 2, 1, 2, 0}, | ||||
|                                       {1, 1, 1, 2, 1, 2, 2, 0}, {0, 0, 0, 0, 0, 0, 2, 0}}; | ||||
|   const uint32_t waveform[50] = { | ||||
|       0x00000008, 0x00000008, 0x00200408, 0x80281888, 0x60a81898, 0x60a8a8a8, 0x60a8a8a8, 0x6068a868, 0x6868a868, | ||||
|       0x6868a868, 0x68686868, 0x6a686868, 0x5a686868, 0x5a686868, 0x5a586a68, 0x5a5a6a68, 0x5a5a6a68, 0x55566a68, | ||||
|       0x55565a64, 0x55555654, 0x55555556, 0x55555556, 0x55555556, 0x55555516, 0x55555596, 0x15555595, 0x95955595, | ||||
|       0x95959595, 0x95949495, 0x94949495, 0x94949495, 0xa4949494, 0x9494a4a4, 0x84a49494, 0x84948484, 0x84848484, | ||||
|       0x84848484, 0x84848484, 0xa5a48484, 0xa9a4a4a8, 0xa9a8a8a8, 0xa5a9a9a4, 0xa5a5a5a4, 0xa1a5a5a1, 0xa9a9a9a9, | ||||
|       0xa9a9a9a9, 0xa9a9a9a9, 0xa9a9a9a9, 0x15151515, 0x11111111}; | ||||
|  | ||||
|   void set_greyscale(bool greyscale) { | ||||
|     this->greyscale_ = greyscale; | ||||
|     this->initialize_(); | ||||
|     this->block_partial_ = true; | ||||
|   } | ||||
|   void set_partial_updating(bool partial_updating) { this->partial_updating_ = partial_updating; } | ||||
|   void set_full_update_every(uint32_t full_update_every) { this->full_update_every_ = full_update_every; } | ||||
|  | ||||
|   void set_display_data_0_pin(GPIOPin *data) { this->display_data_0_pin_ = data; } | ||||
|   void set_display_data_1_pin(GPIOPin *data) { this->display_data_1_pin_ = data; } | ||||
|   void set_display_data_2_pin(GPIOPin *data) { this->display_data_2_pin_ = data; } | ||||
|   void set_display_data_3_pin(GPIOPin *data) { this->display_data_3_pin_ = data; } | ||||
|   void set_display_data_4_pin(GPIOPin *data) { this->display_data_4_pin_ = data; } | ||||
|   void set_display_data_5_pin(GPIOPin *data) { this->display_data_5_pin_ = data; } | ||||
|   void set_display_data_6_pin(GPIOPin *data) { this->display_data_6_pin_ = data; } | ||||
|   void set_display_data_7_pin(GPIOPin *data) { this->display_data_7_pin_ = data; } | ||||
|  | ||||
|   void set_ckv_pin(GPIOPin *ckv) { this->ckv_pin_ = ckv; } | ||||
|   void set_cl_pin(GPIOPin *cl) { this->cl_pin_ = cl; } | ||||
|   void set_gpio0_enable_pin(GPIOPin *gpio0_enable) { this->gpio0_enable_pin_ = gpio0_enable; } | ||||
|   void set_gmod_pin(GPIOPin *gmod) { this->gmod_pin_ = gmod; } | ||||
|   void set_le_pin(GPIOPin *le) { this->le_pin_ = le; } | ||||
|   void set_oe_pin(GPIOPin *oe) { this->oe_pin_ = oe; } | ||||
|   void set_powerup_pin(GPIOPin *powerup) { this->powerup_pin_ = powerup; } | ||||
|   void set_sph_pin(GPIOPin *sph) { this->sph_pin_ = sph; } | ||||
|   void set_spv_pin(GPIOPin *spv) { this->spv_pin_ = spv; } | ||||
|   void set_vcom_pin(GPIOPin *vcom) { this->vcom_pin_ = vcom; } | ||||
|   void set_wakeup_pin(GPIOPin *wakeup) { this->wakeup_pin_ = wakeup; } | ||||
|  | ||||
|   float get_setup_priority() const override; | ||||
|  | ||||
|   void dump_config() override; | ||||
|  | ||||
|   void display(); | ||||
|   void clean(); | ||||
|   void fill(Color color) override; | ||||
|  | ||||
|   void update() override; | ||||
|  | ||||
|   void setup() override; | ||||
|  | ||||
|   uint8_t get_panel_state() { return this->panel_on_; } | ||||
|   bool get_greyscale() { return this->greyscale_; } | ||||
|   bool get_partial_updating() { return this->partial_updating_; } | ||||
|   uint8_t get_temperature() { return this->temperature_; } | ||||
|  | ||||
|  protected: | ||||
|   void draw_absolute_pixel_internal(int x, int y, Color color) override; | ||||
|   void display1b_(); | ||||
|   void display3b_(); | ||||
|   void initialize_(); | ||||
|   bool partial_update_(); | ||||
|   void clean_fast_(uint8_t c, uint8_t rep); | ||||
|  | ||||
|   void hscan_start_(uint32_t d); | ||||
|   void vscan_end_(); | ||||
|   void vscan_start_(); | ||||
|   void vscan_write_(); | ||||
|  | ||||
|   void eink_off_(); | ||||
|   void eink_on_(); | ||||
|  | ||||
|   void setup_pins_(); | ||||
|   void pins_z_state_(); | ||||
|   void pins_as_outputs_(); | ||||
|  | ||||
|   int get_width_internal() override { return 800; } | ||||
|  | ||||
|   int get_height_internal() override { return 600; } | ||||
|  | ||||
|   size_t get_buffer_length_(); | ||||
|  | ||||
|   int get_data_pin_mask_() { | ||||
|     int data = 0; | ||||
|     data |= (1 << this->display_data_0_pin_->get_pin()); | ||||
|     data |= (1 << this->display_data_1_pin_->get_pin()); | ||||
|     data |= (1 << this->display_data_2_pin_->get_pin()); | ||||
|     data |= (1 << this->display_data_3_pin_->get_pin()); | ||||
|     data |= (1 << this->display_data_4_pin_->get_pin()); | ||||
|     data |= (1 << this->display_data_5_pin_->get_pin()); | ||||
|     data |= (1 << this->display_data_6_pin_->get_pin()); | ||||
|     data |= (1 << this->display_data_7_pin_->get_pin()); | ||||
|     return data; | ||||
|   } | ||||
|  | ||||
|   uint8_t panel_on_ = 0; | ||||
|   uint8_t temperature_; | ||||
|  | ||||
|   uint8_t *partial_buffer_{nullptr}; | ||||
|   uint8_t *partial_buffer_2_{nullptr}; | ||||
|  | ||||
|   uint32_t full_update_every_; | ||||
|   uint32_t partial_updates_{0}; | ||||
|  | ||||
|   bool block_partial_; | ||||
|   bool greyscale_; | ||||
|   bool partial_updating_; | ||||
|  | ||||
|   GPIOPin *display_data_0_pin_; | ||||
|   GPIOPin *display_data_1_pin_; | ||||
|   GPIOPin *display_data_2_pin_; | ||||
|   GPIOPin *display_data_3_pin_; | ||||
|   GPIOPin *display_data_4_pin_; | ||||
|   GPIOPin *display_data_5_pin_; | ||||
|   GPIOPin *display_data_6_pin_; | ||||
|   GPIOPin *display_data_7_pin_; | ||||
|  | ||||
|   GPIOPin *ckv_pin_; | ||||
|   GPIOPin *cl_pin_; | ||||
|   GPIOPin *gpio0_enable_pin_; | ||||
|   GPIOPin *gmod_pin_; | ||||
|   GPIOPin *le_pin_; | ||||
|   GPIOPin *oe_pin_; | ||||
|   GPIOPin *powerup_pin_; | ||||
|   GPIOPin *sph_pin_; | ||||
|   GPIOPin *spv_pin_; | ||||
|   GPIOPin *vcom_pin_; | ||||
|   GPIOPin *wakeup_pin_; | ||||
| }; | ||||
|  | ||||
| }  // namespace inkplate6 | ||||
| }  // namespace esphome | ||||
|  | ||||
| #endif | ||||
		Reference in New Issue
	
	Block a user