Skip to content

Commit

Permalink
Merge pull request #183 from mickeprag/160-board_hal
Browse files Browse the repository at this point in the history
160 board HAL refactoring from Micke
  • Loading branch information
martinberlin committed Jun 3, 2022
2 parents 10d54c0 + 30e18f6 commit ba1ec7a
Show file tree
Hide file tree
Showing 26 changed files with 1,390 additions and 684 deletions.
21 changes: 19 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,25 @@ The following list is compiled from past experiences and GitHub issues:
* **The existing image fades / darkens when updating a partial screen region.** Make sure the VCOM voltage is [calibrated](https://epdiy.readthedocs.io/en/latest/getting_started.html#calibrate-vcom) for your specific display.
* **The second third of the image is replaced with the last third.** This seems to be a timing issue we could not yet quite figure out the reason for. For a workarround or suggestions please [join the discussion](https://github.com/vroland/epdiy/issues/15).
* **The ESP does not boot correctly when external periperals are connected.** Make sure not to pull GPIO12 high during boot, as it is a strapping pin internal voltage selection (https://github.com/vroland/epdiy/issues/17).


LilyGo Boards
---------------
There are several differences with these boards.
One particular one is the way the LilyGo handles power to the display the official lilygo code has two states.
This is now handled in epdiy in a different way to the lilygo code.
**epd_poweroff()** completely turns the power off to the display and the other peripherals of the lilygo.
The new function **epd_powerdown()** keeps the peripherals on (this allows the touch functions to continue to work).
**epd_poweroff() should allways be called before sleeping the system**
You can still use touch to wake the screen with the following.
In Arduino it works like this.
`epd_poweroff();`

`epd_deinit();`

`esp_sleep_enable_ext1_wakeup(GPIO_SEL_13, ESP_EXT1_WAKEUP_ANY_HIGH);`

`esp_deep_sleep_start();`

More on E-Paper Displays
------------------------

Expand Down Expand Up @@ -115,4 +133,3 @@ The board and schematic are licensed under a <a rel="license" href="https://crea

Firmware and remaining examples are licensed under the terms of the GNU Lesser GPL version 3.
Utilities are licensed under the terms of the MIT license.

13 changes: 13 additions & 0 deletions src/epd_board.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#pragma once
// This file is only used in the Arduino IDE
// and just includes the IDF component header.

#ifdef __cplusplus
extern "C" {
#endif

#include "epd_driver/include/epd_board.h"

#ifdef __cplusplus
}
#endif
10 changes: 9 additions & 1 deletion src/epd_driver/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@

set(app_sources "epd_driver.c"
"epd_board.c"
"render.c"
"display_ops.c"
"tps65185.c"
Expand All @@ -11,7 +12,14 @@ set(app_sources "epd_driver.c"
"i2s_data_bus.c"
"rmt_pulse.c"
"highlevel.c"
"epd_temperature.c")
"epd_temperature.c"
"board/epd_board_common.c"
"board/epd_board_lilygo_t5_47.c"
"board/epd_board_v2_v3.c"
"board/epd_board_v4.c"
"board/epd_board_v5.c"
"board/epd_board_v6.c"
)


idf_component_register(SRCS ${app_sources} INCLUDE_DIRS "include" REQUIRES esp_adc_cal)
Expand Down
3 changes: 3 additions & 0 deletions src/epd_driver/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ menu "E-Paper Driver"

config EPD_BOARD_REVISION_V6
bool "epdiy v6"

config EPD_BOARD_CUSTOM
bool "Custom board"
endchoice

config EPD_DRIVER_V6_VCOM
Expand Down
35 changes: 35 additions & 0 deletions src/epd_driver/board/epd_board_common.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#include "epd_board.h"
#include "driver/adc.h"
#include "esp_adc_cal.h"
#include "esp_log.h"

static const adc1_channel_t channel = ADC1_CHANNEL_7;
static esp_adc_cal_characteristics_t adc_chars;

#define NUMBER_OF_SAMPLES 100

void epd_board_temperature_init_v2() {
esp_adc_cal_value_t val_type = esp_adc_cal_characterize(
ADC_UNIT_1, ADC_ATTEN_DB_6, ADC_WIDTH_BIT_12, 1100, &adc_chars
);
if (val_type == ESP_ADC_CAL_VAL_EFUSE_TP) {
ESP_LOGI("epd_temperature", "Characterized using Two Point Value\n");
} else if (val_type == ESP_ADC_CAL_VAL_EFUSE_VREF) {
ESP_LOGI("esp_temperature", "Characterized using eFuse Vref\n");
} else {
ESP_LOGI("esp_temperature", "Characterized using Default Vref\n");
}
adc1_config_width(ADC_WIDTH_BIT_12);
adc1_config_channel_atten(channel, ADC_ATTEN_DB_6);
}

float epd_board_ambient_temperature_v2() {
uint32_t value = 0;
for (int i = 0; i < NUMBER_OF_SAMPLES; i++) {
value += adc1_get_raw(channel);
}
value /= NUMBER_OF_SAMPLES;
// voltage in mV
float voltage = esp_adc_cal_raw_to_voltage(value, &adc_chars);
return (voltage - 500.0) / 10.0;
}
8 changes: 8 additions & 0 deletions src/epd_driver/board/epd_board_common.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/**
* @file "epd_board_common.h"
* @brief Common board functions shared between boards.
*/
#pragma once

void epd_board_temperature_init_v2();
float epd_board_ambient_temperature_v2();
218 changes: 218 additions & 0 deletions src/epd_driver/board/epd_board_lilygo_t5_47.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,218 @@
#include "epd_board.h"

#include "../display_ops.h"
#include "../i2s_data_bus.h"
#include "../rmt_pulse.h"

#define CFG_DATA GPIO_NUM_23
#define CFG_CLK GPIO_NUM_18
#define CFG_STR GPIO_NUM_0
#define D7 GPIO_NUM_22
#define D6 GPIO_NUM_21
#define D5 GPIO_NUM_27
#define D4 GPIO_NUM_2
#define D3 GPIO_NUM_19
#define D2 GPIO_NUM_4
#define D1 GPIO_NUM_32
#define D0 GPIO_NUM_33

/* Control Lines */
#define CKV GPIO_NUM_25
#define STH GPIO_NUM_26

#define V4_LATCH_ENABLE GPIO_NUM_15

/* Edges */
#define CKH GPIO_NUM_5

typedef struct {
bool power_disable : 1;
bool pos_power_enable : 1;
bool neg_power_enable : 1;
bool ep_scan_direction : 1;
} epd_config_register_t;

static i2s_bus_config i2s_config = {
.clock = CKH,
.start_pulse = STH,
.data_0 = D0,
.data_1 = D1,
.data_2 = D2,
.data_3 = D3,
.data_4 = D4,
.data_5 = D5,
.data_6 = D6,
.data_7 = D7,
};

static void IRAM_ATTR push_cfg_bit(bool bit) {
gpio_set_level(CFG_CLK, 0);
gpio_set_level(CFG_DATA, bit);
gpio_set_level(CFG_CLK, 1);
}

static epd_config_register_t config_reg;

static void epd_board_init(uint32_t epd_row_width) {
/* Power Control Output/Off */
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[CFG_DATA], PIN_FUNC_GPIO);
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[CFG_CLK], PIN_FUNC_GPIO);
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[CFG_STR], PIN_FUNC_GPIO);
gpio_set_direction(CFG_DATA, GPIO_MODE_OUTPUT);
gpio_set_direction(CFG_CLK, GPIO_MODE_OUTPUT);
gpio_set_direction(CFG_STR, GPIO_MODE_OUTPUT);
fast_gpio_set_lo(CFG_STR);

config_reg.power_disable = true;
config_reg.pos_power_enable = false;
config_reg.neg_power_enable = false;
config_reg.ep_scan_direction = true;

// Setup I2S
// add an offset off dummy bytes to allow for enough timing headroom
i2s_bus_init( &i2s_config, epd_row_width + 32 );

rmt_pulse_init(CKV);
}

