Skip to content

Commit

Permalink
Add autodetection of sync frequency
Browse files Browse the repository at this point in the history
- can be disabled in options
- if > 20kHz use VGA rates
- also sets sync polarity
  • Loading branch information
penfold42 authored and keirf committed Dec 9, 2019
1 parent 676ff1a commit df7d4ca
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 4 deletions.
2 changes: 2 additions & 0 deletions inc/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ extern struct __packed config {
#define DISP_VGA 1
uint16_t display_timing;

uint16_t display_autosync;

#define DISP_SPI2 0
#define DISP_SPI1 1
uint16_t display_spi;
Expand Down
10 changes: 10 additions & 0 deletions src/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ static void config_printk(const struct config *conf)
printk("\nCurrent config:\n");
printk(" Sync: Active %s\n", conf->polarity ? "HIGH" : "LOW");
printk(" Pixel Timing: %s\n", config.display_timing ? "VGA" : "15kHz");
printk(" Auto Sync: %s\n", config.display_autosync ? "ON" : "OFF");
printk(" Display Height: %s\n", conf->display_2Y ? "Double" : "Normal");
printk(" Display Output: %s\n", config.display_spi ? "PA7/SPI1" : "PB15/SPI2");
printk(" Display Enable: %s\n", dispen_pretty[config.dispctl_mode] );
Expand Down Expand Up @@ -94,6 +95,7 @@ static enum {
/* Output */
C_polarity,
C_disptiming,
C_autosync,
C_disp2Y,
C_spibus,
C_dispen,
Expand Down Expand Up @@ -240,6 +242,14 @@ void config_process(uint8_t b)
if (b)
cnf_prt(1, "%s", config.display_timing ? "VGA" : "15kHz");
break;
case C_autosync:
if (changed)
cnf_prt(0, "Auto Sync:");
if (b & (B_LEFT|B_RIGHT))
config.display_autosync ^= 1;
if (b)
cnf_prt(1, "%s", config.display_autosync ? "ON" : "OFF");
break;
case C_disp2Y:
if (changed)
cnf_prt(0, "Display Height:");
Expand Down
1 change: 1 addition & 0 deletions src/default_config.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ const static struct config dfl_config = {
.dispctl_mode = DISPCTL_tristate,
.rows = 2,
.display_timing = DISP_15KHZ,
.display_autosync = FALSE,
.display_spi = DISP_SPI2,
.display_2Y = FALSE,

Expand Down
79 changes: 75 additions & 4 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -168,18 +168,27 @@ volatile unsigned int vstart;
static void button_amikeys(void)
{
/* Sync Polarity. */
if (amiga_key_pressed(AMI_KPPLUS))
if (amiga_key_pressed(AMI_KPPLUS)) {
config.display_autosync = FALSE;
config.polarity = TRUE;
if (amiga_key_pressed(AMI_KPMINUS))
}
if (amiga_key_pressed(AMI_KPMINUS)) {
config.display_autosync = FALSE;
config.polarity = FALSE;
}
if (amiga_key_pressed(AMI_KPLEFTPAREN)) {
config.display_autosync = FALSE;
config.display_timing = DISP_15KHZ;
setup_spi();
}
if (amiga_key_pressed(AMI_KPRIGHTPAREN)) {
config.display_autosync = FALSE;
config.display_timing = DISP_VGA;
setup_spi();
}
if (amiga_key_pressed(AMI_KPSLASH)) {
config.display_autosync = TRUE;
}
if (amiga_key_pressed(AMI_W))
config.v_off = max_t(uint16_t, config.v_off-1, 2);
if (amiga_key_pressed(AMI_S))
Expand Down Expand Up @@ -313,6 +322,11 @@ static void IRQ_vsync(void)
hline = HLINE_VBL;
}

#define sync_log_MAX 20
volatile static int sync_log_ptr;
volatile static int32_t sync_log[sync_log_MAX];
static time_t last_sync_time;

static void IRQ_csync(void)
{
exti->pr = m(pin_csync);
Expand Down Expand Up @@ -349,7 +363,12 @@ static void IRQ_csync(void)

} else if (++hline < vstart) {

/* Before vertical start of OSD: Do nothing. */
/* Before vertical start of OSD: Time hsync pulses. */
time_t this_sync_time = time_now();
sync_log[sync_log_ptr++] = time_diff(last_sync_time, this_sync_time);
last_sync_time = this_sync_time;
if (sync_log_ptr >= sync_log_MAX)
sync_log_ptr = 0;

} else if (hline >= (vstart + display_height)) {

Expand Down Expand Up @@ -723,6 +742,55 @@ void setup_spi(void)
slave_arr_update();
}

static time_t auto_time;
void do_autosync(void)
{
unsigned int avg_hz;
time_t avg_sync_time;
bool_t valid_sync_data;
int i;

if (time_diff(auto_time, time_now()) < time_ms(1000))
return;

auto_time = time_now();

avg_sync_time = 0;
for (i = 0; i < sync_log_MAX; i++)
avg_sync_time += sync_log[i];
avg_sync_time /= sync_log_MAX;

/* Require all samples to be +/- 10/9,000,000th from average */
valid_sync_data = (avg_sync_time != 0);
for (i = 0; i < sync_log_MAX; i++) {
int diff = sync_log[i] - avg_sync_time;
if ((diff > 10) || (diff < -10))
valid_sync_data = FALSE;
}
if (!valid_sync_data)
return;

/* 9MHz clock, 15.625kHz => 576 => PAL/NTSC
* 9MHz clock, 20.000kHz => 450 => my threshold
* 9MHz clock, 39.130kHz => 230 => VGA */
avg_hz = 9000000 / avg_sync_time; /* sync time -> frequency in Hz */
if ((avg_hz < 20000)
&& (config.display_timing != DISP_15KHZ)) {
/* PAL/NTSC */
config.display_timing = DISP_15KHZ;
config.polarity = FALSE;
printk("Switch to PAL/NTSC: %d Hz < 20kHz\n", avg_hz);
setup_spi();
} else if ((avg_hz >= 20000)
&& (config.display_timing != DISP_VGA)) {
/* VGA */
config.display_timing = DISP_VGA;
config.polarity = TRUE;
printk("Switch to VGA: %d Hz > 20kHz\n", avg_hz);
setup_spi();
}
}

int main(void)
{
static struct display no_display;
Expand Down Expand Up @@ -868,7 +936,7 @@ int main(void)
IRQx_enable(irqs[i]);
}

frame_time = time_now();
frame_time = auto_time = time_now();
lost_sync = FALSE;

_keyboard_held = keyboard_held;
Expand Down Expand Up @@ -923,6 +991,9 @@ int main(void)
lost_sync = FALSE;
}

if (config.display_autosync)
do_autosync();

frame_time = time_now();
frame = 0;

Expand Down

0 comments on commit df7d4ca

Please sign in to comment.