2024-01-28 19:03:19 +08:00
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
#include "freertos/FreeRTOS.h"
|
|
|
|
|
#include "freertos/task.h"
|
|
|
|
|
#include "esp_timer.h"
|
2024-01-29 14:42:04 +08:00
|
|
|
|
#include "esp_lcd_panel_io_i80_hub75.h"
|
2024-01-28 19:03:19 +08:00
|
|
|
|
#include "esp_lcd_panel_ops.h"
|
|
|
|
|
#include "driver/gpio.h"
|
|
|
|
|
#include "esp_err.h"
|
|
|
|
|
#include "esp_log.h"
|
2024-01-29 18:03:08 +08:00
|
|
|
|
#include "esp_check.h"
|
2024-01-28 19:03:19 +08:00
|
|
|
|
#include "esp_rom_sys.h"
|
2024-01-29 18:03:08 +08:00
|
|
|
|
#include "hal/ledc_hal.h"
|
|
|
|
|
#include "driver/ledc.h"
|
2024-01-31 11:04:31 +08:00
|
|
|
|
#include "soc/rtc_cntl_reg.h"
|
|
|
|
|
#include "soc/sens_reg.h"
|
|
|
|
|
#include "soc/rtc_periph.h"
|
|
|
|
|
#include "driver/rtc_io.h"
|
|
|
|
|
#include "ulp_riscv.h"
|
|
|
|
|
#include "ulp_main.h"
|
2024-01-29 18:03:08 +08:00
|
|
|
|
|
2024-01-28 19:03:19 +08:00
|
|
|
|
|
|
|
|
|
static const char *TAG = "led matrix";
|
|
|
|
|
|
|
|
|
|
#define HUB75_CLOCK_HZ (10 * 1000 * 1000)
|
2024-01-29 16:26:00 +08:00
|
|
|
|
#define HUB75_MAX_SCAN_TIMES (8) /* 扫描次数是8次,也就是每一行会被扫8次,用于全彩显示 */
|
|
|
|
|
#define HUB75_MAX_SCAN_LINE (8) /* 最多扫描行 */
|
|
|
|
|
#define HUB75_MAX_TRANSFER_DATA_NUM (128) /* 最多发送128个uint16数据 */
|
|
|
|
|
#define HUB75_MAX_TRANSFER_BUTES (HUB75_MAX_TRANSFER_DATA_NUM * 2)
|
2024-01-30 14:14:24 +08:00
|
|
|
|
#define HUB75_WIDTH (64)
|
|
|
|
|
#define HUB75_HEIGHT (32)
|
2024-01-28 19:03:19 +08:00
|
|
|
|
|
|
|
|
|
#define HUB75_LINE_ADDR_A_PIN_NUM 33
|
|
|
|
|
#define HUB75_LINE_ADDR_B_PIN_NUM 34
|
|
|
|
|
#define HUB75_LINE_ADDR_C_PIN_NUM 35
|
|
|
|
|
#define HUB75_LINE_ADDR_D_PIN_NUM 36
|
|
|
|
|
#define HUB75_LAT_PIN_NUM 8
|
|
|
|
|
#define HUB75_OE_PIN_NUM 21
|
|
|
|
|
#define HUB75_CLK_PIN_NUM 7
|
2024-01-30 11:54:07 +08:00
|
|
|
|
#define HUB75_OE_CAPTRUE_PIN_NUM 18
|
|
|
|
|
|
2024-01-31 11:04:31 +08:00
|
|
|
|
#define HUB75_OE_CAPTRUE__RTC_PIN_NUM GPIO_NUM_18
|
|
|
|
|
#define HUB75_LINE_ADDR_A_RTC_PIN_NUM GPIO_NUM_16
|
|
|
|
|
#define HUB75_LINE_ADDR_B_RTC_PIN_NUM GPIO_NUM_15
|
|
|
|
|
#define HUB75_LINE_ADDR_C_RTC_PIN_NUM GPIO_NUM_14
|
|
|
|
|
#define HUB75_LINE_ADDR_D_RTC_PIN_NUM GPIO_NUM_13
|
|
|
|
|
|
|
|
|
|
|
2024-01-29 14:42:04 +08:00
|
|
|
|
#define HUB75_G0 1
|
|
|
|
|
#define HUB75_R0 2
|
2024-01-28 19:03:19 +08:00
|
|
|
|
#define HUB75_B0 3
|
2024-01-29 14:42:04 +08:00
|
|
|
|
#define HUB75_G1 4
|
|
|
|
|
#define HUB75_R1 5
|
2024-01-28 19:03:19 +08:00
|
|
|
|
#define HUB75_B1 6
|
2024-01-29 14:42:04 +08:00
|
|
|
|
#define HUB75_G2 37
|
|
|
|
|
#define HUB75_R2 38
|
2024-01-28 19:03:19 +08:00
|
|
|
|
#define HUB75_B2 39
|
2024-01-29 14:42:04 +08:00
|
|
|
|
#define HUB75_G3 40
|
|
|
|
|
#define HUB75_R3 41
|
2024-01-28 19:03:19 +08:00
|
|
|
|
#define HUB75_B3 42
|
|
|
|
|
|
|
|
|
|
#define PSRAM_DATA_ALIGNMENT 64
|
|
|
|
|
|
|
|
|
|
typedef unsigned char uint8_t;
|
|
|
|
|
typedef unsigned short int uint16_t;
|
|
|
|
|
|
2024-01-31 13:05:20 +08:00
|
|
|
|
|
2024-01-29 16:26:00 +08:00
|
|
|
|
esp_lcd_i80_hub75_bus_handle_t i80_bus = NULL;
|
|
|
|
|
esp_lcd_panel_io_handle_t io_handle = NULL;
|
2024-01-31 13:05:20 +08:00
|
|
|
|
static void led_matrix_i80_hub75_bus_init(void)
|
2024-01-28 19:03:19 +08:00
|
|
|
|
{
|
|
|
|
|
/* 8080总线配置 */
|
|
|
|
|
ESP_LOGI(TAG, "Initialize Intel 8080 bus");
|
2024-01-29 14:42:04 +08:00
|
|
|
|
esp_lcd_i80_hub75_bus_config_t bus_config = {
|
2024-01-28 19:03:19 +08:00
|
|
|
|
.clk_src = HUB75_CLK_PIN_NUM,
|
|
|
|
|
.wr_gpio_num = HUB75_CLK_PIN_NUM,
|
|
|
|
|
.data_gpio_nums = {
|
|
|
|
|
HUB75_R0,
|
|
|
|
|
HUB75_G0,
|
|
|
|
|
HUB75_B0,
|
|
|
|
|
HUB75_R1,
|
|
|
|
|
HUB75_G1,
|
|
|
|
|
HUB75_B1,
|
|
|
|
|
HUB75_R2,
|
|
|
|
|
HUB75_G2,
|
|
|
|
|
HUB75_B2,
|
|
|
|
|
HUB75_R3,
|
|
|
|
|
HUB75_G3,
|
|
|
|
|
HUB75_B3,
|
|
|
|
|
-1,
|
|
|
|
|
-1,
|
|
|
|
|
-1,
|
|
|
|
|
-1,
|
|
|
|
|
},
|
|
|
|
|
.bus_width = 16,
|
2024-01-29 16:26:00 +08:00
|
|
|
|
.max_transfer_bytes = HUB75_MAX_TRANSFER_BUTES, /* 每次发一行 */
|
|
|
|
|
.max_scan_line = HUB75_MAX_SCAN_LINE,
|
|
|
|
|
.max_scan_times = HUB75_MAX_SCAN_TIMES,
|
2024-01-30 14:14:24 +08:00
|
|
|
|
.height = HUB75_HEIGHT,
|
|
|
|
|
.width = HUB75_WIDTH,
|
2024-01-28 19:03:19 +08:00
|
|
|
|
.psram_trans_align = PSRAM_DATA_ALIGNMENT,
|
|
|
|
|
.sram_trans_align = 4,
|
|
|
|
|
};
|
2024-01-29 14:42:04 +08:00
|
|
|
|
ESP_ERROR_CHECK(esp_lcd_new_i80_hub75_bus(&bus_config, &i80_bus));
|
2024-01-28 19:03:19 +08:00
|
|
|
|
|
|
|
|
|
/* 8080IO设备申请 */
|
2024-01-29 14:42:04 +08:00
|
|
|
|
esp_lcd_panel_io_i80_hub75_config_t io_config = {
|
2024-01-28 19:03:19 +08:00
|
|
|
|
.cs_gpio_num = -1,
|
|
|
|
|
.pclk_hz = HUB75_CLOCK_HZ,
|
|
|
|
|
.trans_queue_depth = 10,
|
2024-01-29 14:42:04 +08:00
|
|
|
|
.flags = {
|
|
|
|
|
.pclk_idle_low = 1,
|
|
|
|
|
},
|
|
|
|
|
.on_color_trans_done = NULL,
|
2024-01-28 19:03:19 +08:00
|
|
|
|
.user_ctx = NULL,
|
|
|
|
|
.lcd_cmd_bits = 0,
|
|
|
|
|
.lcd_param_bits = 0,
|
|
|
|
|
};
|
2024-01-29 14:42:04 +08:00
|
|
|
|
ESP_ERROR_CHECK(esp_lcd_new_panel_io_i80_hub75(i80_bus, &io_config, &io_handle));
|
2024-01-29 16:26:00 +08:00
|
|
|
|
}
|
2024-01-29 14:42:04 +08:00
|
|
|
|
|
2024-01-29 16:26:00 +08:00
|
|
|
|
|
2024-01-29 18:03:08 +08:00
|
|
|
|
#define LEDC_MODE LEDC_LOW_SPEED_MODE
|
|
|
|
|
#define LEDC_TIMER LEDC_TIMER_0
|
|
|
|
|
#define LEDC_DUTY_RES LEDC_TIMER_11_BIT
|
2024-01-31 17:52:23 +08:00
|
|
|
|
#define LEDC_FREQUENCY (60 * HUB75_MAX_SCAN_TIMES * HUB75_MAX_SCAN_LINE)
|
2024-01-29 18:03:08 +08:00
|
|
|
|
|
2024-01-30 14:14:24 +08:00
|
|
|
|
#define LEDC_DUTY_OE (1000) /* 先低后高,前面有效,控制亮度 */
|
2024-01-30 11:54:07 +08:00
|
|
|
|
#define LEDC_DUTY_LAT (2048 - 5) /* 高电平锁存 */
|
2024-01-29 18:03:08 +08:00
|
|
|
|
|
|
|
|
|
static void IRAM_ATTR ledc_timer_ovf_isr(void *arg);
|
|
|
|
|
extern esp_err_t ledc_set_timer_ovf_intr(ledc_mode_t speed_mode, ledc_channel_t channel, int enbale);
|
2024-01-30 11:54:07 +08:00
|
|
|
|
extern void ledc_clear_timer_ovf_intr_status(ledc_timer_t timer_num);
|
2024-01-29 18:03:08 +08:00
|
|
|
|
static ledc_isr_handle_t s_ledc_time_isr_handle = NULL;
|
|
|
|
|
|
2024-01-31 13:05:20 +08:00
|
|
|
|
static esp_err_t led_matrix_oe_lat_ledc_init(void)
|
2024-01-29 18:03:08 +08:00
|
|
|
|
{
|
|
|
|
|
ESP_LOGI(TAG, "led_matrix_oe_lat_ledc_init");
|
|
|
|
|
|
|
|
|
|
ledc_timer_config_t ledc_timer = {
|
|
|
|
|
.speed_mode = LEDC_MODE,
|
|
|
|
|
.timer_num = LEDC_TIMER,
|
|
|
|
|
.duty_resolution = LEDC_DUTY_RES,
|
|
|
|
|
.freq_hz = LEDC_FREQUENCY,
|
|
|
|
|
.clk_cfg = LEDC_AUTO_CLK};
|
|
|
|
|
ESP_ERROR_CHECK(ledc_timer_config(&ledc_timer));
|
|
|
|
|
|
|
|
|
|
ledc_channel_config_t ledc_channel_oe = {
|
|
|
|
|
.speed_mode = LEDC_MODE,
|
|
|
|
|
.channel = LEDC_CHANNEL_0,
|
|
|
|
|
.timer_sel = LEDC_TIMER,
|
|
|
|
|
.intr_type = LEDC_INTR_DISABLE,
|
|
|
|
|
.gpio_num = HUB75_OE_PIN_NUM,
|
|
|
|
|
.duty = LEDC_DUTY_OE,
|
|
|
|
|
.flags.output_invert = 1,
|
|
|
|
|
.hpoint = 0};
|
|
|
|
|
ledc_channel_config_t ledc_channel_lat = {
|
|
|
|
|
.speed_mode = LEDC_MODE,
|
|
|
|
|
.channel = LEDC_CHANNEL_1,
|
|
|
|
|
.timer_sel = LEDC_TIMER,
|
|
|
|
|
.intr_type = LEDC_INTR_DISABLE,
|
|
|
|
|
.gpio_num = HUB75_LAT_PIN_NUM,
|
|
|
|
|
.duty = LEDC_DUTY_LAT,
|
2024-01-30 11:54:07 +08:00
|
|
|
|
.flags.output_invert = 1,
|
2024-01-29 18:03:08 +08:00
|
|
|
|
.hpoint = 0};
|
|
|
|
|
ESP_ERROR_CHECK(ledc_channel_config(&ledc_channel_oe));
|
|
|
|
|
ESP_ERROR_CHECK(ledc_channel_config(&ledc_channel_lat));
|
|
|
|
|
|
|
|
|
|
/* 中断配置 */
|
|
|
|
|
ledc_set_timer_ovf_intr(LEDC_MODE, LEDC_TIMER, false);
|
|
|
|
|
int isr_flags = ESP_INTR_FLAG_LEVEL2;
|
2024-01-30 11:54:07 +08:00
|
|
|
|
int ret = ledc_isr_register(ledc_timer_ovf_isr, i80_bus, isr_flags, &s_ledc_time_isr_handle);
|
2024-01-29 18:03:08 +08:00
|
|
|
|
ESP_GOTO_ON_ERROR(ret, err, TAG, "install interrupt failed");
|
|
|
|
|
ledc_set_timer_ovf_intr(LEDC_MODE, LEDC_TIMER, true);
|
|
|
|
|
|
|
|
|
|
return ESP_OK;
|
|
|
|
|
err:
|
|
|
|
|
return ESP_FAIL;
|
|
|
|
|
}
|
|
|
|
|
|
2024-01-31 13:05:20 +08:00
|
|
|
|
|
2024-01-30 14:14:24 +08:00
|
|
|
|
static int times = 0;
|
2024-01-30 11:54:07 +08:00
|
|
|
|
static int line = 0; /* 本次扫描行,32行16扫,一次显示两行 */
|
2024-01-29 18:03:08 +08:00
|
|
|
|
static void IRAM_ATTR ledc_timer_ovf_isr(void *arg)
|
|
|
|
|
{
|
2024-01-30 11:54:07 +08:00
|
|
|
|
ledc_clear_timer_ovf_intr_status(LEDC_TIMER_0);
|
|
|
|
|
line ++;
|
2024-01-30 14:14:24 +08:00
|
|
|
|
if (line == HUB75_MAX_SCAN_LINE)
|
|
|
|
|
{
|
|
|
|
|
line = 0;
|
|
|
|
|
times ++;
|
|
|
|
|
if (times == HUB75_MAX_SCAN_TIMES)
|
|
|
|
|
times = 0;
|
|
|
|
|
}
|
2024-01-31 17:52:23 +08:00
|
|
|
|
|
|
|
|
|
/* ULP处理行地址 */
|
|
|
|
|
ulp_line = line;
|
|
|
|
|
// if (ulp_flag != 0) ESP_LOGE(TAG, "ULP not deal line addr");
|
|
|
|
|
ulp_flag = 1;
|
|
|
|
|
|
2024-01-30 14:14:24 +08:00
|
|
|
|
hub75_send_line(io_handle, times, line);
|
2024-01-30 11:54:07 +08:00
|
|
|
|
}
|
|
|
|
|
|
2024-01-31 11:04:31 +08:00
|
|
|
|
extern const uint8_t ulp_main_bin_start[] asm("_binary_ulp_main_bin_start");
|
|
|
|
|
extern const uint8_t ulp_main_bin_end[] asm("_binary_ulp_main_bin_end");
|
|
|
|
|
static void led_matrix_ulp_risc_init(void)
|
2024-01-30 11:54:07 +08:00
|
|
|
|
{
|
2024-01-31 13:05:20 +08:00
|
|
|
|
ESP_LOGI(TAG, "led_matrix_ulp_risc_init");
|
|
|
|
|
|
2024-01-31 11:04:31 +08:00
|
|
|
|
rtc_gpio_init(HUB75_OE_CAPTRUE__RTC_PIN_NUM);
|
|
|
|
|
rtc_gpio_set_direction(HUB75_OE_CAPTRUE__RTC_PIN_NUM, RTC_GPIO_MODE_INPUT_ONLY);
|
|
|
|
|
rtc_gpio_pulldown_dis(HUB75_OE_CAPTRUE__RTC_PIN_NUM);
|
|
|
|
|
rtc_gpio_pullup_dis(HUB75_OE_CAPTRUE__RTC_PIN_NUM);
|
|
|
|
|
rtc_gpio_hold_en(HUB75_OE_CAPTRUE__RTC_PIN_NUM);
|
2024-01-29 18:03:08 +08:00
|
|
|
|
|
2024-01-31 11:04:31 +08:00
|
|
|
|
rtc_gpio_init(HUB75_LINE_ADDR_A_RTC_PIN_NUM);
|
|
|
|
|
rtc_gpio_set_direction(HUB75_LINE_ADDR_A_RTC_PIN_NUM, RTC_GPIO_MODE_OUTPUT_ONLY);
|
|
|
|
|
rtc_gpio_init(HUB75_LINE_ADDR_B_RTC_PIN_NUM);
|
|
|
|
|
rtc_gpio_set_direction(HUB75_LINE_ADDR_B_RTC_PIN_NUM, RTC_GPIO_MODE_OUTPUT_ONLY);
|
|
|
|
|
rtc_gpio_init(HUB75_LINE_ADDR_C_RTC_PIN_NUM);
|
|
|
|
|
rtc_gpio_set_direction(HUB75_LINE_ADDR_C_RTC_PIN_NUM, RTC_GPIO_MODE_OUTPUT_ONLY);
|
|
|
|
|
rtc_gpio_init(HUB75_LINE_ADDR_D_RTC_PIN_NUM);
|
|
|
|
|
rtc_gpio_set_direction(HUB75_LINE_ADDR_D_RTC_PIN_NUM, RTC_GPIO_MODE_OUTPUT_ONLY);
|
|
|
|
|
|
|
|
|
|
esp_err_t err = ulp_riscv_load_binary(ulp_main_bin_start, (ulp_main_bin_end - ulp_main_bin_start));
|
|
|
|
|
ESP_ERROR_CHECK(err);
|
|
|
|
|
ulp_set_wakeup_period(0, 20000);
|
|
|
|
|
|
|
|
|
|
/* Start the program */
|
|
|
|
|
err = ulp_riscv_run();
|
|
|
|
|
ESP_ERROR_CHECK(err);
|
|
|
|
|
}
|
2024-01-29 16:26:00 +08:00
|
|
|
|
|
2024-01-31 13:05:20 +08:00
|
|
|
|
|
|
|
|
|
void led_matrix_init(void)
|
2024-01-29 16:26:00 +08:00
|
|
|
|
{
|
2024-01-31 13:05:20 +08:00
|
|
|
|
ESP_LOGI(TAG, "led_matrix_init");
|
|
|
|
|
|
2024-01-29 16:26:00 +08:00
|
|
|
|
led_matrix_i80_hub75_bus_init();
|
2024-01-29 18:03:08 +08:00
|
|
|
|
led_matrix_oe_lat_ledc_init();
|
2024-01-31 11:04:31 +08:00
|
|
|
|
led_matrix_ulp_risc_init();
|
2024-01-31 13:05:20 +08:00
|
|
|
|
}
|
2024-01-29 14:42:04 +08:00
|
|
|
|
|
2024-02-01 10:12:44 +08:00
|
|
|
|
/* 设置亮度,规定可调范围0-1800 */
|
2024-01-31 13:05:20 +08:00
|
|
|
|
int led_matrix_set_brightness(int brightness)
|
|
|
|
|
{
|
2024-02-01 10:12:44 +08:00
|
|
|
|
if (brightness < 0 || brightness > 1800)
|
2024-01-31 13:05:20 +08:00
|
|
|
|
{
|
2024-02-01 10:12:44 +08:00
|
|
|
|
ESP_LOGE(TAG, "Invalid brightness value(0-1800): %d", brightness);
|
2024-01-31 13:05:20 +08:00
|
|
|
|
return -1;
|
2024-01-28 19:03:19 +08:00
|
|
|
|
}
|
2024-01-31 13:05:20 +08:00
|
|
|
|
ESP_ERROR_CHECK(ledc_set_duty(LEDC_MODE, LEDC_CHANNEL_0, brightness));
|
|
|
|
|
ESP_ERROR_CHECK(ledc_update_duty(LEDC_MODE, LEDC_CHANNEL_0));
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2024-01-29 14:42:04 +08:00
|
|
|
|
|
2024-01-31 13:05:20 +08:00
|
|
|
|
/* 画点 */
|
|
|
|
|
int led_matrix_draw_point(int x, int y, uint8_t color)
|
|
|
|
|
{
|
|
|
|
|
return hub75_draw_point(io_handle, x, y, color);
|
2024-01-28 19:03:19 +08:00
|
|
|
|
}
|
2024-01-31 13:05:20 +08:00
|
|
|
|
|
|
|
|
|
/* 填充区域 */
|
|
|
|
|
void led_matrix_fill_rectangle(int x0, int y0, int x1, int y1, void *color)
|
|
|
|
|
{
|
|
|
|
|
hub75_fill_rectangle(io_handle, x0, y0, x1, y1, color);
|
|
|
|
|
}
|