led_matrix/main/i80_controller_example_main.c

231 lines
7.2 KiB
C
Raw Normal View History

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-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-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-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-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;
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-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
void led_matrix_addr_gpio_init(void)
{
2024-01-29 14:42:04 +08:00
gpio_config_t io_conf = {
.mode = GPIO_MODE_OUTPUT,
2024-01-30 11:54:07 +08:00
.pin_bit_mask = (1ULL << HUB75_LAT_PIN_NUM) |
(1ULL << HUB75_OE_PIN_NUM) |
(1ULL << HUB75_LINE_ADDR_A_PIN_NUM) |
2024-01-29 14:42:04 +08:00
(1ULL << HUB75_LINE_ADDR_B_PIN_NUM) |
(1ULL << HUB75_LINE_ADDR_C_PIN_NUM) |
(1ULL << HUB75_LINE_ADDR_D_PIN_NUM),
2024-01-28 19:03:19 +08:00
};
2024-01-29 14:42:04 +08:00
ESP_ERROR_CHECK(gpio_config(&io_conf));
2024-01-30 11:54:07 +08:00
gpio_config_t io_conf1 = {
.mode = GPIO_MODE_INPUT,
.pin_bit_mask = (1ULL << HUB75_OE_CAPTRUE_PIN_NUM),
};
ESP_ERROR_CHECK(gpio_config(&io_conf1));
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-30 11:54:07 +08:00
#define LEDC_FREQUENCY (480) /* 3840 = 60 * 8 * 8 */
2024-01-29 18:03:08 +08:00
2024-01-30 11:54:07 +08:00
#define LEDC_DUTY_OE (100) /* 先低后高,前面有效,控制亮度 */
#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;
esp_err_t led_matrix_oe_lat_ledc_init(void)
{
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-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);
gpio_set_level(HUB75_LINE_ADDR_A_PIN_NUM, line & 1); /* 行地址A是低位待求证 */
gpio_set_level(HUB75_LINE_ADDR_B_PIN_NUM, (line >> 1) & 1);
gpio_set_level(HUB75_LINE_ADDR_C_PIN_NUM, (line >> 2) & 1);
gpio_set_level(HUB75_LINE_ADDR_D_PIN_NUM, (line >> 3) & 1);
line ++;
if (line == 8) line = 0;
hub75_send_line(io_handle, 0, line);
}
static void hub75_addr_task(void *arg)
{
ESP_LOGI(TAG, "hub75_addr_task");
int oe = 0;
while (1)
{
oe = gpio_get_level(HUB75_OE_CAPTRUE_PIN_NUM);
if (oe == 1)
{
// ESP_LOGI(TAG, "oe = 1");
gpio_set_level(HUB75_LINE_ADDR_A_PIN_NUM, line & 1); /* 行地址A是低位待求证 */
gpio_set_level(HUB75_LINE_ADDR_B_PIN_NUM, (line >> 1) & 1);
gpio_set_level(HUB75_LINE_ADDR_C_PIN_NUM, (line >> 2) & 1);
gpio_set_level(HUB75_LINE_ADDR_D_PIN_NUM, (line >> 3) & 1);
}
}
2024-01-29 18:03:08 +08:00
}
2024-01-29 16:26:00 +08:00
void app_main(void)
{
led_matrix_i80_hub75_bus_init();
led_matrix_addr_gpio_init();
test_init_buf(i80_bus);
2024-01-29 18:03:08 +08:00
led_matrix_oe_lat_ledc_init();
2024-01-29 14:42:04 +08:00
2024-01-30 11:54:07 +08:00
// xTaskCreatePinnedToCore(hub75_addr_task, "hub75_addr", 4096, NULL, 9, NULL, tskNO_AFFINITY);
2024-01-28 19:03:19 +08:00
while (1) {
2024-01-30 11:54:07 +08:00
vTaskDelay(pdMS_TO_TICKS(1000));
2024-01-28 19:03:19 +08:00
}
2024-01-29 14:42:04 +08:00
2024-01-28 19:03:19 +08:00
}