static void epd_board_set_ctrl(epd_ctrl_state_t *state, const epd_ctrl_state_t * const mask) {
if (state->ep_sth) {
fast_gpio_set_hi(STH);
} else {
fast_gpio_set_lo(STH);
}

if (mask->ep_output_enable || mask->ep_mode || mask->ep_stv || mask->ep_latch_enable) {
fast_gpio_set_lo(CFG_STR);

// push config bits in reverse order
push_cfg_bit(state->ep_output_enable);
push_cfg_bit(state->ep_mode);
push_cfg_bit(config_reg.ep_scan_direction);
push_cfg_bit(state->ep_stv);

push_cfg_bit(config_reg.neg_power_enable);
push_cfg_bit(config_reg.pos_power_enable);
push_cfg_bit(config_reg.power_disable);
push_cfg_bit(state->ep_latch_enable);

fast_gpio_set_hi(CFG_STR);
}
}

static void epd_board_poweron(epd_ctrl_state_t *state) {
i2s_gpio_attach(&i2s_config);

// This was re-purposed as power enable.
config_reg.ep_scan_direction = true;

// POWERON
epd_ctrl_state_t mask = { // Trigger output to shift register
.ep_stv = true,
};
config_reg.power_disable = false;
epd_board_set_ctrl(state, &mask);
busy_delay(100 * 240);
config_reg.neg_power_enable = true;
epd_board_set_ctrl(state, &mask);
busy_delay(500 * 240);
config_reg.pos_power_enable = true;
epd_board_set_ctrl(state, &mask);
busy_delay(100 * 240);
state->ep_stv = true;
state->ep_sth = true;
mask.ep_sth = true;
epd_board_set_ctrl(state, &mask);
// END POWERON
}

