#include #include #include "sdkconfig.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "esp_lcd_panel_interface.h" #include "esp_lcd_panel_io.h" #include "hub75.h" #include "esp_lcd_panel_ops.h" #include "esp_lcd_panel_commands.h" #include "driver/gpio.h" #include "esp_log.h" #include "esp_check.h" static const char *TAG = "lcd_panel.hub75"; static esp_err_t panel_hub75_del(esp_lcd_panel_t *panel); static esp_err_t panel_hub75_reset(esp_lcd_panel_t *panel); static esp_err_t panel_hub75_init(esp_lcd_panel_t *panel); static esp_err_t panel_hub75_draw_bitmap(esp_lcd_panel_t *panel, int x_start, int y_start, int x_end, int y_end, const void *color_data); static esp_err_t panel_hub75_invert_color(esp_lcd_panel_t *panel, bool invert_color_data); static esp_err_t panel_hub75_mirror(esp_lcd_panel_t *panel, bool mirror_x, bool mirror_y); static esp_err_t panel_hub75_swap_xy(esp_lcd_panel_t *panel, bool swap_axes); static esp_err_t panel_hub75_set_gap(esp_lcd_panel_t *panel, int x_gap, int y_gap); static esp_err_t panel_hub75_disp_on_off(esp_lcd_panel_t *panel, bool off); typedef struct { esp_lcd_panel_t base; esp_lcd_panel_io_handle_t io; int line_addr_num; /* 行地址GPIO数量 */ int line_addr_gpio_num[5]; /* 行地址GPIO */ int lat_gpio_num; /* 行数据锁存GPIO 下降沿 */ int oe_gpio_num; /* 使能显示GPIO 低电平*/ } hub75_panel_t; esp_err_t esp_lcd_new_panel_hub75(const esp_lcd_panel_io_handle_t io, const hub75_panel_config_t *panel_dev_config, esp_lcd_panel_handle_t *ret_panel) { int i; esp_err_t ret = ESP_OK; hub75_panel_t *hub75 = NULL; ESP_GOTO_ON_FALSE(io && panel_dev_config && ret_panel, ESP_ERR_INVALID_ARG, err, TAG, "invalid argument"); hub75 = calloc(1, sizeof(hub75_panel_t)); ESP_GOTO_ON_FALSE(hub75, ESP_ERR_NO_MEM, err, TAG, "no mem for hub75 panel"); /* gpio初始化 */ gpio_config_t io_conf = { .mode = GPIO_MODE_OUTPUT, .pin_bit_mask = (1ULL << panel_dev_config->lat_gpio_num) | (1ULL << panel_dev_config->oe_gpio_num), }; for (i = 0; i < panel_dev_config->line_addr_num; i++) io_conf.pin_bit_mask |= (1ULL << panel_dev_config->line_addr_gpio_num[i]); ESP_GOTO_ON_ERROR(gpio_config(&io_conf), err, TAG, "configure GPIO for hub75 failed"); hub75->line_addr_num = panel_dev_config->line_addr_num; for (i = 0; i < panel_dev_config->line_addr_num; i++) hub75->line_addr_gpio_num[i] = panel_dev_config->line_addr_gpio_num[i]; hub75->lat_gpio_num = panel_dev_config->lat_gpio_num; hub75->oe_gpio_num = panel_dev_config->oe_gpio_num; hub75->io = io; hub75->base.del = panel_hub75_del; hub75->base.reset = panel_hub75_reset; hub75->base.init = panel_hub75_init; hub75->base.draw_bitmap = panel_hub75_draw_bitmap; hub75->base.invert_color = panel_hub75_invert_color; hub75->base.set_gap = panel_hub75_set_gap; hub75->base.mirror = panel_hub75_mirror; hub75->base.swap_xy = panel_hub75_swap_xy; hub75->base.disp_on_off = panel_hub75_disp_on_off; *ret_panel = &(hub75->base); ESP_LOGD(TAG, "new hub75 panel @%p", hub75); return ESP_OK; err: if (hub75) { panel_hub75_del(&(hub75->base)); } return ret; } static esp_err_t panel_hub75_del(esp_lcd_panel_t *panel) { int i; hub75_panel_t *hub75 = __containerof(panel, hub75_panel_t, base); /* 恢复gpio原始状态 */ for (i = 0; i < hub75->line_addr_num; i++) gpio_reset_pin(hub75->line_addr_gpio_num[i]); gpio_reset_pin(hub75->lat_gpio_num); gpio_reset_pin(hub75->oe_gpio_num); ESP_LOGD(TAG, "del hub75 panel @%p", hub75); free(hub75); return ESP_OK; } static esp_err_t panel_hub75_reset(esp_lcd_panel_t *panel) { return ESP_OK; } static esp_err_t panel_hub75_init(esp_lcd_panel_t *panel) { return ESP_OK; } static esp_err_t panel_hub75_draw_bitmap(esp_lcd_panel_t *panel, int x_start, int y_start, int x_end, int y_end, const void *color_data) { hub75_panel_t *hub75 = __containerof(panel, hub75_panel_t, base); assert((x_start < x_end) && (y_start < y_end) && "start position must be smaller than end position"); esp_lcd_panel_io_handle_t io = hub75->io; /* 很重要,在这里进行一行数据的组织和发送 */ // esp_lcd_panel_io_tx_color(io, LCD_CMD_RAMWR, color_data, len); return ESP_OK; } static esp_err_t panel_hub75_invert_color(esp_lcd_panel_t *panel, bool invert_color_data) { return ESP_OK; } static esp_err_t panel_hub75_mirror(esp_lcd_panel_t *panel, bool mirror_x, bool mirror_y) { return ESP_OK; } static esp_err_t panel_hub75_swap_xy(esp_lcd_panel_t *panel, bool swap_axes) { return ESP_OK; } static esp_err_t panel_hub75_set_gap(esp_lcd_panel_t *panel, int x_gap, int y_gap) { return ESP_OK; } static esp_err_t panel_hub75_disp_on_off(esp_lcd_panel_t *panel, bool on_off) { return ESP_OK; }