Files
matrix-screen-controller/核桃派软件源代码/app/display/native/h618_hub75.h
T

139 lines
3.9 KiB
C

/*
* Native HUB75 refresh driver for WalnutPi ZeroW / Allwinner H618.
*
* GPIO register layout and physical-pin mapping are derived from WalnutPi's
* MIT-licensed gpioc project, commit 220a46267469cc9cb1cbc35cd72f35eb1699a6e8:
* https://github.com/walnutpi/gpioc
*
* This project keeps the upstream MIT license in THIRD_PARTY_NOTICES.md.
*/
#ifndef WALNUTPI_H618_HUB75_H
#define WALNUTPI_H618_HUB75_H
#include <stddef.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
#define HUB75_WIDTH 64
#define HUB75_HEIGHT 64
#define HUB75_SCAN_ROWS 32
#define HUB75_PWM_BITS 7
#define HUB75_INTERNAL_PWM_BITS 11
#define HUB75_PWM_PLANE_OFFSET (HUB75_INTERNAL_PWM_BITS - HUB75_PWM_BITS)
#define HUB75_SCANS_PER_FRAME 1
#define HUB75_FRAME_BYTES (HUB75_WIDTH * HUB75_HEIGHT * 3)
#define HUB75_BITPLANE_WORDS (HUB75_SCAN_ROWS * HUB75_PWM_BITS * HUB75_WIDTH)
#define HUB75_HARDWARE_MAPPING "walnutpi-pi-bank-pwm-oe-v2"
#define HUB75_OE_TIMING_BACKEND "h618-pwm4"
#define HUB75_OE_PWM_TICK_NS 125u
typedef struct hub75_context hub75_context;
typedef struct hub75_config {
int brightness;
int refresh_rate_hz;
int cpu_affinity;
int realtime_priority;
int use_dev_mem;
int fake_pwm5_mode;
int fake_pwm4_stuck;
} hub75_config;
typedef struct hub75_stats {
double actual_refresh_rate_hz;
double panel_scan_rate_hz;
uint64_t completed_frames;
uint64_t completed_scans;
uint64_t deadline_misses;
uint64_t buffer_swaps;
uint64_t submitted_frames;
uint64_t oe_pulse_faults;
uint64_t oe_forced_blanks;
uint64_t max_programmed_oe_ns;
int cpu_affinity;
int cpu_affinity_active;
int realtime_priority;
int realtime_priority_active;
int memory_locked;
int running;
int brightness;
int refresh_rate_hz;
int scans_per_frame;
char governor[32];
char affinity_error[128];
char realtime_error[128];
char memory_lock_error[128];
char oe_timing_backend[32];
char oe_timing_error[256];
char safeoff_error[256];
char last_error[256];
} hub75_stats;
hub75_context *hub75_create(const hub75_config *config, char *error, size_t error_size);
int hub75_start(hub75_context *context);
int hub75_submit_rgb(hub75_context *context, const uint8_t *rgb, size_t length);
int hub75_set_brightness(hub75_context *context, int brightness);
int hub75_set_refresh_rate(hub75_context *context, int refresh_rate_hz);
int hub75_clear(hub75_context *context);
int hub75_get_stats(hub75_context *context, hub75_stats *stats);
void hub75_destroy(hub75_context *context);
const char *hub75_hardware_mapping(void);
int hub75_force_safeoff(int use_dev_mem, char *error, size_t error_size);
/* Pure conversion hook used by tests; output words contain PI0..PI5 colors. */
int hub75_build_bitplanes(
const uint8_t *rgb,
size_t length,
uint16_t *output,
size_t output_words
);
/* Raspberry-Pi-compatible CIE1931 brightness mapping into 11-bit color. */
int hub75_build_bitplanes_for_brightness(
const uint8_t *rgb,
size_t length,
int brightness,
uint16_t *output,
size_t output_words
);
/* Pure 8-bit RGB channel to 11-bit CIE1931 mapping hook. */
uint16_t hub75_map_channel_for_brightness(uint8_t value, int brightness);
/* Pure scan-count hook used by native tests and the benchmark. */
int hub75_scans_per_frame_for_brightness(int brightness);
/* Fixed binary OE weights matching internal bitplanes 4..10. */
uint32_t hub75_oe_ticks_for_plane(
uint64_t scan_slot_ns,
int brightness,
unsigned plane,
uint64_t *remainder
);
typedef struct hub75_fake_registers {
uint32_t mux0;
uint32_t mux1;
uint32_t data;
uint32_t pwm_pccr45;
uint32_t pwm_per;
uint32_t pwm_pcr4;
uint32_t pwm_ppr4;
uint32_t pwm_pcr5;
uint32_t pwm_ppr5;
} hub75_fake_registers;
int hub75_get_fake_registers(
hub75_context *context,
hub75_fake_registers *registers
);
#ifdef __cplusplus
}
#endif
#endif