void epd_powerdown_lilygo_t5_47() {
epd_ctrl_state_t *state = epd_ctrl_state();

// This was re-purposed as power enable however it also disables the touch.
// this workaround may still leave power on to epd and as such may cause other
// problems such as grey screen.
epd_ctrl_state_t mask = { // Trigger output to shift register
.ep_stv = true,
};
config_reg.pos_power_enable = false;
epd_board_set_ctrl(state, &mask);
busy_delay(10 * 240);

config_reg.neg_power_enable = false;
config_reg.pos_power_enable = false;
epd_board_set_ctrl(state, &mask);
busy_delay(100 * 240);

state->ep_stv = false;
mask.ep_stv = true;
state->ep_output_enable = false;
mask.ep_output_enable = true;
state->ep_mode = false;
mask.ep_mode = true;
config_reg.power_disable = true;
epd_board_set_ctrl(state, &mask);

i2s_gpio_detach(&i2s_config);
}

static void epd_board_poweroff_common(epd_ctrl_state_t *state) {
// POWEROFF
epd_ctrl_state_t mask = { // Trigger output to shift register
.ep_stv = true,
};
config_reg.pos_power_enable = false;
epd_board_set_ctrl(state, &mask);
busy_delay(10 * 240);

config_reg.neg_power_enable = false;
config_reg.pos_power_enable = false;
epd_board_set_ctrl(state, &mask);
busy_delay(100 * 240);

state->ep_stv = false;
mask.ep_stv = true;
state->ep_output_enable = false;
mask.ep_output_enable = true;
state->ep_mode = false;
mask.ep_mode = true;
config_reg.power_disable = true;
epd_board_set_ctrl(state, &mask);

i2s_gpio_detach(&i2s_config);
// END POWEROFF
}

static void epd_board_poweroff(epd_ctrl_state_t *state) {
// This was re-purposed as power enable.
config_reg.ep_scan_direction = false;
epd_board_poweroff_common(state);
}

static void epd_board_poweroff_touch(epd_ctrl_state_t *state) {
// This was re-purposed as power enable.
config_reg.ep_scan_direction = true;
epd_board_poweroff_common(state);
}

const EpdBoardDefinition epd_board_lilygo_t5_47 = {
.init = epd_board_init,
.deinit = NULL,
.set_ctrl = epd_board_set_ctrl,
.poweron = epd_board_poweron,
.poweroff = epd_board_poweroff,

.temperature_init = NULL,
.ambient_temperature = NULL,
};

const EpdBoardDefinition epd_board_lilygo_t5_47_touch = {
.init = epd_board_init,
.deinit = NULL,
.set_ctrl = epd_board_set_ctrl,
.poweron = epd_board_poweron,
.poweroff = epd_board_poweroff_touch,

.temperature_init = NULL,
.ambient_temperature = NULL,
};

0 comments on commit ba1ec7a

Please sign in to comment.