i2c fixes + server improvements
This commit is contained in:
@@ -6,14 +6,19 @@
|
||||
#include "esp_lcd_panel_ops.h"
|
||||
#include "esp_timer.h"
|
||||
#include "esp_lcd_panel_sh1106.h"
|
||||
#include "esp_log.h"
|
||||
#include "ygg_bmp280.h"
|
||||
#include "ygg_lock.h"
|
||||
|
||||
#define I2C_HOST I2C_NUM_0
|
||||
#define EXAMPLE_I2C_MASTER_FREQ_HZ 400000
|
||||
#define EXAMPLE_I2C_MASTER_FREQ_HZ YGG_I2C_FREQ_HZ
|
||||
#define EXAMPLE_LCD_V_RES 64
|
||||
#define EXAMPLE_LCD_H_RES 128
|
||||
#define EXAMPLE_LVGL_PALETTE_SIZE 8
|
||||
#define SH1106_I2C_SDA_GPIO 19
|
||||
#define SH1106_I2C_SCL_GPIO 23
|
||||
#define SH1106_I2C_SDA_GPIO I2C_MASTER_SDA
|
||||
#define SH1106_I2C_SCL_GPIO I2C_MASTER_SCL
|
||||
|
||||
static const char *TAG = "ygg_sh1106";
|
||||
|
||||
static uint8_t oled_buffer[EXAMPLE_LCD_H_RES * EXAMPLE_LCD_V_RES / 8];
|
||||
|
||||
@@ -51,8 +56,21 @@ static void example_lvgl_flush_cb(lv_display_t *disp, const lv_area_t *area, uin
|
||||
}
|
||||
}
|
||||
}
|
||||
// pass the draw buffer to the driver
|
||||
esp_lcd_panel_draw_bitmap(panel_handle, x1, y1, x2 + 1, y2 + 1, oled_buffer);
|
||||
// pass the draw buffer to the driver.
|
||||
// Cały transfer pod wspólnym mutexem I2C - BMP280 (i2cdev) używa
|
||||
// tego samego busa. Bez tego odczyt sensora potrafi wejść w środek
|
||||
// rysowania -> I2C hardware timeout po obu stronach.
|
||||
// UWAGA: nie bierzemy tu mutexa LVGL - flush jest wołany z lvgl_task
|
||||
// już pod mutexem LVGL (z lv_timer_handler). Branie go tu = deadlock.
|
||||
if (ygg_i2c_lock_take(pdMS_TO_TICKS(1000))) {
|
||||
esp_err_t err = esp_lcd_panel_draw_bitmap(panel_handle, x1, y1, x2 + 1, y2 + 1, oled_buffer);
|
||||
ygg_i2c_lock_give();
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGW(TAG, "draw_bitmap failed: %s", esp_err_to_name(err));
|
||||
}
|
||||
} else {
|
||||
ESP_LOGW(TAG, "I2C busy, skipping flush");
|
||||
}
|
||||
lv_display_flush_ready(disp);
|
||||
}
|
||||
|
||||
@@ -71,7 +89,8 @@ void ygg_init_tick_cb() {
|
||||
}
|
||||
|
||||
lv_display_t* ygg_sh1106_init() {
|
||||
ESP_ERROR_CHECK(i2cdev_init());
|
||||
// UWAGA: i2cdev_init() + ygg_lock_init() robi app_main() raz przed
|
||||
// wszystkimi initami. Tutaj już nie tworzymy magistrali.
|
||||
|
||||
static i2c_dev_t oled_i2c_dev;
|
||||
memset(&oled_i2c_dev, 0, sizeof(oled_i2c_dev));
|
||||
@@ -102,6 +121,9 @@ lv_display_t* ygg_sh1106_init() {
|
||||
// Create the i2c io handle
|
||||
esp_lcd_panel_io_handle_t io_handle = NULL;
|
||||
esp_lcd_panel_io_i2c_config_t io_config = ESP_SH1106_DEFAULT_IO_CONFIG;
|
||||
// Zejście z domyślnych 400kHz na 100kHz - wspólna magistrala z BMP280,
|
||||
// pająk + słabe pull-upy. 400kHz/1MHz = timeouty.
|
||||
io_config.scl_speed_hz = EXAMPLE_I2C_MASTER_FREQ_HZ;
|
||||
ESP_ERROR_CHECK(esp_lcd_new_panel_io_i2c(i2c_bus_handle, &io_config, &io_handle));
|
||||
|
||||
|
||||
@@ -149,9 +171,16 @@ lv_display_t* ygg_sh1106_init() {
|
||||
}
|
||||
|
||||
void ygg_set_display_label(lv_display_t *display, lv_obj_t *label, const char *str) {
|
||||
// LVGL nie jest thread-safe. Ta funkcja jest wołana z sensor_task,
|
||||
// a lv_timer_handler chodzi w lvgl_task - wszystko pod jednym mutexem.
|
||||
if (!ygg_lvgl_lock_take(pdMS_TO_TICKS(500))) {
|
||||
ESP_LOGW(TAG, "LVGL busy, skipping label update");
|
||||
return;
|
||||
}
|
||||
lv_label_set_text(label, str);
|
||||
/* Size of the screen (if you use rotation 90 or 270, please use lv_display_get_vertical_resolution) */
|
||||
lv_obj_set_width(label, lv_display_get_horizontal_resolution(display));
|
||||
lv_obj_set_style_text_align(label, LV_TEXT_ALIGN_CENTER, 0);
|
||||
lv_obj_align(label, LV_ALIGN_TOP_MID, 0, 0);
|
||||
ygg_lvgl_lock_give();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user