Support for new driver. Also split profiles into separate folders for each CPLD

pull/113/head
IanSB 2019-12-04 01:16:25 +00:00
rodzic 0baad9bc6b
commit 6187fe05f4
6 zmienionych plików z 62 dodań i 143 usunięć

Wyświetl plik

@ -96,6 +96,8 @@ file( GLOB core_files
cpld_normal.c cpld_normal.c
cpld_atom.h cpld_atom.h
cpld_atom.c cpld_atom.c
cpld_yuv6847.h
cpld_yuv6847.c
cpld_null.h cpld_null.h
cpld_null.c cpld_null.c
geometry.h geometry.h

Wyświetl plik

@ -8,6 +8,7 @@
#define DESIGN_NORMAL 0 #define DESIGN_NORMAL 0
#define DESIGN_ALTERNATIVE 1 // This has now been removed from the code base #define DESIGN_ALTERNATIVE 1 // This has now been removed from the code base
#define DESIGN_ATOM 2 #define DESIGN_ATOM 2
#define DESIGN_YUV6847 3
#define DESIGN_NULL 15 // This is when the CPLD is unprogrammed #define DESIGN_NULL 15 // This is when the CPLD is unprogrammed
typedef struct { typedef struct {

Wyświetl plik

@ -16,15 +16,9 @@
#define NUM_CAL_FRAMES 10 #define NUM_CAL_FRAMES 10
typedef struct { typedef struct {
int dummy;
int sp_offset; int sp_offset;
int filter_c; int filter_c;
int filter_l; int filter_l;
int invert_l;
int lvl_uvpos;
int lvl_uvneg;
int lvl_ylo;
int lvl_yhi;
} config_t; } config_t;
// Current calibration state for mode 0..6 // Current calibration state for mode 0..6
@ -45,88 +39,27 @@ static int errors;
// The CPLD version number // The CPLD version number
static int cpld_version; static int cpld_version;
static int frontend = 0;
static int supports_invert = 0;
// ============================================================= // =============================================================
// Param definitions for OSD // Param definitions for OSD
// ============================================================= // =============================================================
enum { enum {
SETUP,
OFFSET, OFFSET,
FILTER_C, FILTER_C,
FILTER_L, FILTER_L,
INVERT_L,
LVL_UVPOS,
LVL_UVNEG,
LVL_YHI,
LVL_YLO
}; };
static param_t params[] = { static param_t params[] = {
{ SETUP, "Setup Mode", "setup_mode", 0, 1, 1 },
{ OFFSET, "Offset", "offset", 0, 15, 1 }, { OFFSET, "Offset", "offset", 0, 15, 1 },
{ FILTER_C, "C Filter", "c_filter", 0, 1, 1 }, { FILTER_C, "C Filter", "c_filter", 0, 1, 1 },
{ FILTER_L, "L Filter", "l_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 } { -1, NULL, NULL, 0, 0, 0 }
}; };
// ============================================================= // =============================================================
// Private methods // 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) { static void write_config(config_t *config) {
int sp = 0; int sp = 0;
int scan_len = 6; int scan_len = 6;
@ -134,11 +67,6 @@ static void write_config(config_t *config) {
sp |= config->filter_c << 4; sp |= config->filter_c << 4;
sp |= config->filter_l << 5; sp |= config->filter_l << 5;
if (supports_invert) {
sp |= config->invert_l << 6;
scan_len++;
}
for (int i = 0; i < scan_len; i++) { for (int i = 0; i < scan_len; i++) {
RPI_SetGpioValue(SP_DATA_PIN, sp & 1); RPI_SetGpioValue(SP_DATA_PIN, sp & 1);
for (int j = 0; j < 1000; j++); for (int j = 0; j < 1000; j++);
@ -152,11 +80,6 @@ static void write_config(config_t *config) {
sp >>= 1; 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); RPI_SetGpioValue(SP_DATA_PIN, 0);
} }
@ -192,17 +115,6 @@ static void cpld_init(int version) {
} }
errors = -1; 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() { static int cpld_get_version() {
@ -295,17 +207,6 @@ static int cpld_get_value(int num) {
return config->filter_c; return config->filter_c;
case FILTER_L: case FILTER_L:
return config->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; return 0;
} }
@ -331,21 +232,6 @@ static void cpld_set_value(int num, int value) {
case FILTER_L: case FILTER_L:
config->filter_l = value; config->filter_l = value;
break; 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); write_config(config);
} }
@ -380,18 +266,16 @@ static int cpld_get_delay() {
} }
static int cpld_frontend_info() { static int cpld_frontend_info() {
return 1; return 0;
} }
static void cpld_set_frontend(int value) { static void cpld_set_frontend(int value) {
frontend = value;
write_config(config);
} }
cpld_t cpld_atom = { cpld_t cpld_atom = {
.name = "Atom", .name = "Atom",
.default_profile = "Atom_CPLD", .default_profile = "Atom",
.init = cpld_init, .init = cpld_init,
.get_version = cpld_get_version, .get_version = cpld_get_version,
.calibrate = cpld_calibrate, .calibrate = cpld_calibrate,

Wyświetl plik

@ -318,17 +318,17 @@ unsigned int file_read_profile(char *profile_name, char *sub_profile_name, int u
init_filesystem(); init_filesystem();
if (sub_profile_name != NULL) { 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 { } 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); result = f_open(&file, path, FA_READ);
if (result != FR_OK) { if (result != FR_OK) {
if (sub_profile_name != NULL) { 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 { } 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); result = f_open(&file, path, FA_READ);
if (result != FR_OK) { if (result != FR_OK) {
@ -359,7 +359,9 @@ unsigned int file_read_profile(char *profile_name, char *sub_profile_name, int u
} }
if (updatecmd) { 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) { if (result != FR_OK) {
log_warn("Failed to open %s (result = %d)", path, result); log_warn("Failed to open %s (result = %d)", path, result);
close_filesystem(); close_filesystem();
@ -482,7 +484,9 @@ void scan_sub_profiles(char sub_profile_names[MAX_SUB_PROFILES][MAX_PROFILE_WIDT
FRESULT res; FRESULT res;
DIR dir; DIR dir;
static FILINFO fno; static FILINFO fno;
char path[100] = "/Profiles/"; char path[100] = "/Profiles/";
strncat(path, cpld->name, 80);
strncat(path, "/", 80);
strncat(path, sub_path, 80); strncat(path, sub_path, 80);
init_filesystem(); init_filesystem();
res = f_opendir(&dir, path); 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) { if (result != FR_OK && result != FR_EXIST) {
log_warn("Failed to create dir %s (result = %d)",SAVED_PROFILE_BASE, result); 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) { 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); result = f_mkdir(path);
if (result != FR_OK && result != FR_EXIST) { if (result != FR_OK && result != FR_EXIST) {
log_warn("Failed to create dir %s (result = %d)", dirpath, result); log_warn("Failed to create dir %s (result = %d)", dirpath, result);
} }
sprintf(path, "%s/%s/%s.txt", SAVED_PROFILE_BASE, dirpath, name); sprintf(path, "%s/%s/%s/%s.txt", SAVED_PROFILE_BASE, cpld->name, dirpath, name);
sprintf(comparison_path, "%s/%s/%s.txt", PROFILE_BASE, dirpath, name); sprintf(comparison_path, "%s/%s/%s/%s.txt", PROFILE_BASE, cpld->name, dirpath, name);
} else { } else {
sprintf(path, "%s/%s.txt", SAVED_PROFILE_BASE, name); sprintf(path, "%s/%s/%s.txt", SAVED_PROFILE_BASE, cpld->name, name);
sprintf(comparison_path, "%s/%s.txt", PROFILE_BASE, name); sprintf(comparison_path, "%s/%s/%s.txt", PROFILE_BASE, cpld->name, name);
} }
log_info("Loading comparison file %s", comparison_path); log_info("Loading comparison file %s", comparison_path);
@ -698,14 +708,14 @@ int file_restore(char *dirpath, char *name) {
} }
if (dirpath != NULL) { if (dirpath != NULL) {
sprintf(path, "%s/%s", root, dirpath); sprintf(path, "%s/%s/%s", root, cpld->name, dirpath);
result = f_mkdir(path); result = f_mkdir(path);
if (result != FR_OK && result != FR_EXIST) { if (result != FR_OK && result != FR_EXIST) {
log_warn("Failed to create dir %s (result = %d)", dirpath, result); 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 { } else {
sprintf(path, "%s/%s.txt", root, name); sprintf(path, "%s/%s/%s.txt", root, cpld->name, name);
} }

Wyświetl plik

@ -1275,7 +1275,7 @@ void osd_update_palette() {
int b = (i & 4) ? 255 : 0; int b = (i & 4) ? 255 : 0;
int i6847 = i; 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 //some 6847 YUV to RGB conversions based on Atom VHDL
int AH = 0; int AH = 0;
@ -1705,14 +1705,17 @@ int save_profile(char *path, char *name, char *buffer, char *default_buffer, cha
param_t *param; param_t *param;
int current_mode7 = geometry_get_mode(); int current_mode7 = geometry_get_mode();
int i; int i;
int index = 0;
if (((cpld->get_version() >> VERSION_DESIGN_BIT) & 0x0F) == DESIGN_NORMAL) {
index = 1;
}
if (default_buffer != NULL) { if (default_buffer != NULL) {
if (get_feature(F_AUTOSWITCH) == AUTOSWITCH_MODE7) { if (get_feature(F_AUTOSWITCH) == AUTOSWITCH_MODE7) {
geometry_set_mode(1); geometry_set_mode(1);
cpld->set_mode(1); cpld->set_mode(1);
pointer += sprintf(pointer, "sampling7="); pointer += sprintf(pointer, "sampling7=");
i = 1; i = index;
param = cpld->get_params() + i; param = cpld->get_params() + i;
while(param->key >= 0) { while(param->key >= 0) {
pointer += sprintf(pointer, "%d,", cpld->get_value(param->key)); 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); cpld->set_mode(0);
pointer += sprintf(pointer, "sampling="); pointer += sprintf(pointer, "sampling=");
i = 1; i = index;
param = cpld->get_params() + i; param = cpld->get_params() + i;
while(param->key >= 0) { while(param->key >= 0) {
pointer += sprintf(pointer, "%d,", cpld->get_value(param->key)); pointer += sprintf(pointer, "%d,", cpld->get_value(param->key));
@ -1790,7 +1793,10 @@ void process_single_profile(char *buffer) {
if (buffer[0] == 0) { if (buffer[0] == 0) {
return; return;
} }
int index = 0;
if (((cpld->get_version() >> VERSION_DESIGN_BIT) & 0x0F) == DESIGN_NORMAL) {
index = 1;
}
for (int m7 = 0; m7 < 2; m7++) { for (int m7 = 0; m7 < 2; m7++) {
geometry_set_mode(m7); geometry_set_mode(m7);
cpld->set_mode(m7); cpld->set_mode(m7);
@ -1798,7 +1804,7 @@ void process_single_profile(char *buffer) {
prop = get_prop(buffer, m7 ? "sampling7" : "sampling"); prop = get_prop(buffer, m7 ? "sampling7" : "sampling");
if (prop) { if (prop) {
char *prop2 = strtok(prop, ","); char *prop2 = strtok(prop, ",");
int i = 1; int i = index;
while (prop2) { while (prop2) {
param_t *param; param_t *param;
param = cpld->get_params() + i; param = cpld->get_params() + i;
@ -2667,11 +2673,15 @@ void osd_init() {
default_buffer[0] = 0; default_buffer[0] = 0;
has_sub_profiles[0] = 0; has_sub_profiles[0] = 0;
char path[100] = "/Profiles/";
strncat(path, cpld->name, 80);
char name[100];
// pre-read default profile // pre-read default profile
unsigned int bytes = file_read_profile(DEFAULT_STRING, NULL, 0, default_buffer, MAX_BUFFER_SIZE - 4); unsigned int bytes = file_read_profile(DEFAULT_STRING, NULL, 0, default_buffer, MAX_BUFFER_SIZE - 4);
if (bytes != 0) { if (bytes != 0) {
size_t count = 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) { if (count != 0) {
features[F_PROFILE].max = count - 1; features[F_PROFILE].max = count - 1;
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
@ -2684,10 +2694,12 @@ void osd_init() {
// The default profile is provided by the CPLD // The default profile is provided by the CPLD
prop = cpld->default_profile; prop = cpld->default_profile;
// It can be over-ridden by a local profile.txt file // 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) { if (cbytes) {
prop = get_prop_no_space(config_buffer, "profile"); prop = get_prop_no_space(config_buffer, "profile");
} }
int found_profile = 0;
if (prop) { if (prop) {
for (int i=0; i<count; i++) { for (int i=0; i<count; i++) {
if (strcmp(profile_names[i], prop) == 0) { if (strcmp(profile_names[i], prop) == 0) {
@ -2696,9 +2708,17 @@ void osd_init() {
process_profile(i); process_profile(i);
set_feature(F_SUBPROFILE, 0); set_feature(F_SUBPROFILE, 0);
log_info("Profile = %s", prop); log_info("Profile = %s", prop);
found_profile = 1;
break; break;
} }
} }
if (!found_profile) {
set_profile(0);
load_profiles(0, 0);
process_profile(0);
set_feature(F_SUBPROFILE, 0);
}
} }
} }
} }

Wyświetl plik

@ -6,7 +6,6 @@
#include <math.h> #include <math.h>
#include "cache.h" #include "cache.h"
#include "defs.h" #include "defs.h"
#include "cpld.h"
#include "info.h" #include "info.h"
#include "logging.h" #include "logging.h"
#include "rpi-aux.h" #include "rpi-aux.h"
@ -19,6 +18,7 @@
#include "cpld.h" #include "cpld.h"
#include "cpld_normal.h" #include "cpld_normal.h"
#include "cpld_atom.h" #include "cpld_atom.h"
#include "cpld_yuv6847.h"
#include "cpld_null.h" #include "cpld_null.h"
#include "geometry.h" #include "geometry.h"
#include "filesystem.h" #include "filesystem.h"
@ -1067,6 +1067,8 @@ static void cpld_init() {
cpld = &cpld_normal; cpld = &cpld_normal;
} else if ((cpld_version_id >> VERSION_DESIGN_BIT) == DESIGN_ATOM) { } else if ((cpld_version_id >> VERSION_DESIGN_BIT) == DESIGN_ATOM) {
cpld = &cpld_atom; cpld = &cpld_atom;
} else if ((cpld_version_id >> VERSION_DESIGN_BIT) == DESIGN_YUV6847) {
cpld = &cpld_yuv6847;
} else { } else {
log_info("Unknown CPLD: identifier = %03x", cpld_version_id); log_info("Unknown CPLD: identifier = %03x", cpld_version_id);
cpld = &cpld_null; 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 // It might be better to combine this with the cpld->old_firmware() and
// rename this to cpld->get_capabilities(). // 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; autoswitch ^= AUTOSWITCH_PC;
} else { } else {
autoswitch = value; autoswitch = value;