kopia lustrzana https://github.com/hoglet67/RGBtoHDMI
Support for new driver. Also split profiles into separate folders for each CPLD
rodzic
0baad9bc6b
commit
6187fe05f4
|
@ -96,6 +96,8 @@ file( GLOB core_files
|
|||
cpld_normal.c
|
||||
cpld_atom.h
|
||||
cpld_atom.c
|
||||
cpld_yuv6847.h
|
||||
cpld_yuv6847.c
|
||||
cpld_null.h
|
||||
cpld_null.c
|
||||
geometry.h
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#define DESIGN_NORMAL 0
|
||||
#define DESIGN_ALTERNATIVE 1 // This has now been removed from the code base
|
||||
#define DESIGN_ATOM 2
|
||||
#define DESIGN_YUV6847 3
|
||||
#define DESIGN_NULL 15 // This is when the CPLD is unprogrammed
|
||||
|
||||
typedef struct {
|
||||
|
|
120
src/cpld_atom.c
120
src/cpld_atom.c
|
@ -16,15 +16,9 @@
|
|||
#define NUM_CAL_FRAMES 10
|
||||
|
||||
typedef struct {
|
||||
int dummy;
|
||||
int sp_offset;
|
||||
int filter_c;
|
||||
int filter_l;
|
||||
int invert_l;
|
||||
int lvl_uvpos;
|
||||
int lvl_uvneg;
|
||||
int lvl_ylo;
|
||||
int lvl_yhi;
|
||||
} config_t;
|
||||
|
||||
// Current calibration state for mode 0..6
|
||||
|
@ -45,88 +39,27 @@ static int errors;
|
|||
// The CPLD version number
|
||||
static int cpld_version;
|
||||
|
||||
static int frontend = 0;
|
||||
|
||||
static int supports_invert = 0;
|
||||
|
||||
// =============================================================
|
||||
// Param definitions for OSD
|
||||
// =============================================================
|
||||
|
||||
enum {
|
||||
SETUP,
|
||||
OFFSET,
|
||||
FILTER_C,
|
||||
FILTER_L,
|
||||
INVERT_L,
|
||||
LVL_UVPOS,
|
||||
LVL_UVNEG,
|
||||
LVL_YHI,
|
||||
LVL_YLO
|
||||
|
||||
};
|
||||
|
||||
static param_t params[] = {
|
||||
{ SETUP, "Setup Mode", "setup_mode", 0, 1, 1 },
|
||||
{ OFFSET, "Offset", "offset", 0, 15, 1 },
|
||||
{ FILTER_C, "C Filter", "c_filter", 0, 1, 1 },
|
||||
{ FILTER_L, "L Filter", "l_filter", 0, 1, 1 },
|
||||
{ INVERT_L, "L Invert", "l_invert", 0, 1, 1 },
|
||||
{ LVL_UVPOS, "DAC-A (+UV)","level_uv_pos", 0, 255, 1 },
|
||||
{ LVL_UVNEG, "DAC-B (-UV)","level_uv_neg", 0, 255, 1 },
|
||||
{ LVL_YHI,"DAC-C (Y Hi)", "level_y_hi", 0, 255, 1 },
|
||||
{ LVL_YLO,"DAC-D (Y Lo)", "level_y_lo", 0, 255, 1 },
|
||||
|
||||
{ -1, NULL, NULL, 0, 0, 0 }
|
||||
};
|
||||
|
||||
// =============================================================
|
||||
// Private methods
|
||||
// =============================================================
|
||||
void sendDAC_atom(int dac, int value)
|
||||
{
|
||||
|
||||
switch (frontend) {
|
||||
case 1: // tlc5260 or tlv5260
|
||||
{
|
||||
//log_info("Setting DAC type 1");
|
||||
int packet = dac << 9 | value;
|
||||
RPI_SetGpioValue(STROBE_PIN, 1);
|
||||
delay_in_arm_cycles(1000);
|
||||
for (int i = 0; i < 11; i++) {
|
||||
RPI_SetGpioValue(SP_CLKEN_PIN, 1);
|
||||
RPI_SetGpioValue(SP_DATA_PIN, (packet >> 10) & 1);
|
||||
delay_in_arm_cycles(500);
|
||||
RPI_SetGpioValue(SP_CLKEN_PIN, 0);
|
||||
delay_in_arm_cycles(500);
|
||||
packet <<= 1;
|
||||
}
|
||||
RPI_SetGpioValue(STROBE_PIN, 0);
|
||||
delay_in_arm_cycles(500);
|
||||
RPI_SetGpioValue(STROBE_PIN, 1);
|
||||
RPI_SetGpioValue(SP_DATA_PIN, 0);
|
||||
}
|
||||
break;
|
||||
case 2: // dac084s085
|
||||
{
|
||||
//log_info("Setting DAC type 2");
|
||||
int packet = (dac << 14) | 0x1000 | (value << 4);
|
||||
RPI_SetGpioValue(STROBE_PIN, 1);
|
||||
delay_in_arm_cycles(500);
|
||||
RPI_SetGpioValue(STROBE_PIN, 0);
|
||||
for (int i = 0; i < 16; i++) {
|
||||
RPI_SetGpioValue(SP_CLKEN_PIN, 1);
|
||||
RPI_SetGpioValue(SP_DATA_PIN, (packet >> 15) & 1);
|
||||
delay_in_arm_cycles(500);
|
||||
RPI_SetGpioValue(SP_CLKEN_PIN, 0);
|
||||
delay_in_arm_cycles(500);
|
||||
packet <<= 1;
|
||||
}
|
||||
RPI_SetGpioValue(SP_DATA_PIN, 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
static void write_config(config_t *config) {
|
||||
int sp = 0;
|
||||
int scan_len = 6;
|
||||
|
@ -134,11 +67,6 @@ static void write_config(config_t *config) {
|
|||
sp |= config->filter_c << 4;
|
||||
sp |= config->filter_l << 5;
|
||||
|
||||
if (supports_invert) {
|
||||
sp |= config->invert_l << 6;
|
||||
scan_len++;
|
||||
}
|
||||
|
||||
for (int i = 0; i < scan_len; i++) {
|
||||
RPI_SetGpioValue(SP_DATA_PIN, sp & 1);
|
||||
for (int j = 0; j < 1000; j++);
|
||||
|
@ -152,11 +80,6 @@ static void write_config(config_t *config) {
|
|||
sp >>= 1;
|
||||
}
|
||||
|
||||
sendDAC_atom(0, config->lvl_uvpos); // addr 0 + range 0
|
||||
sendDAC_atom(1, config->lvl_uvneg); // addr 1 + range 0
|
||||
sendDAC_atom(2, config->lvl_ylo); // addr 2 + range 0
|
||||
sendDAC_atom(3, config->lvl_yhi); // addr 3 + range 0
|
||||
|
||||
RPI_SetGpioValue(SP_DATA_PIN, 0);
|
||||
}
|
||||
|
||||
|
@ -192,17 +115,6 @@ static void cpld_init(int version) {
|
|||
}
|
||||
errors = -1;
|
||||
|
||||
int major = (cpld_version >> VERSION_MAJOR_BIT) & 0x0F;
|
||||
//int minor = (cpld_version >> VERSION_MINOR_BIT) & 0x0F;
|
||||
|
||||
// Optional invert parameter
|
||||
// CPLDv3 and beyond support an invertion of video
|
||||
if (major >= 3) {
|
||||
supports_invert = 1;
|
||||
} else {
|
||||
supports_invert = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static int cpld_get_version() {
|
||||
|
@ -295,17 +207,6 @@ static int cpld_get_value(int num) {
|
|||
return config->filter_c;
|
||||
case FILTER_L:
|
||||
return config->filter_l;
|
||||
case INVERT_L:
|
||||
return config->invert_l;
|
||||
case LVL_YLO:
|
||||
return config->lvl_yhi;
|
||||
case LVL_YHI:
|
||||
return config->lvl_ylo;
|
||||
case LVL_UVNEG:
|
||||
return config->lvl_uvneg;
|
||||
case LVL_UVPOS:
|
||||
return config->lvl_uvpos;
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -331,21 +232,6 @@ static void cpld_set_value(int num, int value) {
|
|||
case FILTER_L:
|
||||
config->filter_l = value;
|
||||
break;
|
||||
case INVERT_L:
|
||||
config->invert_l = value;
|
||||
break;
|
||||
case LVL_YLO:
|
||||
config->lvl_yhi = value;
|
||||
break;
|
||||
case LVL_YHI:
|
||||
config->lvl_ylo = value;
|
||||
break;
|
||||
case LVL_UVNEG:
|
||||
config->lvl_uvneg = value;
|
||||
break;
|
||||
case LVL_UVPOS:
|
||||
config->lvl_uvpos = value;
|
||||
break;
|
||||
}
|
||||
write_config(config);
|
||||
}
|
||||
|
@ -380,18 +266,16 @@ static int cpld_get_delay() {
|
|||
}
|
||||
|
||||
static int cpld_frontend_info() {
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void cpld_set_frontend(int value) {
|
||||
frontend = value;
|
||||
write_config(config);
|
||||
}
|
||||
|
||||
|
||||
cpld_t cpld_atom = {
|
||||
.name = "Atom",
|
||||
.default_profile = "Atom_CPLD",
|
||||
.default_profile = "Atom",
|
||||
.init = cpld_init,
|
||||
.get_version = cpld_get_version,
|
||||
.calibrate = cpld_calibrate,
|
||||
|
|
|
@ -318,17 +318,17 @@ unsigned int file_read_profile(char *profile_name, char *sub_profile_name, int u
|
|||
init_filesystem();
|
||||
|
||||
if (sub_profile_name != NULL) {
|
||||
sprintf(path, "%s/%s/%s.txt", SAVED_PROFILE_BASE, profile_name, sub_profile_name);
|
||||
sprintf(path, "%s/%s/%s/%s.txt", SAVED_PROFILE_BASE, cpld->name, profile_name, sub_profile_name);
|
||||
} else {
|
||||
sprintf(path, "%s/%s.txt", SAVED_PROFILE_BASE, profile_name);
|
||||
sprintf(path, "%s/%s/%s.txt", SAVED_PROFILE_BASE, cpld->name, profile_name);
|
||||
}
|
||||
|
||||
result = f_open(&file, path, FA_READ);
|
||||
if (result != FR_OK) {
|
||||
if (sub_profile_name != NULL) {
|
||||
sprintf(path, "%s/%s/%s.txt", PROFILE_BASE, profile_name, sub_profile_name);
|
||||
sprintf(path, "%s/%s/%s/%s.txt", PROFILE_BASE, cpld->name, profile_name, sub_profile_name);
|
||||
} else {
|
||||
sprintf(path, "%s/%s.txt", PROFILE_BASE, profile_name);
|
||||
sprintf(path, "%s/%s/%s.txt", PROFILE_BASE, cpld->name, profile_name);
|
||||
}
|
||||
result = f_open(&file, path, FA_READ);
|
||||
if (result != FR_OK) {
|
||||
|
@ -359,7 +359,9 @@ unsigned int file_read_profile(char *profile_name, char *sub_profile_name, int u
|
|||
}
|
||||
|
||||
if (updatecmd) {
|
||||
result = f_open(&file, "/profile.txt", FA_WRITE | FA_CREATE_ALWAYS);
|
||||
char name[100];
|
||||
sprintf(name, "/profile_%s.txt", cpld->name);
|
||||
result = f_open(&file, name, FA_WRITE | FA_CREATE_ALWAYS);
|
||||
if (result != FR_OK) {
|
||||
log_warn("Failed to open %s (result = %d)", path, result);
|
||||
close_filesystem();
|
||||
|
@ -482,7 +484,9 @@ void scan_sub_profiles(char sub_profile_names[MAX_SUB_PROFILES][MAX_PROFILE_WIDT
|
|||
FRESULT res;
|
||||
DIR dir;
|
||||
static FILINFO fno;
|
||||
char path[100] = "/Profiles/";
|
||||
char path[100] = "/Profiles/";
|
||||
strncat(path, cpld->name, 80);
|
||||
strncat(path, "/", 80);
|
||||
strncat(path, sub_path, 80);
|
||||
init_filesystem();
|
||||
res = f_opendir(&dir, path);
|
||||
|
@ -584,18 +588,24 @@ int file_save(char *dirpath, char *name, char *buffer, unsigned int buffer_size)
|
|||
if (result != FR_OK && result != FR_EXIST) {
|
||||
log_warn("Failed to create dir %s (result = %d)",SAVED_PROFILE_BASE, result);
|
||||
}
|
||||
|
||||
sprintf(path, "%s/%s", SAVED_PROFILE_BASE, cpld->name);
|
||||
|
||||
result = f_mkdir(path);
|
||||
if (result != FR_OK && result != FR_EXIST) {
|
||||
log_warn("Failed to create dir %s (result = %d)",path, result);
|
||||
}
|
||||
|
||||
if (dirpath != NULL) {
|
||||
sprintf(path, "%s/%s", SAVED_PROFILE_BASE, dirpath);
|
||||
sprintf(path, "%s/%s/%s", SAVED_PROFILE_BASE, cpld->name, dirpath);
|
||||
result = f_mkdir(path);
|
||||
if (result != FR_OK && result != FR_EXIST) {
|
||||
log_warn("Failed to create dir %s (result = %d)", dirpath, result);
|
||||
}
|
||||
sprintf(path, "%s/%s/%s.txt", SAVED_PROFILE_BASE, dirpath, name);
|
||||
sprintf(comparison_path, "%s/%s/%s.txt", PROFILE_BASE, dirpath, name);
|
||||
sprintf(path, "%s/%s/%s/%s.txt", SAVED_PROFILE_BASE, cpld->name, dirpath, name);
|
||||
sprintf(comparison_path, "%s/%s/%s/%s.txt", PROFILE_BASE, cpld->name, dirpath, name);
|
||||
} else {
|
||||
sprintf(path, "%s/%s.txt", SAVED_PROFILE_BASE, name);
|
||||
sprintf(comparison_path, "%s/%s.txt", PROFILE_BASE, name);
|
||||
sprintf(path, "%s/%s/%s.txt", SAVED_PROFILE_BASE, cpld->name, name);
|
||||
sprintf(comparison_path, "%s/%s/%s.txt", PROFILE_BASE, cpld->name, name);
|
||||
}
|
||||
|
||||
log_info("Loading comparison file %s", comparison_path);
|
||||
|
@ -698,14 +708,14 @@ int file_restore(char *dirpath, char *name) {
|
|||
}
|
||||
|
||||
if (dirpath != NULL) {
|
||||
sprintf(path, "%s/%s", root, dirpath);
|
||||
sprintf(path, "%s/%s/%s", root, cpld->name, dirpath);
|
||||
result = f_mkdir(path);
|
||||
if (result != FR_OK && result != FR_EXIST) {
|
||||
log_warn("Failed to create dir %s (result = %d)", dirpath, result);
|
||||
}
|
||||
sprintf(path, "%s/%s/%s.txt", root, dirpath, name);
|
||||
sprintf(path, "%s/%s/%s/%s.txt", root, cpld->name, dirpath, name);
|
||||
} else {
|
||||
sprintf(path, "%s/%s.txt", root, name);
|
||||
sprintf(path, "%s/%s/%s.txt", root, cpld->name, name);
|
||||
}
|
||||
|
||||
|
||||
|
|
36
src/osd.c
36
src/osd.c
|
@ -1275,7 +1275,7 @@ void osd_update_palette() {
|
|||
int b = (i & 4) ? 255 : 0;
|
||||
int i6847 = i;
|
||||
|
||||
if((((cpld->get_version() >> VERSION_DESIGN_BIT) & 0x0F) != DESIGN_ATOM) && palette >= PALETTE_ATOM_MKI && palette <= PALETTE_ATOM_6847_EMULATORS) {
|
||||
if((((cpld->get_version() >> VERSION_DESIGN_BIT) & 0x0F) == DESIGN_NORMAL) && palette >= PALETTE_ATOM_MKI && palette <= PALETTE_ATOM_6847_EMULATORS) {
|
||||
|
||||
//some 6847 YUV to RGB conversions based on Atom VHDL
|
||||
int AH = 0;
|
||||
|
@ -1705,14 +1705,17 @@ int save_profile(char *path, char *name, char *buffer, char *default_buffer, cha
|
|||
param_t *param;
|
||||
int current_mode7 = geometry_get_mode();
|
||||
int i;
|
||||
|
||||
int index = 0;
|
||||
if (((cpld->get_version() >> VERSION_DESIGN_BIT) & 0x0F) == DESIGN_NORMAL) {
|
||||
index = 1;
|
||||
}
|
||||
if (default_buffer != NULL) {
|
||||
if (get_feature(F_AUTOSWITCH) == AUTOSWITCH_MODE7) {
|
||||
|
||||
geometry_set_mode(1);
|
||||
cpld->set_mode(1);
|
||||
pointer += sprintf(pointer, "sampling7=");
|
||||
i = 1;
|
||||
i = index;
|
||||
param = cpld->get_params() + i;
|
||||
while(param->key >= 0) {
|
||||
pointer += sprintf(pointer, "%d,", cpld->get_value(param->key));
|
||||
|
@ -1735,7 +1738,7 @@ int save_profile(char *path, char *name, char *buffer, char *default_buffer, cha
|
|||
cpld->set_mode(0);
|
||||
|
||||
pointer += sprintf(pointer, "sampling=");
|
||||
i = 1;
|
||||
i = index;
|
||||
param = cpld->get_params() + i;
|
||||
while(param->key >= 0) {
|
||||
pointer += sprintf(pointer, "%d,", cpld->get_value(param->key));
|
||||
|
@ -1790,7 +1793,10 @@ void process_single_profile(char *buffer) {
|
|||
if (buffer[0] == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
int index = 0;
|
||||
if (((cpld->get_version() >> VERSION_DESIGN_BIT) & 0x0F) == DESIGN_NORMAL) {
|
||||
index = 1;
|
||||
}
|
||||
for (int m7 = 0; m7 < 2; m7++) {
|
||||
geometry_set_mode(m7);
|
||||
cpld->set_mode(m7);
|
||||
|
@ -1798,7 +1804,7 @@ void process_single_profile(char *buffer) {
|
|||
prop = get_prop(buffer, m7 ? "sampling7" : "sampling");
|
||||
if (prop) {
|
||||
char *prop2 = strtok(prop, ",");
|
||||
int i = 1;
|
||||
int i = index;
|
||||
while (prop2) {
|
||||
param_t *param;
|
||||
param = cpld->get_params() + i;
|
||||
|
@ -2667,11 +2673,15 @@ void osd_init() {
|
|||
default_buffer[0] = 0;
|
||||
has_sub_profiles[0] = 0;
|
||||
|
||||
char path[100] = "/Profiles/";
|
||||
strncat(path, cpld->name, 80);
|
||||
char name[100];
|
||||
|
||||
// pre-read default profile
|
||||
unsigned int bytes = file_read_profile(DEFAULT_STRING, NULL, 0, default_buffer, MAX_BUFFER_SIZE - 4);
|
||||
if (bytes != 0) {
|
||||
size_t count = 0;
|
||||
scan_profiles(profile_names, has_sub_profiles, "/Profiles", &count);
|
||||
scan_profiles(profile_names, has_sub_profiles, path, &count);
|
||||
if (count != 0) {
|
||||
features[F_PROFILE].max = count - 1;
|
||||
for (int i = 0; i < count; i++) {
|
||||
|
@ -2684,10 +2694,12 @@ void osd_init() {
|
|||
// The default profile is provided by the CPLD
|
||||
prop = cpld->default_profile;
|
||||
// It can be over-ridden by a local profile.txt file
|
||||
cbytes = file_load("/profile.txt", config_buffer, MAX_CONFIG_BUFFER_SIZE);
|
||||
sprintf(name, "/profile_%s.txt", cpld->name);
|
||||
cbytes = file_load(name, config_buffer, MAX_CONFIG_BUFFER_SIZE);
|
||||
if (cbytes) {
|
||||
prop = get_prop_no_space(config_buffer, "profile");
|
||||
}
|
||||
int found_profile = 0;
|
||||
if (prop) {
|
||||
for (int i=0; i<count; i++) {
|
||||
if (strcmp(profile_names[i], prop) == 0) {
|
||||
|
@ -2696,9 +2708,17 @@ void osd_init() {
|
|||
process_profile(i);
|
||||
set_feature(F_SUBPROFILE, 0);
|
||||
log_info("Profile = %s", prop);
|
||||
found_profile = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found_profile) {
|
||||
set_profile(0);
|
||||
load_profiles(0, 0);
|
||||
process_profile(0);
|
||||
set_feature(F_SUBPROFILE, 0);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
#include <math.h>
|
||||
#include "cache.h"
|
||||
#include "defs.h"
|
||||
#include "cpld.h"
|
||||
#include "info.h"
|
||||
#include "logging.h"
|
||||
#include "rpi-aux.h"
|
||||
|
@ -19,6 +18,7 @@
|
|||
#include "cpld.h"
|
||||
#include "cpld_normal.h"
|
||||
#include "cpld_atom.h"
|
||||
#include "cpld_yuv6847.h"
|
||||
#include "cpld_null.h"
|
||||
#include "geometry.h"
|
||||
#include "filesystem.h"
|
||||
|
@ -1067,6 +1067,8 @@ static void cpld_init() {
|
|||
cpld = &cpld_normal;
|
||||
} else if ((cpld_version_id >> VERSION_DESIGN_BIT) == DESIGN_ATOM) {
|
||||
cpld = &cpld_atom;
|
||||
} else if ((cpld_version_id >> VERSION_DESIGN_BIT) == DESIGN_YUV6847) {
|
||||
cpld = &cpld_yuv6847;
|
||||
} else {
|
||||
log_info("Unknown CPLD: identifier = %03x", cpld_version_id);
|
||||
cpld = &cpld_null;
|
||||
|
@ -1881,7 +1883,7 @@ void set_autoswitch(int value) {
|
|||
//
|
||||
// It might be better to combine this with the cpld->old_firmware() and
|
||||
// rename this to cpld->get_capabilities().
|
||||
if (value == AUTOSWITCH_MODE7 && ((cpld->get_version() >> VERSION_DESIGN_BIT) & 0x0F) == DESIGN_ATOM) {
|
||||
if (value == AUTOSWITCH_MODE7 && ((cpld->get_version() >> VERSION_DESIGN_BIT) & 0x0F) != DESIGN_NORMAL) {
|
||||
autoswitch ^= AUTOSWITCH_PC;
|
||||
} else {
|
||||
autoswitch = value;
|
||||
|
|
Ładowanie…
Reference in New Issue