1
0
mirror of https://github.com/marqs85/ossc.git synced 2024-06-02 08:41:28 +00:00

Compare commits

..

No commits in common. "v1.04" and "release" have entirely different histories.

61 changed files with 11632 additions and 12497 deletions

5
.gitignore vendored
View File

@ -1,8 +1,3 @@
*_bb.v
*_inst.v
*.ppf
*.qws
greybox_tmp
.DS_Store
software/sys_controller/.cproject
software/sys_controller/.force_relink

View File

@ -5,10 +5,9 @@ package require -exact sopc 9.1
# |
set_module_property NAME altera_jtag_avalon_master_mod
set_module_property DESCRIPTION "The JTAG to Avalon Master Bridge is a collection of pre-wired components that provide an Avalon Master using the new JTAG channel."
#set_module_property VERSION "21.1"
set_module_property INTERNAL false
set_module_property VERSION "20.1"
set_module_property GROUP "Basic Functions/Bridges and Adaptors/Memory Mapped"
#set_module_property AUTHOR "Altera Corporation"
set_module_property AUTHOR "Altera Corporation"
set_module_property DISPLAY_NAME "JTAG to Avalon Master Bridge (customized)"
set_module_property DATASHEET_URL "http://www.altera.com/literature/hb/nios2/qts_qii55011.pdf"
set_module_property INSTANTIATE_IN_SYSTEM_MODULE true

View File

@ -20,149 +20,118 @@
#ifndef SC_CONFIG_REGS_H_
#define SC_CONFIG_REGS_H_
#include <stdint.h>
#include <alt_types.h>
// bit-fields coded as little-endian
typedef union {
struct {
uint16_t vtotal:11;
uint8_t interlace_flag:1;
uint8_t sync_active:1;
uint32_t fe_rsv:19;
alt_u16 vmax:11;
alt_u8 interlace_flag:1;
alt_u8 sc_rsv2:4;
alt_u8 fpga_vsyncgen:2;
alt_u16 vmax_tvp:11;
alt_u8 sc_rsv:2;
alt_u8 vsync_flag:1;
} __attribute__((packed, __may_alias__));
uint32_t data;
} fe_status_reg;
alt_u32 data;
} sc_status_reg;
typedef union {
struct {
uint32_t pcnt_frame:20;
uint8_t hsync_width:8;
uint8_t fe_rsv:4;
alt_u32 pcnt_frame:20;
alt_u16 sc_rsv:12;
} __attribute__((packed, __may_alias__));
uint32_t data;
} fe_status2_reg;
alt_u32 data;
} sc_status2_reg;
typedef union {
struct {
uint16_t lt_lat_result:16;
uint16_t lt_stb_result:12;
uint8_t lt_rsv:3;
uint8_t lt_finished:1;
alt_u16 lt_lat_result:16;
alt_u16 lt_stb_result:12;
alt_u8 lt_rsv:3;
alt_u8 lt_finished:1;
} __attribute__((packed, __may_alias__));
uint32_t data;
alt_u32 data;
} lt_status_reg;
typedef union {
struct {
uint16_t h_total:12;
uint16_t h_active:12;
uint16_t h_synclen:8;
alt_u16 h_active:11;
alt_u16 h_backporch:9;
alt_u8 h_synclen:8;
alt_u8 h_l3_240x360:1;
alt_u8 h_l5fmt:1;
alt_u8 h_multmode:2;
} __attribute__((packed, __may_alias__));
uint32_t data;
} hv_config_reg;
alt_u32 data;
} h_config_reg;
typedef union {
struct {
uint16_t h_backporch:9;
uint16_t v_total:11;
uint16_t v_active:11;
uint8_t interlaced:1;
alt_u16 h_opt_startoff:10;
alt_u8 h_opt_sample_mult:3;
alt_u8 h_opt_sample_sel:3;
alt_u8 h_opt_scale:3;
alt_u16 h_mask:11;
alt_u8 h_rsv:2;
} __attribute__((packed, __may_alias__));
uint32_t data;
} hv_config2_reg;
alt_u32 data;
} h_config2_reg;
typedef union {
struct {
uint8_t v_synclen:4;
uint16_t v_backporch:9;
uint16_t v_startline:11;
uint8_t h_skip:4;
uint8_t h_sample_sel:4;
alt_u16 v_active:11;
alt_u8 v_backporch:8;
alt_u8 v_synclen:3;
alt_u8 v_mask:6;
alt_u8 v_rsv:1;
alt_u8 v_multmode:3;
} __attribute__((packed, __may_alias__));
uint32_t data;
} hv_config3_reg;
alt_u32 data;
} v_config_reg;
typedef union {
struct {
uint16_t x_size:12;
uint16_t y_size:11;
int16_t y_offset:9;
alt_u8 mask_br:4;
alt_u8 mask_color:3;
alt_u8 rev_lpf_str:5;
alt_u8 panasonic_hack:1;
alt_u32 misc_rsv:19;
} __attribute__((packed, __may_alias__));
uint32_t data;
} xy_config_reg;
typedef union {
struct {
int16_t x_offset:10;
uint8_t x_start_lb:8;
int8_t y_start_lb:6;
int8_t x_rpt:4;
int8_t y_rpt:4;
} __attribute__((packed, __may_alias__));
uint32_t data;
} xy_config2_reg;
typedef union {
struct {
uint8_t mask_br:4;
uint8_t mask_color:3;
uint8_t reverse_lpf:5;
uint8_t lm_deint_mode:1;
uint8_t nir_even_offset:1;
uint8_t ypbpr_cs:1;
uint8_t vip_enable:1;
uint8_t bfi_str:4;
uint8_t bfi_enable:1;
uint32_t misc_rsv:11;
} __attribute__((packed, __may_alias__));
uint32_t data;
alt_u32 data;
} misc_config_reg;
typedef union {
struct {
uint32_t sl_l_str_arr:24;
uint8_t sl_l_overlay:6;
uint8_t sl_method:1;
uint8_t sl_altern:1;
alt_u32 sl_l_str_arr:20;
alt_u8 sl_l_overlay:5;
alt_u8 sl_hybr_str:5;
alt_u8 sl_method:1;
alt_u8 sl_no_altern:1;
} __attribute__((packed, __may_alias__));
uint32_t data;
alt_u32 data;
} sl_config_reg;
typedef union {
struct {
uint32_t sl_c_str_arr_l;
alt_u32 sl_c_str_arr:24;
alt_u8 sl_c_overlay:6;
alt_u8 sl_rsv:1;
alt_u8 sl_altiv:1;
} __attribute__((packed, __may_alias__));
uint32_t data;
alt_u32 data;
} sl_config2_reg;
typedef union {
struct {
uint32_t sl_c_str_arr_h:8;
uint32_t sl_c_overlay:10;
uint8_t sl_iv_y:3;
uint8_t sl_iv_x:4;
uint8_t sl_hybr_str:5;
uint32_t sl_rsv:2;
} __attribute__((packed, __may_alias__));
uint32_t data;
} sl_config3_reg;
typedef struct {
fe_status_reg fe_status;
fe_status2_reg fe_status2;
sc_status_reg sc_status;
sc_status2_reg sc_status2;
lt_status_reg lt_status;
hv_config_reg hv_in_config;
hv_config2_reg hv_in_config2;
hv_config3_reg hv_in_config3;
hv_config_reg hv_out_config;
hv_config2_reg hv_out_config2;
hv_config3_reg hv_out_config3;
xy_config_reg xy_out_config;
xy_config2_reg xy_out_config2;
h_config_reg h_config;
h_config2_reg h_config2;
v_config_reg v_config;
misc_config_reg misc_config;
sl_config_reg sl_config;
sl_config2_reg sl_config2;
sl_config3_reg sl_config3;
} sc_regs;
} __attribute__((packed, __may_alias__)) sc_regs;
#endif //SC_CONFIG_REGS_H_

View File

@ -1,11 +1,11 @@
#
#
# request TCL package from ACDS 16.1
#
#
package require -exact qsys 16.1
#
#
# module
#
#
set_module_property DESCRIPTION "Scanconverter config"
set_module_property NAME sc_config
#set_module_property VERSION 18.0
@ -20,9 +20,9 @@ set_module_property REPORT_TO_TALKBACK false
set_module_property ALLOW_GREYBOX_GENERATION false
set_module_property REPORT_HIERARCHY false
#
#
# file sets
#
#
add_fileset QUARTUS_SYNTH QUARTUS_SYNTH "" ""
set_fileset_property QUARTUS_SYNTH TOP_LEVEL sc_config_top
set_fileset_property QUARTUS_SYNTH ENABLE_RELATIVE_INCLUDE_PATHS false
@ -35,19 +35,19 @@ set_fileset_property SIM_VERILOG ENABLE_FILE_OVERWRITE_MODE false
set_fileset_property SIM_VERILOG TOP_LEVEL sc_config_top
add_fileset_file sc_config_top.sv VERILOG PATH sc_config_top.sv
#
#
# parameters
#
#
#
#
# display items
#
#
#
#
# connection point clock_sink
#
#
add_interface clock_sink clock end
set_interface_property clock_sink clockRate 0
set_interface_property clock_sink ENABLED true
@ -59,9 +59,9 @@ set_interface_property clock_sink SVD_ADDRESS_GROUP ""
add_interface_port clock_sink clk_i clk Input 1
#
#
# connection point reset_sink
#
#
add_interface reset_sink reset end
set_interface_property reset_sink associatedClock clock_sink
set_interface_property reset_sink synchronousEdges DEASSERT
@ -74,9 +74,9 @@ set_interface_property reset_sink SVD_ADDRESS_GROUP ""
add_interface_port reset_sink rst_i reset Input 1
#
#
# connection point avalon_s
#
#
add_interface avalon_s avalon end
set_interface_property avalon_s addressUnits WORDS
set_interface_property avalon_s associatedClock clock_sink
@ -114,9 +114,9 @@ set_interface_assignment avalon_s embeddedsw.configuration.isNonVolatileStorage
set_interface_assignment avalon_s embeddedsw.configuration.isPrintableDevice 0
#
#
# connection point bus
#
#
#add_sv_interface bus sc_if
# Setting the parameter property to add SV interface parameters
@ -131,9 +131,9 @@ set_interface_assignment avalon_s embeddedsw.configuration.isPrintableDevice 0
#add_fileset_file sc_if.sv SYSTEM_VERILOG PATH sc_if.sv SYSTEMVERILOG_INTERFACE
#
#
# connection point sc_if
#
#
add_interface sc_if conduit end
set_interface_property sc_if associatedClock ""
set_interface_property sc_if associatedReset ""
@ -143,18 +143,12 @@ set_interface_property sc_if PORT_NAME_MAP ""
set_interface_property sc_if CMSIS_SVD_VARIABLES ""
set_interface_property sc_if SVD_ADDRESS_GROUP ""
add_interface_port sc_if fe_status_i fe_status_i Input 32
add_interface_port sc_if fe_status2_i fe_status2_i Input 32
add_interface_port sc_if sc_status_i sc_status_i Input 32
add_interface_port sc_if sc_status2_i sc_status2_i Input 32
add_interface_port sc_if lt_status_i lt_status_i Input 32
add_interface_port sc_if hv_in_config_o hv_in_config_o Output 32
add_interface_port sc_if hv_in_config2_o hv_in_config2_o Output 32
add_interface_port sc_if hv_in_config3_o hv_in_config3_o Output 32
add_interface_port sc_if hv_out_config_o hv_out_config_o Output 32
add_interface_port sc_if hv_out_config2_o hv_out_config2_o Output 32
add_interface_port sc_if hv_out_config3_o hv_out_config3_o Output 32
add_interface_port sc_if xy_out_config_o xy_out_config_o Output 32
add_interface_port sc_if xy_out_config2_o xy_out_config2_o Output 32
add_interface_port sc_if h_config_o h_config_o Output 32
add_interface_port sc_if h_config2_o h_config2_o Output 32
add_interface_port sc_if v_config_o v_config_o Output 32
add_interface_port sc_if misc_config_o misc_config_o Output 32
add_interface_port sc_if sl_config_o sl_config_o Output 32
add_interface_port sc_if sl_config2_o sl_config2_o Output 32
add_interface_port sc_if sl_config3_o sl_config3_o Output 32

View File

@ -18,7 +18,7 @@ set_sw_property version 1.0
#
# Multiple-Version compatibility was introduced in version 7.1;
# prior versions are therefore excluded.
set_sw_property min_compatible_hw_version 1.0
set_sw_property min_compatible_hw_version 7.1
# Initialize the driver in alt_sys_init()
set_sw_property auto_initialize false

View File

@ -23,7 +23,7 @@ module sc_config_top(
input rst_i,
// avalon slave
input [31:0] avalon_s_writedata,
output reg [31:0] avalon_s_readdata,
output [31:0] avalon_s_readdata,
input [3:0] avalon_s_address,
input [3:0] avalon_s_byteenable,
input avalon_s_write,
@ -31,73 +31,144 @@ module sc_config_top(
input avalon_s_chipselect,
output avalon_s_waitrequest_n,
// SC interface
input [31:0] fe_status_i,
input [31:0] fe_status2_i,
input [31:0] sc_status_i,
input [31:0] sc_status2_i,
input [31:0] lt_status_i,
output [31:0] hv_in_config_o,
output [31:0] hv_in_config2_o,
output [31:0] hv_in_config3_o,
output [31:0] hv_out_config_o,
output [31:0] hv_out_config2_o,
output [31:0] hv_out_config3_o,
output [31:0] xy_out_config_o,
output [31:0] xy_out_config2_o,
output [31:0] misc_config_o,
output [31:0] sl_config_o,
output [31:0] sl_config2_o,
output [31:0] sl_config3_o
output reg [31:0] h_config_o,
output reg [31:0] h_config2_o,
output reg [31:0] v_config_o,
output reg [31:0] misc_config_o,
output reg [31:0] sl_config_o,
output reg [31:0] sl_config2_o
);
localparam FE_STATUS_REGNUM = 4'h0;
localparam FE_STATUS2_REGNUM = 4'h1;
localparam LT_STATUS_REGNUM = 4'h2;
localparam HV_IN_CONFIG_REGNUM = 4'h3;
localparam HV_IN_CONFIG2_REGNUM = 4'h4;
localparam HV_IN_CONFIG3_REGNUM = 4'h5;
localparam HV_OUT_CONFIG_REGNUM = 4'h6;
localparam HV_OUT_CONFIG2_REGNUM = 4'h7;
localparam HV_OUT_CONFIG3_REGNUM = 4'h8;
localparam XY_OUT_CONFIG_REGNUM = 4'h9;
localparam XY_OUT_CONFIG2_REGNUM = 4'ha;
localparam MISC_CONFIG_REGNUM = 4'hb;
localparam SL_CONFIG_REGNUM = 4'hc;
localparam SL_CONFIG2_REGNUM = 4'hd;
localparam SL_CONFIG3_REGNUM = 4'he;
localparam SC_STATUS_REGNUM = 4'h0;
localparam SC_STATUS2_REGNUM = 4'h1;
localparam LT_STATUS_REGNUM = 4'h2;
localparam H_CONFIG_REGNUM = 4'h3;
localparam H_CONFIG2_REGNUM = 4'h4;
localparam V_CONFIG_REGNUM = 4'h5;
localparam MISC_CONFIG_REGNUM = 4'h6;
localparam SL_CONFIG_REGNUM = 4'h7;
localparam SL_CONFIG2_REGNUM = 4'h8;
reg [31:0] config_reg[HV_IN_CONFIG_REGNUM:SL_CONFIG3_REGNUM] /* synthesis ramstyle = "logic" */;
assign avalon_s_waitrequest_n = 1'b1;
genvar i;
generate
for (i=HV_IN_CONFIG_REGNUM; i <= SL_CONFIG3_REGNUM; i++) begin : gen_reg
always @(posedge clk_i or posedge rst_i) begin
if (rst_i) begin
config_reg[i] <= 0;
end else begin
if (avalon_s_chipselect && avalon_s_write && (avalon_s_address==i)) begin
if (avalon_s_byteenable[3])
config_reg[i][31:24] <= avalon_s_writedata[31:24];
if (avalon_s_byteenable[2])
config_reg[i][23:16] <= avalon_s_writedata[23:16];
if (avalon_s_byteenable[1])
config_reg[i][15:8] <= avalon_s_writedata[15:8];
if (avalon_s_byteenable[0])
config_reg[i][7:0] <= avalon_s_writedata[7:0];
end
end
always @(posedge clk_i or posedge rst_i) begin
if (rst_i) begin
h_config_o <= 0;
end else begin
if (avalon_s_chipselect && avalon_s_write && (avalon_s_address==H_CONFIG_REGNUM)) begin
if (avalon_s_byteenable[3])
h_config_o[31:24] <= avalon_s_writedata[31:24];
if (avalon_s_byteenable[2])
h_config_o[23:16] <= avalon_s_writedata[23:16];
if (avalon_s_byteenable[1])
h_config_o[15:8] <= avalon_s_writedata[15:8];
if (avalon_s_byteenable[0])
h_config_o[7:0] <= avalon_s_writedata[7:0];
end
end
endgenerate
end
always @(posedge clk_i or posedge rst_i) begin
if (rst_i) begin
h_config2_o <= 0;
end else begin
if (avalon_s_chipselect && avalon_s_write && (avalon_s_address==H_CONFIG2_REGNUM)) begin
if (avalon_s_byteenable[3])
h_config2_o[31:24] <= avalon_s_writedata[31:24];
if (avalon_s_byteenable[2])
h_config2_o[23:16] <= avalon_s_writedata[23:16];
if (avalon_s_byteenable[1])
h_config2_o[15:8] <= avalon_s_writedata[15:8];
if (avalon_s_byteenable[0])
h_config2_o[7:0] <= avalon_s_writedata[7:0];
end
end
end
always @(posedge clk_i or posedge rst_i) begin
if (rst_i) begin
v_config_o <= 0;
end else begin
if (avalon_s_chipselect && avalon_s_write && (avalon_s_address==V_CONFIG_REGNUM)) begin
if (avalon_s_byteenable[3])
v_config_o[31:24] <= avalon_s_writedata[31:24];
if (avalon_s_byteenable[2])
v_config_o[23:16] <= avalon_s_writedata[23:16];
if (avalon_s_byteenable[1])
v_config_o[15:8] <= avalon_s_writedata[15:8];
if (avalon_s_byteenable[0])
v_config_o[7:0] <= avalon_s_writedata[7:0];
end
end
end
always @(posedge clk_i or posedge rst_i) begin
if (rst_i) begin
misc_config_o <= 0;
end else begin
if (avalon_s_chipselect && avalon_s_write && (avalon_s_address==MISC_CONFIG_REGNUM)) begin
if (avalon_s_byteenable[3])
misc_config_o[31:24] <= avalon_s_writedata[31:24];
if (avalon_s_byteenable[2])
misc_config_o[23:16] <= avalon_s_writedata[23:16];
if (avalon_s_byteenable[1])
misc_config_o[15:8] <= avalon_s_writedata[15:8];
if (avalon_s_byteenable[0])
misc_config_o[7:0] <= avalon_s_writedata[7:0];
end
end
end
always @(posedge clk_i or posedge rst_i) begin
if (rst_i) begin
sl_config_o <= 0;
end else begin
if (avalon_s_chipselect && avalon_s_write && (avalon_s_address==SL_CONFIG_REGNUM)) begin
if (avalon_s_byteenable[3])
sl_config_o[31:24] <= avalon_s_writedata[31:24];
if (avalon_s_byteenable[2])
sl_config_o[23:16] <= avalon_s_writedata[23:16];
if (avalon_s_byteenable[1])
sl_config_o[15:8] <= avalon_s_writedata[15:8];
if (avalon_s_byteenable[0])
sl_config_o[7:0] <= avalon_s_writedata[7:0];
end
end
end
always @(posedge clk_i or posedge rst_i) begin
if (rst_i) begin
sl_config2_o <= 0;
end else begin
if (avalon_s_chipselect && avalon_s_write && (avalon_s_address==SL_CONFIG2_REGNUM)) begin
if (avalon_s_byteenable[3])
sl_config2_o[31:24] <= avalon_s_writedata[31:24];
if (avalon_s_byteenable[2])
sl_config2_o[23:16] <= avalon_s_writedata[23:16];
if (avalon_s_byteenable[1])
sl_config2_o[15:8] <= avalon_s_writedata[15:8];
if (avalon_s_byteenable[0])
sl_config2_o[7:0] <= avalon_s_writedata[7:0];
end
end
end
// no readback for config regs -> unused bits optimized out
always @(*) begin
if (avalon_s_chipselect && avalon_s_read) begin
case (avalon_s_address)
FE_STATUS_REGNUM: avalon_s_readdata = fe_status_i;
FE_STATUS2_REGNUM: avalon_s_readdata = fe_status2_i;
SC_STATUS_REGNUM: avalon_s_readdata = sc_status_i;
SC_STATUS2_REGNUM: avalon_s_readdata = sc_status2_i;
LT_STATUS_REGNUM: avalon_s_readdata = lt_status_i;
H_CONFIG_REGNUM: avalon_s_readdata = h_config_o;
H_CONFIG2_REGNUM: avalon_s_readdata = h_config2_o;
V_CONFIG_REGNUM: avalon_s_readdata = v_config_o;
MISC_CONFIG_REGNUM: avalon_s_readdata = misc_config_o;
SL_CONFIG_REGNUM: avalon_s_readdata = sl_config_o;
SL_CONFIG2_REGNUM: avalon_s_readdata = sl_config2_o;
default: avalon_s_readdata = 32'h00000000;
endcase
end else begin
@ -105,17 +176,4 @@ always @(*) begin
end
end
assign hv_in_config_o = config_reg[HV_IN_CONFIG_REGNUM];
assign hv_in_config2_o = config_reg[HV_IN_CONFIG2_REGNUM];
assign hv_in_config3_o = config_reg[HV_IN_CONFIG3_REGNUM];
assign hv_out_config_o = config_reg[HV_OUT_CONFIG_REGNUM];
assign hv_out_config2_o = config_reg[HV_OUT_CONFIG2_REGNUM];
assign hv_out_config3_o = config_reg[HV_OUT_CONFIG3_REGNUM];
assign xy_out_config_o = config_reg[XY_OUT_CONFIG_REGNUM];
assign xy_out_config2_o = config_reg[XY_OUT_CONFIG2_REGNUM];
assign misc_config_o = config_reg[MISC_CONFIG_REGNUM];
assign sl_config_o = config_reg[SL_CONFIG_REGNUM];
assign sl_config2_o = config_reg[SL_CONFIG2_REGNUM];
assign sl_config3_o = config_reg[SL_CONFIG3_REGNUM];
endmodule

View File

@ -19,7 +19,7 @@
<auto_create_rpd>0</auto_create_rpd>
<rpd_little_endian>1</rpd_little_endian>
<options>
<map_file>0</map_file>
<map_file>1</map_file>
</options>
<advanced_options>
<ignore_epcs_id_check>0</ignore_epcs_id_check>

104
ossc.qsf
View File

@ -1,17 +1,17 @@
# -------------------------------------------------------------------------- #
#
# Copyright (C) 1991-2013 Altera Corporation
# Your use of Altera Corporation's design tools, logic functions
# and other software and tools, and its AMPP partner logic
# functions, and any output files from any of the foregoing
# (including device programming or simulation files), and any
# associated documentation or information are expressly subject
# to the terms and conditions of the Altera Program License
# Subscription Agreement, Altera MegaCore Function License
# Agreement, or other applicable license agreement, including,
# without limitation, that your use is for the sole purpose of
# programming logic devices manufactured by Altera and sold by
# Altera or its authorized distributors. Please refer to the
# Your use of Altera Corporation's design tools, logic functions
# and other software and tools, and its AMPP partner logic
# functions, and any output files from any of the foregoing
# (including device programming or simulation files), and any
# associated documentation or information are expressly subject
# to the terms and conditions of the Altera Program License
# Subscription Agreement, Altera MegaCore Function License
# Agreement, or other applicable license agreement, including,
# without limitation, that your use is for the sole purpose of
# programming logic devices manufactured by Altera and sold by
# Altera or its authorized distributors. Please refer to the
# applicable agreement for further details.
#
# -------------------------------------------------------------------------- #
@ -41,7 +41,7 @@ set_global_assignment -name DEVICE EP4CE15E22C8
set_global_assignment -name TOP_LEVEL_ENTITY ossc
set_global_assignment -name ORIGINAL_QUARTUS_VERSION 13.1
set_global_assignment -name PROJECT_CREATION_TIME_DATE "17:27:03 MAY 17, 2014"
set_global_assignment -name LAST_QUARTUS_VERSION "21.1.0 Lite Edition"
set_global_assignment -name LAST_QUARTUS_VERSION "20.1.1 Lite Edition"
set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files
set_global_assignment -name MIN_CORE_JUNCTION_TEMP 0
set_global_assignment -name MAX_CORE_JUNCTION_TEMP 85
@ -59,40 +59,38 @@ set_global_assignment -name STRATIX_DEVICE_IO_STANDARD "3.3-V LVTTL"
set_location_assignment PIN_25 -to clk27
set_location_assignment PIN_99 -to hw_reset_n
set_location_assignment PIN_23 -to ir_rx
set_location_assignment PIN_126 -to cfg[1]
set_location_assignment PIN_127 -to cfg[0]
#============================================================
# TVP7002
#============================================================
set_location_assignment PIN_52 -to TVP_R_i[0]
set_location_assignment PIN_53 -to TVP_R_i[1]
set_location_assignment PIN_54 -to TVP_R_i[2]
set_location_assignment PIN_55 -to TVP_R_i[3]
set_location_assignment PIN_58 -to TVP_R_i[4]
set_location_assignment PIN_59 -to TVP_R_i[5]
set_location_assignment PIN_60 -to TVP_R_i[6]
set_location_assignment PIN_61 -to TVP_R_i[7]
set_location_assignment PIN_88 -to TVP_B_i[7]
set_location_assignment PIN_87 -to TVP_B_i[6]
set_location_assignment PIN_86 -to TVP_B_i[5]
set_location_assignment PIN_85 -to TVP_B_i[4]
set_location_assignment PIN_83 -to TVP_B_i[3]
set_location_assignment PIN_80 -to TVP_B_i[2]
set_location_assignment PIN_77 -to TVP_B_i[1]
set_location_assignment PIN_89 -to TVP_PCLK_i
set_location_assignment PIN_76 -to TVP_B_i[0]
set_location_assignment PIN_90 -to TVP_HS_i
set_location_assignment PIN_91 -to TVP_VSYNC_i
set_location_assignment PIN_98 -to TVP_SOG_i
set_location_assignment PIN_72 -to TVP_G_i[7]
set_location_assignment PIN_71 -to TVP_G_i[6]
set_location_assignment PIN_69 -to TVP_G_i[5]
set_location_assignment PIN_68 -to TVP_G_i[4]
set_location_assignment PIN_67 -to TVP_G_i[3]
set_location_assignment PIN_66 -to TVP_G_i[2]
set_location_assignment PIN_65 -to TVP_G_i[1]
set_location_assignment PIN_64 -to TVP_G_i[0]
set_location_assignment PIN_52 -to R_in[0]
set_location_assignment PIN_53 -to R_in[1]
set_location_assignment PIN_54 -to R_in[2]
set_location_assignment PIN_55 -to R_in[3]
set_location_assignment PIN_58 -to R_in[4]
set_location_assignment PIN_59 -to R_in[5]
set_location_assignment PIN_60 -to R_in[6]
set_location_assignment PIN_61 -to R_in[7]
set_location_assignment PIN_88 -to B_in[7]
set_location_assignment PIN_87 -to B_in[6]
set_location_assignment PIN_86 -to B_in[5]
set_location_assignment PIN_85 -to B_in[4]
set_location_assignment PIN_83 -to B_in[3]
set_location_assignment PIN_80 -to B_in[2]
set_location_assignment PIN_77 -to B_in[1]
set_location_assignment PIN_89 -to PCLK_in
set_location_assignment PIN_76 -to B_in[0]
set_location_assignment PIN_90 -to HSYNC_in
set_location_assignment PIN_91 -to VSYNC_in
set_location_assignment PIN_98 -to FID_in
set_location_assignment PIN_72 -to G_in[7]
set_location_assignment PIN_71 -to G_in[6]
set_location_assignment PIN_69 -to G_in[5]
set_location_assignment PIN_68 -to G_in[4]
set_location_assignment PIN_67 -to G_in[3]
set_location_assignment PIN_66 -to G_in[2]
set_location_assignment PIN_65 -to G_in[1]
set_location_assignment PIN_64 -to G_in[0]
#============================================================
# HDMITX
@ -126,6 +124,7 @@ set_location_assignment PIN_7 -to HDMI_TX_RD[5]
set_location_assignment PIN_10 -to HDMI_TX_RD[6]
set_location_assignment PIN_11 -to HDMI_TX_RD[7]
set_location_assignment PIN_100 -to HDMI_TX_INT_N
set_location_assignment PIN_127 -to HDMI_TX_MODE
#============================================================
# SD card
@ -188,7 +187,7 @@ set_global_assignment -name PHYSICAL_SYNTHESIS_EFFORT NORMAL
set_global_assignment -name PHYSICAL_SYNTHESIS_COMBO_LOGIC OFF
set_global_assignment -name PHYSICAL_SYNTHESIS_REGISTER_DUPLICATION OFF
set_global_assignment -name OPTIMIZATION_MODE BALANCED
set_global_assignment -name OPTIMIZATION_MODE "AGGRESSIVE PERFORMANCE"
set_global_assignment -name ALLOW_REGISTER_RETIMING OFF
set_global_assignment -name ENABLE_OCT_DONE OFF
@ -212,14 +211,14 @@ set_global_assignment -name POWER_DEFAULT_INPUT_IO_TOGGLE_RATE 50%
set_global_assignment -name ROUTER_CLOCKING_TOPOLOGY_ANALYSIS ON
set_global_assignment -name PLACEMENT_EFFORT_MULTIPLIER 1
set_global_assignment -name PLACEMENT_EFFORT_MULTIPLIER 8.0
set_global_assignment -name ROUTER_EFFORT_MULTIPLIER 2.0
set_global_assignment -name CYCLONEII_OPTIMIZATION_TECHNIQUE SPEED
set_global_assignment -name ENABLE_SIGNALTAP OFF
set_global_assignment -name USE_SIGNALTAP_FILE output_files/ossc_new.stp
set_global_assignment -name USE_SIGNALTAP_FILE output_files/ossc_la.stp
set_global_assignment -name FITTER_EFFORT "AUTO FIT"
set_global_assignment -name SEED 3
set_global_assignment -name SEED 2
@ -235,24 +234,17 @@ set_global_assignment -name VERILOG_FILE rtl/videogen.v
set_global_assignment -name VERILOG_FILE rtl/ir_rcv.v
set_global_assignment -name VERILOG_FILE rtl/ossc.v
set_global_assignment -name VERILOG_FILE rtl/scanconverter.v
set_global_assignment -name VERILOG_FILE rtl/linebuf_top.v
set_global_assignment -name VERILOG_FILE rtl/tvp7002_frontend.v
set_global_assignment -name VERILOG_FILE rtl/lat_tester.v
set_global_assignment -name QIP_FILE sys/synthesis/sys.qip
set_global_assignment -name QIP_FILE software/sys_controller/mem_init/meminit.qip
set_global_assignment -name QIP_FILE rtl/linebuf.qip
set_global_assignment -name QIP_FILE rtl/char_rom.qip
set_global_assignment -name QIP_FILE rtl/pll_2x.qip
set_global_assignment -name QIP_FILE rtl/lpm_mult_hybr_ref_pre.qip
set_global_assignment -name QIP_FILE rtl/lpm_mult_hybr_ref.qip
set_global_assignment -name QIP_FILE rtl/lpm_mult_sl.qip
set_global_assignment -name QIP_FILE rtl/lpm_mult_4_hybr_ref_pre.qip
set_global_assignment -name QIP_FILE rtl/lpm_mult_4_hybr_ref.qip
set_global_assignment -name QIP_FILE rtl/lpm_mult_4_sl.qip
set_global_assignment -name SDC_FILE ossc.sdc
set_global_assignment -name CDF_FILE output_files/Chain1.cdf
set_global_assignment -name SIGNALTAP_FILE output_files/ossc_la.stp
set_global_assignment -name QIP_FILE rtl/char_array.qip
set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top

View File

@ -3,30 +3,42 @@
create_clock -period 27MHz -name clk27 [get_ports clk27]
set_input_delay -clock clk27 0 [get_ports {sda scl SD_CMD SD_DAT* *ALTERA_DATA0}]
set_false_path -from [get_ports {btn* cfg* ir_rx HDMI_TX_INT_N LED_R}]
set_false_path -from [get_ports {btn* ir_rx HDMI_TX_INT_N HDMI_TX_MODE}]
set_false_path -to {sys:sys_inst|sys_pio_1:pio_1|readdata*}
### Scanconverter clock constraints ###
create_clock -period 165MHz -name pclk_tvp_high [get_ports TVP_PCLK_i]
create_clock -period 33MHz -name pclk_tvp_low [get_ports TVP_PCLK_i] -add
create_clock -period 108MHz -name pclk_1x [get_ports PCLK_in]
create_clock -period 54MHz -name pclk_2x_source [get_ports PCLK_in] -add
create_clock -period 54MHz -name pclk_3x_source [get_ports PCLK_in] -add
create_clock -period 33MHz -name pclk_4x_source [get_ports PCLK_in] -add
create_clock -period 33MHz -name pclk_5x_source [get_ports PCLK_in] -add
#derive_pll_clocks
create_generated_clock -name pclk_5x -master_clock pclk_tvp_low -source {pll_pclk|altpll_component|auto_generated|pll1|inclk[1]} -multiply_by 5 -duty_cycle 50.00 {pll_pclk|altpll_component|auto_generated|pll1|clk[0]}
create_generated_clock -name pclk_27mhz -master_clock clk27 -source {pll_pclk|altpll_component|auto_generated|pll1|inclk[0]} -multiply_by 1 -duty_cycle 50.00 {pll_pclk|altpll_component|auto_generated|pll1|clk[0]} -add
create_generated_clock -name pclk_2x -master_clock pclk_2x_source -source {scanconverter_inst|pll_pclk|altpll_component|auto_generated|pll1|inclk[1]} -multiply_by 2 -duty_cycle 50.00 {scanconverter_inst|pll_pclk|altpll_component|auto_generated|pll1|clk[0]} -add
create_generated_clock -name pclk_3x -master_clock pclk_3x_source -source {scanconverter_inst|pll_pclk|altpll_component|auto_generated|pll1|inclk[1]} -multiply_by 3 -duty_cycle 50.00 {scanconverter_inst|pll_pclk|altpll_component|auto_generated|pll1|clk[0]} -add
create_generated_clock -name pclk_4x -master_clock pclk_4x_source -source {scanconverter_inst|pll_pclk|altpll_component|auto_generated|pll1|inclk[1]} -multiply_by 4 -duty_cycle 50.00 {scanconverter_inst|pll_pclk|altpll_component|auto_generated|pll1|clk[1]} -add
create_generated_clock -name pclk_5x -master_clock pclk_5x_source -source {scanconverter_inst|pll_pclk|altpll_component|auto_generated|pll1|inclk[1]} -multiply_by 5 -duty_cycle 50.00 {scanconverter_inst|pll_pclk|altpll_component|auto_generated|pll1|clk[1]} -add
create_generated_clock -name pclk_27mhz -master_clock clk27 -source {scanconverter_inst|pll_pclk|altpll_component|auto_generated|pll1|inclk[0]} -multiply_by 1 -duty_cycle 50.00 {scanconverter_inst|pll_pclk|altpll_component|auto_generated|pll1|clk[0]} -add
# retrieve post-mapping clkmux output pin
set clkmux_output [get_pins clkctrl1|outclk]
set clkmux_output [get_pins scanconverter_inst|clkctrl1|outclk]
# specify postmux clocks which clock postprocess pipeline
create_generated_clock -name pclk_1x_postmux -master_clock pclk_tvp_high -source [get_pins clkctrl1|inclk[0]] -multiply_by 1 $clkmux_output
create_generated_clock -name pclk_5x_postmux -master_clock pclk_5x -source [get_pins clkctrl1|inclk[2]] -multiply_by 1 $clkmux_output -add
create_generated_clock -name pclk_27mhz_postmux -master_clock pclk_27mhz -source [get_pins clkctrl1|inclk[2]] -multiply_by 1 $clkmux_output -add
create_generated_clock -name pclk_1x_postmux -master_clock pclk_1x -source [get_pins scanconverter_inst|clkctrl1|inclk[0]] -multiply_by 1 $clkmux_output
create_generated_clock -name pclk_2x_postmux -master_clock pclk_2x -source [get_pins scanconverter_inst|clkctrl1|inclk[2]] -multiply_by 1 $clkmux_output -add
create_generated_clock -name pclk_3x_postmux -master_clock pclk_3x -source [get_pins scanconverter_inst|clkctrl1|inclk[2]] -multiply_by 1 $clkmux_output -add
create_generated_clock -name pclk_4x_postmux -master_clock pclk_4x -source [get_pins scanconverter_inst|clkctrl1|inclk[3]] -multiply_by 1 $clkmux_output -add
create_generated_clock -name pclk_5x_postmux -master_clock pclk_5x -source [get_pins scanconverter_inst|clkctrl1|inclk[3]] -multiply_by 1 $clkmux_output -add
create_generated_clock -name pclk_27mhz_postmux -master_clock pclk_27mhz -source [get_pins scanconverter_inst|clkctrl1|inclk[2]] -multiply_by 1 $clkmux_output -add
# specify output clocks that drive PCLK output pin
set pclk_out_port [get_ports HDMI_TX_PCLK]
create_generated_clock -name pclk_1x_out -master_clock pclk_1x_postmux -source $clkmux_output -multiply_by 1 $pclk_out_port
create_generated_clock -name pclk_2x_out -master_clock pclk_2x_postmux -source $clkmux_output -multiply_by 1 $pclk_out_port -add
create_generated_clock -name pclk_3x_out -master_clock pclk_3x_postmux -source $clkmux_output -multiply_by 1 $pclk_out_port -add
create_generated_clock -name pclk_4x_out -master_clock pclk_4x_postmux -source $clkmux_output -multiply_by 1 $pclk_out_port -add
create_generated_clock -name pclk_5x_out -master_clock pclk_5x_postmux -source $clkmux_output -multiply_by 1 $pclk_out_port -add
create_generated_clock -name pclk_27mhz_out -master_clock pclk_27mhz_postmux -source $clkmux_output -multiply_by 1 $pclk_out_port -add
@ -35,8 +47,8 @@ derive_clock_uncertainty
# input delay constraints
set TVP_dmin 0
set TVP_dmax 1.5
set critinputs [get_ports {TVP_R_i* TVP_G_i* TVP_B_i* TVP_HS_i TVP_SOG_i TVP_VSYNC_i}]
foreach_in_collection c [get_clocks "pclk_tvp*"] {
set critinputs [get_ports {R_in* G_in* B_in* HSYNC_in VSYNC_in FID_in}]
foreach_in_collection c [get_clocks "pclk_1x pclk_*_source"] {
set_input_delay -clock $c -min $TVP_dmin $critinputs -add_delay
set_input_delay -clock $c -max $TVP_dmax $critinputs -add_delay
}
@ -55,14 +67,27 @@ set_false_path -to [remove_from_collection [all_outputs] $critoutputs_hdmi]
### CPU/scanconverter clock relations ###
# Treat CPU clock asynchronous to pixel clocks
# Treat CPU clock asynchronous to pixel clocks
set_clock_groups -asynchronous -group \
{clk27} \
{pclk_27mhz pclk_27mhz_postmux pclk_27mhz_out} \
{pclk_tvp_low} \
{pclk_tvp_high} \
{pclk_1x_postmux pclk_1x_out} \
{pclk_5x pclk_5x_postmux pclk_5x_out}
{clk27 pclk_27mhz pclk_27mhz_postmux pclk_27mhz_out} \
{pclk_1x pclk_1x_postmux pclk_1x_out} \
{pclk_2x_source pclk_2x pclk_2x_postmux pclk_2x_out} \
{pclk_3x_source pclk_3x pclk_3x_postmux pclk_3x_out} \
{pclk_4x_source pclk_4x pclk_4x_postmux pclk_4x_out} \
{pclk_5x_source pclk_5x pclk_5x_postmux pclk_5x_out}
# Ignore paths from registers which are updated only at leading edge of vsync
set_false_path -from [get_registers {scanconverter_inst|H_* scanconverter_inst|V_* scanconverter_inst|X_* scanconverter_inst|SL_* scanconverter_inst|LT_POS_*}]
# Ignore paths from registers which are updated only at leading edge of hsync
#set_false_path -from [get_registers {scanconverter:scanconverter_inst|line_idx scanconverter:scanconverter_inst|line_out_idx* scanconverter:scanconverter_inst|hmax*}]
# Ignore paths that cross clock domains from 3x to 2x and 5x to 4x, since they share a clock line, but cannot co-occur.
set_false_path -from [get_clocks {pclk_3x*}] -to [get_registers {scanconverter:scanconverter_inst|*_2x*}]
set_false_path -from [get_clocks {pclk_5x*}] -to [get_registers {scanconverter:scanconverter_inst|*_4x*}]
# Ignore paths to latency tester sync regs
set_false_path -to [get_registers {lat_tester:lt0|mode_synced* lat_tester:lt0|VSYNC_in_* lat_tester:lt0|trigger_*}]
### JTAG Signal Constraints ###

View File

@ -5,14 +5,14 @@
<Project Name="ossc_sw" Path="software/ossc_sw.project" Active="Yes"/>
<Project Name="tools" Path="tools.project" Active="No"/>
<BuildMatrix>
<WorkspaceConfiguration Name="Debug">
<WorkspaceConfiguration Name="Debug" Selected="no">
<Environment/>
<Project Name="ossc_rtl" ConfigName="Debug"/>
<Project Name="ossc_sw_bsp" ConfigName="Debug"/>
<Project Name="ossc_sw" ConfigName="Debug"/>
<Project Name="tools" ConfigName="Debug"/>
</WorkspaceConfiguration>
<WorkspaceConfiguration Name="Release">
<WorkspaceConfiguration Name="Release" Selected="yes">
<Environment/>
<Project Name="ossc_rtl" ConfigName="Release"/>
<Project Name="ossc_sw_bsp" ConfigName="Release"/>

View File

@ -1,5 +1,5 @@
set_global_assignment -name IP_TOOL_NAME "RAM: 2-PORT"
set_global_assignment -name IP_TOOL_VERSION "21.1"
set_global_assignment -name IP_TOOL_VERSION "20.1"
set_global_assignment -name IP_GENERATED_DEVICE_FAMILY "{Cyclone IV E}"
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "char_array.v"]
set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "char_array_inst.v"]

View File

@ -14,11 +14,11 @@
// ************************************************************
// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
//
// 21.1.0 Build 842 10/21/2021 SJ Lite Edition
// 20.1.1 Build 720 11/11/2020 SJ Lite Edition
// ************************************************************
//Copyright (C) 2021 Intel Corporation. All rights reserved.
//Copyright (C) 2020 Intel Corporation. All rights reserved.
//Your use of Intel Corporation's design tools, logic functions
//and other software and tools, and any partner logic
//functions, and any output files from any of the foregoing

View File

@ -1,5 +1,5 @@
set_global_assignment -name IP_TOOL_NAME "ROM: 1-PORT"
set_global_assignment -name IP_TOOL_VERSION "21.1"
set_global_assignment -name IP_TOOL_VERSION "20.1"
set_global_assignment -name IP_GENERATED_DEVICE_FAMILY "{Cyclone IV E}"
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "char_rom.v"]
set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "char_rom_inst.v"]

View File

@ -14,11 +14,11 @@
// ************************************************************
// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
//
// 21.1.0 Build 842 10/21/2021 SJ Lite Edition
// 20.1.1 Build 720 11/11/2020 SJ Lite Edition
// ************************************************************
//Copyright (C) 2021 Intel Corporation. All rights reserved.
//Copyright (C) 2020 Intel Corporation. All rights reserved.
//Your use of Intel Corporation's design tools, logic functions
//and other software and tools, and any partner logic
//functions, and any output files from any of the foregoing

View File

@ -1,4 +1,6 @@
set_global_assignment -name IP_TOOL_NAME "RAM: 2-PORT"
set_global_assignment -name IP_TOOL_VERSION "21.1"
set_global_assignment -name IP_TOOL_VERSION "20.1"
set_global_assignment -name IP_GENERATED_DEVICE_FAMILY "{Cyclone IV E}"
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "linebuf.v"]
set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "linebuf_inst.v"]
set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "linebuf_bb.v"]

View File

@ -14,11 +14,11 @@
// ************************************************************
// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
//
// 21.1.0 Build 842 10/21/2021 SJ Lite Edition
// 20.1.1 Build 720 11/11/2020 SJ Lite Edition
// ************************************************************
//Copyright (C) 2021 Intel Corporation. All rights reserved.
//Copyright (C) 2020 Intel Corporation. All rights reserved.
//Your use of Intel Corporation's design tools, logic functions
//and other software and tools, and any partner logic
//functions, and any output files from any of the foregoing
@ -41,28 +41,22 @@ module linebuf (
data,
rdaddress,
rdclock,
rdclocken,
wraddress,
wrclock,
wrclocken,
wren,
q);
input [23:0] data;
input [11:0] rdaddress;
input rdclock;
input rdclocken;
input [11:0] wraddress;
input wrclock;
input wrclocken;
input wren;
output [23:0] q;
`ifndef ALTERA_RESERVED_QIS
// synopsys translate_off
`endif
tri1 rdclocken;
tri1 wrclock;
tri1 wrclocken;
tri0 wren;
`ifndef ALTERA_RESERVED_QIS
// synopsys translate_on
@ -76,8 +70,6 @@ module linebuf (
.address_b (rdaddress),
.clock0 (wrclock),
.clock1 (rdclock),
.clocken0 (wrclocken),
.clocken1 (rdclocken),
.data_a (data),
.wren_a (wren),
.q_b (sub_wire0),
@ -87,6 +79,8 @@ module linebuf (
.addressstall_b (1'b0),
.byteena_a (1'b1),
.byteena_b (1'b1),
.clocken0 (1'b1),
.clocken1 (1'b1),
.clocken2 (1'b1),
.clocken3 (1'b1),
.data_b ({24{1'b1}}),
@ -98,9 +92,9 @@ module linebuf (
defparam
altsyncram_component.address_aclr_b = "NONE",
altsyncram_component.address_reg_b = "CLOCK1",
altsyncram_component.clock_enable_input_a = "NORMAL",
altsyncram_component.clock_enable_input_b = "NORMAL",
altsyncram_component.clock_enable_output_b = "NORMAL",
altsyncram_component.clock_enable_input_a = "BYPASS",
altsyncram_component.clock_enable_input_b = "BYPASS",
altsyncram_component.clock_enable_output_b = "BYPASS",
altsyncram_component.intended_device_family = "Cyclone IV E",
altsyncram_component.lpm_type = "altsyncram",
altsyncram_component.numwords_a = 4096,
@ -129,10 +123,10 @@ endmodule
// Retrieval info: PRIVATE: BYTE_ENABLE_B NUMERIC "0"
// Retrieval info: PRIVATE: BYTE_SIZE NUMERIC "8"
// Retrieval info: PRIVATE: BlankMemory NUMERIC "1"
// Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_A NUMERIC "1"
// Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_B NUMERIC "1"
// Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_A NUMERIC "1"
// Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_B NUMERIC "1"
// Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_A NUMERIC "0"
// Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_B NUMERIC "0"
// Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_A NUMERIC "0"
// Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_B NUMERIC "0"
// Retrieval info: PRIVATE: CLRdata NUMERIC "0"
// Retrieval info: PRIVATE: CLRq NUMERIC "0"
// Retrieval info: PRIVATE: CLRrdaddress NUMERIC "0"
@ -178,14 +172,14 @@ endmodule
// Retrieval info: PRIVATE: WRADDR_ACLR_B NUMERIC "0"
// Retrieval info: PRIVATE: WRADDR_REG_B NUMERIC "0"
// Retrieval info: PRIVATE: WRCTRL_ACLR_B NUMERIC "0"
// Retrieval info: PRIVATE: enable NUMERIC "1"
// Retrieval info: PRIVATE: enable NUMERIC "0"
// Retrieval info: PRIVATE: rden NUMERIC "0"
// Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all
// Retrieval info: CONSTANT: ADDRESS_ACLR_B STRING "NONE"
// Retrieval info: CONSTANT: ADDRESS_REG_B STRING "CLOCK1"
// Retrieval info: CONSTANT: CLOCK_ENABLE_INPUT_A STRING "NORMAL"
// Retrieval info: CONSTANT: CLOCK_ENABLE_INPUT_B STRING "NORMAL"
// Retrieval info: CONSTANT: CLOCK_ENABLE_OUTPUT_B STRING "NORMAL"
// Retrieval info: CONSTANT: CLOCK_ENABLE_INPUT_A STRING "BYPASS"
// Retrieval info: CONSTANT: CLOCK_ENABLE_INPUT_B STRING "BYPASS"
// Retrieval info: CONSTANT: CLOCK_ENABLE_OUTPUT_B STRING "BYPASS"
// Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone IV E"
// Retrieval info: CONSTANT: LPM_TYPE STRING "altsyncram"
// Retrieval info: CONSTANT: NUMWORDS_A NUMERIC "4096"
@ -203,17 +197,13 @@ endmodule
// Retrieval info: USED_PORT: q 0 0 24 0 OUTPUT NODEFVAL "q[23..0]"
// Retrieval info: USED_PORT: rdaddress 0 0 12 0 INPUT NODEFVAL "rdaddress[11..0]"
// Retrieval info: USED_PORT: rdclock 0 0 0 0 INPUT NODEFVAL "rdclock"
// Retrieval info: USED_PORT: rdclocken 0 0 0 0 INPUT VCC "rdclocken"
// Retrieval info: USED_PORT: wraddress 0 0 12 0 INPUT NODEFVAL "wraddress[11..0]"
// Retrieval info: USED_PORT: wrclock 0 0 0 0 INPUT VCC "wrclock"
// Retrieval info: USED_PORT: wrclocken 0 0 0 0 INPUT VCC "wrclocken"
// Retrieval info: USED_PORT: wren 0 0 0 0 INPUT GND "wren"
// Retrieval info: CONNECT: @address_a 0 0 12 0 wraddress 0 0 12 0
// Retrieval info: CONNECT: @address_b 0 0 12 0 rdaddress 0 0 12 0
// Retrieval info: CONNECT: @clock0 0 0 0 0 wrclock 0 0 0 0
// Retrieval info: CONNECT: @clock1 0 0 0 0 rdclock 0 0 0 0
// Retrieval info: CONNECT: @clocken0 0 0 0 0 wrclocken 0 0 0 0
// Retrieval info: CONNECT: @clocken1 0 0 0 0 rdclocken 0 0 0 0
// Retrieval info: CONNECT: @data_a 0 0 24 0 data 0 0 24 0
// Retrieval info: CONNECT: @wren_a 0 0 0 0 wren 0 0 0 0
// Retrieval info: CONNECT: q 0 0 24 0 @q_b 0 0 24 0
@ -221,6 +211,6 @@ endmodule
// Retrieval info: GEN_FILE: TYPE_NORMAL linebuf.inc FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL linebuf.cmp FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL linebuf.bsf FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL linebuf_inst.v FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL linebuf_bb.v FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL linebuf_inst.v TRUE
// Retrieval info: GEN_FILE: TYPE_NORMAL linebuf_bb.v TRUE
// Retrieval info: LIB_FILE: altera_mf

View File

@ -1,279 +0,0 @@
//
// Copyright (C) 2022 Markus Hiienkari <mhiienka@niksula.hut.fi>
//
// This file is part of Open Source Scan Converter project.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
//`define DEBUG
module linebuf_top (
input PCLK_CAP_i,
input PCLK_OUT_i,
input [7:0] R_i,
input [7:0] G_i,
input [7:0] B_i,
input DE_i,
input datavalid_i,
input [11:0] h_in_active,
input [10:0] xpos_i,
input [10:0] ypos_i,
input [10:0] xpos_lb,
input [10:0] ypos_lb,
input [10:0] ypos_lb_next,
input line_id,
input lb_enable,
output [7:0] R_linebuf,
output [7:0] G_linebuf,
output [7:0] B_linebuf,
// optional EMIF if
input emif_br_clk,
input emif_br_reset,
output reg [27:0] emif_rd_addr,
output reg emif_rd_read,
input [255:0] emif_rd_rdata,
input emif_rd_waitrequest,
input emif_rd_readdatavalid,
output reg [5:0] emif_rd_burstcount,
output [27:0] emif_wr_addr,
output reg emif_wr_write,
output [255:0] emif_wr_wdata,
input emif_wr_waitrequest,
output reg [5:0] emif_wr_burstcount
);
parameter EMIF_ENABLE = 0;
parameter NUM_LINE_BUFFERS = 32;
localparam EMIF_WR_MAXBURST = 32;
localparam EMIF_RD_MAXBURST = 32;
generate
if (EMIF_ENABLE) begin
`ifdef DEBUG
reg [10:0] emif_wr_stall_ctr /* synthesis noprune */;
reg [10:0] emif_rd_stall_ctr /* synthesis noprune */;
reg emif_rd_line_missed /* synthesis noprune */;
always @(posedge emif_br_clk) begin
if (emif_wr_write & emif_wr_waitrequest & (emif_wr_stall_ctr != 2047))
emif_wr_stall_ctr <= emif_wr_stall_ctr + 1'b1;
else
emif_wr_stall_ctr <= 0;
if (emif_rd_burstcount > 0) begin
if (emif_rd_readdatavalid)
emif_rd_stall_ctr <= 0;
else
emif_rd_stall_ctr <= emif_rd_stall_ctr + 1'b1;
end
end
`endif
// Number of 8-pixel blocks per line
wire [8:0] blocks_per_line = (h_in_active / 8) + (h_in_active[2:0] != 3'h0);
/* ------------------------------ EMIF WR interface ------------------------------ */
// PCLK_CAP_i related signals
reg [8:0] emif_wr_fifo_blksleft;
reg [19:0] emif_wr_fifo_addr; // [19:9] = y_pos; [8:0] = x_pos_x8
reg [23:0] emif_wr_fifo_pixs[7:0] /* synthesis ramstyle = "logic" */;
reg emif_wr_fifo_wrreq;
reg [8:0] blocks_inserted;
reg DE_prev;
wire emif_wr_fifo_wrfull;
// emif_br_clk related signals
wire [8:0] emif_wr_fifo_blksleft_q;
reg [8:0] emif_wr_blksleft;
wire [19:0] emif_wr_fifo_addr_q;
wire [23:0] emif_wr_fifo_pixs_q[7:0];
reg emif_wr_fifo_iniread_prev;
wire emif_wr_fifo_rdempty;
wire [8:0] emif_wr_fifo_rdusedw;
wire emif_wr_fifo_iniread = (lb_enable & (emif_wr_blksleft == 0) & !emif_wr_fifo_iniread_prev & !emif_wr_fifo_rdempty);
wire emif_wr_fifo_rdreq = emif_wr_fifo_iniread | ((emif_wr_burstcount > 1) & !emif_wr_waitrequest);
assign emif_wr_addr = {3'b001, emif_wr_fifo_addr_q, 5'h0};
assign emif_wr_wdata = {8'h0, emif_wr_fifo_pixs_q[0], 8'h0, emif_wr_fifo_pixs_q[1], 8'h0, emif_wr_fifo_pixs_q[2], 8'h0, emif_wr_fifo_pixs_q[3],
8'h0, emif_wr_fifo_pixs_q[4], 8'h0, emif_wr_fifo_pixs_q[5], 8'h0, emif_wr_fifo_pixs_q[6], 8'h0, emif_wr_fifo_pixs_q[7]};
dc_fifo_emif_wr dc_fifo_emif_wr_inst (
.data({emif_wr_fifo_blksleft, emif_wr_fifo_addr,
emif_wr_fifo_pixs[0], emif_wr_fifo_pixs[1], emif_wr_fifo_pixs[2], emif_wr_fifo_pixs[3],
emif_wr_fifo_pixs[4], emif_wr_fifo_pixs[5], emif_wr_fifo_pixs[6], emif_wr_fifo_pixs[7]}),
.rdclk(emif_br_clk),
.rdreq(emif_wr_fifo_rdreq),
.rdempty(emif_wr_fifo_rdempty),
.rdusedw(emif_wr_fifo_rdusedw),
.wrclk(PCLK_CAP_i),
.wrreq(emif_wr_fifo_wrreq),
.wrfull(emif_wr_fifo_wrfull),
.q({emif_wr_fifo_blksleft_q, emif_wr_fifo_addr_q,
emif_wr_fifo_pixs_q[0], emif_wr_fifo_pixs_q[1], emif_wr_fifo_pixs_q[2], emif_wr_fifo_pixs_q[3],
emif_wr_fifo_pixs_q[4], emif_wr_fifo_pixs_q[5], emif_wr_fifo_pixs_q[6], emif_wr_fifo_pixs_q[7]})
);
always @(posedge PCLK_CAP_i) begin
emif_wr_fifo_wrreq <= 1'b0;
if (datavalid_i) begin
emif_wr_fifo_pixs[xpos_i[2:0]] <= {R_i, G_i, B_i};
DE_prev <= DE_i;
if (~DE_prev & DE_i)
blocks_inserted <= 0;
if ((blocks_inserted < blocks_per_line) & ~emif_wr_fifo_wrfull & (xpos_i[2:0] == 3'h7)) begin
emif_wr_fifo_blksleft <= blocks_per_line - blocks_inserted;
emif_wr_fifo_addr[19:9] <= ypos_i;
emif_wr_fifo_addr[7:0] <= xpos_i[10:3];
emif_wr_fifo_wrreq <= 1'b1;
blocks_inserted <= blocks_inserted + 1'b1;
end
end
end
always @(posedge emif_br_clk or posedge emif_br_reset) begin
if (emif_br_reset) begin
emif_wr_write <= 1'b0;
emif_wr_burstcount <= 1'b0;
end else begin
if (emif_wr_burstcount > 0) begin
if (!emif_wr_waitrequest) begin
emif_wr_burstcount <= emif_wr_burstcount - 1'b1;
if (emif_wr_burstcount == 1) begin
emif_wr_blksleft <= 0;
emif_wr_write <= 1'b0;
end
end
end else if (lb_enable & (emif_wr_blksleft > 0) & ((emif_wr_fifo_rdusedw >= emif_wr_blksleft-1) | (emif_wr_fifo_rdusedw >= 31))) begin
emif_wr_write <= 1'b1;
emif_wr_burstcount <= (emif_wr_blksleft > EMIF_WR_MAXBURST) ? EMIF_WR_MAXBURST : emif_wr_blksleft;
end else if (emif_wr_fifo_iniread_prev) begin
emif_wr_blksleft <= emif_wr_fifo_blksleft_q;
end
emif_wr_fifo_iniread_prev <= emif_wr_fifo_iniread;
end
end
/* ------------------------------ EMIF RD interface ------------------------------ */
// PCLK_OUT_i related signals
wire [12:0] linebuf_rdaddr = {xpos_lb + (line_id ? 2560 : 0)};
// emif_br_clk related signals
reg [8:0] blocks_copied;
wire linebuf_wren = emif_rd_readdatavalid;
wire [191:0] linebuf_wrdata = {emif_rd_rdata[23:0], emif_rd_rdata[55:32], emif_rd_rdata[87:64], emif_rd_rdata[119:96],
emif_rd_rdata[151:128], emif_rd_rdata[183:160], emif_rd_rdata[215:192], emif_rd_rdata[247:224]};
wire [9:0] linebuf_wraddr = {blocks_copied + (line_id ? 0 : 320)};
wire [19:0] emif_rd_block_addr = {ypos_lb_next, blocks_copied};
reg line_id_brclk_sync1_reg, line_id_brclk_sync2_reg, line_id_brclk_sync3_reg;
linebuf_double linebuf_rgb (
.data(linebuf_wrdata),
.rdaddress(linebuf_rdaddr),
.rdclock(PCLK_OUT_i),
.rdclocken(lb_enable),
.wraddress(linebuf_wraddr),
.wrclock(emif_br_clk),
.wren(linebuf_wren),
.wrclocken(lb_enable),
.q({R_linebuf, G_linebuf, B_linebuf})
);
// BRAM linebuffer operation
always @(posedge emif_br_clk or posedge emif_br_reset) begin
if (emif_br_reset) begin
emif_rd_read <= 1'b0;
emif_rd_burstcount <= 1'b0;
end else begin
if (emif_rd_burstcount > 0) begin // always finish read first, make sure doesn't last longer than line length
if (emif_rd_readdatavalid) begin
blocks_copied <= blocks_copied + 1'b1;
emif_rd_burstcount <= emif_rd_burstcount - 1'b1;
end
if (!emif_rd_waitrequest)
emif_rd_read <= 1'b0;
`ifdef DEBUG
emif_rd_line_missed <= (line_id_brclk_sync2_reg != line_id_brclk_sync3_reg);
`endif
end else if (line_id_brclk_sync2_reg != line_id_brclk_sync3_reg) begin
blocks_copied <= 0;
end else if (lb_enable & (blocks_copied < blocks_per_line)) begin
emif_rd_read <= 1'b1;
emif_rd_burstcount <= ((blocks_per_line-blocks_copied) > EMIF_RD_MAXBURST) ? EMIF_RD_MAXBURST : (blocks_per_line-blocks_copied);
emif_rd_addr <= {3'b001, emif_rd_block_addr, 5'h0};
end
line_id_brclk_sync1_reg <= line_id;
line_id_brclk_sync2_reg <= line_id_brclk_sync1_reg;
line_id_brclk_sync3_reg <= line_id_brclk_sync2_reg;
end
end
end else begin // EMIF_ENABLE
/* ------------------------------ BRAM lb interface ------------------------------ */
reg [5:0] ypos_wraddr;
reg [10:0] ypos_prev;
reg [10:0] xpos_wraddr;
reg [23:0] linebuf_wrdata;
reg linebuf_wren;
wire [16:0] linebuf_wraddr = {ypos_wraddr[($clog2(NUM_LINE_BUFFERS)-1):0], xpos_wraddr};
wire [16:0] linebuf_rdaddr = {ypos_lb[($clog2(NUM_LINE_BUFFERS)-1):0], xpos_lb[10:0]};
linebuf linebuf_rgb (
.data(linebuf_wrdata),
.rdaddress(linebuf_rdaddr),
.rdclock(PCLK_OUT_i),
.rdclocken(lb_enable),
.wraddress(linebuf_wraddr),
.wrclock(PCLK_CAP_i),
.wren(linebuf_wren),
.wrclocken(lb_enable),
.q({R_linebuf, G_linebuf, B_linebuf})
);
// Linebuffer write address calculation
always @(posedge PCLK_CAP_i) begin
if (ypos_i == 0) begin
ypos_wraddr <= 0;
end else if (ypos_i != ypos_prev) begin
if (ypos_wraddr == NUM_LINE_BUFFERS-1)
ypos_wraddr <= 0;
else
ypos_wraddr <= ypos_wraddr + 1'b1;
end
xpos_wraddr <= xpos_i;
ypos_prev <= ypos_i;
linebuf_wrdata <= {R_i, G_i, B_i};
linebuf_wren <= DE_i & datavalid_i;
end
end
endgenerate
endmodule

View File

@ -1,4 +1,5 @@
set_global_assignment -name IP_TOOL_NAME "LPM_MULT"
set_global_assignment -name IP_TOOL_VERSION "21.1"
set_global_assignment -name IP_TOOL_VERSION "20.1"
set_global_assignment -name IP_GENERATED_DEVICE_FAMILY "{Cyclone IV E}"
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "lpm_mult_hybr_ref.v"]
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "lpm_mult_4_hybr_ref.v"]
set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "lpm_mult_4_hybr_ref_bb.v"]

View File

@ -4,7 +4,7 @@
// MODULE: lpm_mult
// ============================================================
// File Name: lpm_mult_hybr_ref.v
// File Name: lpm_mult_4_hybr_ref.v
// Megafunction Name(s):
// lpm_mult
//
@ -14,11 +14,11 @@
// ************************************************************
// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
//
// 21.1.0 Build 842 10/21/2021 SJ Lite Edition
// 20.1.1 Build 720 11/11/2020 SJ Lite Edition
// ************************************************************
//Copyright (C) 2021 Intel Corporation. All rights reserved.
//Copyright (C) 2020 Intel Corporation. All rights reserved.
//Your use of Intel Corporation's design tools, logic functions
//and other software and tools, and any partner logic
//functions, and any output files from any of the foregoing
@ -37,7 +37,7 @@
// synopsys translate_off
`timescale 1 ps / 1 ps
// synopsys translate_on
module lpm_mult_hybr_ref (
module lpm_mult_4_hybr_ref (
clock,
dataa,
datab,
@ -108,10 +108,10 @@ endmodule
// Retrieval info: CONNECT: @dataa 0 0 9 0 dataa 0 0 9 0
// Retrieval info: CONNECT: @datab 0 0 8 0 datab 0 0 8 0
// Retrieval info: CONNECT: result 0 0 9 0 @result 0 0 9 0
// Retrieval info: GEN_FILE: TYPE_NORMAL lpm_mult_hybr_ref.v TRUE
// Retrieval info: GEN_FILE: TYPE_NORMAL lpm_mult_hybr_ref.inc FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL lpm_mult_hybr_ref.cmp FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL lpm_mult_hybr_ref.bsf FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL lpm_mult_hybr_ref_inst.v FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL lpm_mult_hybr_ref_bb.v FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL lpm_mult_4_hybr_ref.v TRUE
// Retrieval info: GEN_FILE: TYPE_NORMAL lpm_mult_4_hybr_ref.inc FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL lpm_mult_4_hybr_ref.cmp FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL lpm_mult_4_hybr_ref.bsf FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL lpm_mult_4_hybr_ref_inst.v FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL lpm_mult_4_hybr_ref_bb.v TRUE
// Retrieval info: LIB_FILE: lpm

View File

@ -0,0 +1,5 @@
set_global_assignment -name IP_TOOL_NAME "LPM_MULT"
set_global_assignment -name IP_TOOL_VERSION "20.1"
set_global_assignment -name IP_GENERATED_DEVICE_FAMILY "{Cyclone IV E}"
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "lpm_mult_4_hybr_ref_pre.v"]
set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "lpm_mult_4_hybr_ref_pre_bb.v"]

View File

@ -4,7 +4,7 @@
// MODULE: lpm_mult
// ============================================================
// File Name: lpm_mult_hybr_ref_pre.v
// File Name: lpm_mult_4_hybr_ref_pre.v
// Megafunction Name(s):
// lpm_mult
//
@ -14,11 +14,11 @@
// ************************************************************
// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
//
// 21.1.0 Build 842 10/21/2021 SJ Lite Edition
// 20.1.1 Build 720 11/11/2020 SJ Lite Edition
// ************************************************************
//Copyright (C) 2021 Intel Corporation. All rights reserved.
//Copyright (C) 2020 Intel Corporation. All rights reserved.
//Your use of Intel Corporation's design tools, logic functions
//and other software and tools, and any partner logic
//functions, and any output files from any of the foregoing
@ -37,7 +37,7 @@
// synopsys translate_off
`timescale 1 ps / 1 ps
// synopsys translate_on
module lpm_mult_hybr_ref_pre (
module lpm_mult_4_hybr_ref_pre (
clock,
dataa,
datab,
@ -108,10 +108,10 @@ endmodule
// Retrieval info: CONNECT: @dataa 0 0 8 0 dataa 0 0 8 0
// Retrieval info: CONNECT: @datab 0 0 5 0 datab 0 0 5 0
// Retrieval info: CONNECT: result 0 0 9 0 @result 0 0 9 0
// Retrieval info: GEN_FILE: TYPE_NORMAL lpm_mult_hybr_ref_pre.v TRUE
// Retrieval info: GEN_FILE: TYPE_NORMAL lpm_mult_hybr_ref_pre.inc FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL lpm_mult_hybr_ref_pre.cmp FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL lpm_mult_hybr_ref_pre.bsf FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL lpm_mult_hybr_ref_pre_inst.v FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL lpm_mult_hybr_ref_pre_bb.v FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL lpm_mult_4_hybr_ref_pre.v TRUE
// Retrieval info: GEN_FILE: TYPE_NORMAL lpm_mult_4_hybr_ref_pre.inc FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL lpm_mult_4_hybr_ref_pre.cmp FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL lpm_mult_4_hybr_ref_pre.bsf FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL lpm_mult_4_hybr_ref_pre_inst.v FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL lpm_mult_4_hybr_ref_pre_bb.v TRUE
// Retrieval info: LIB_FILE: lpm

View File

@ -1,4 +1,5 @@
set_global_assignment -name IP_TOOL_NAME "LPM_MULT"
set_global_assignment -name IP_TOOL_VERSION "21.1"
set_global_assignment -name IP_TOOL_VERSION "20.1"
set_global_assignment -name IP_GENERATED_DEVICE_FAMILY "{Cyclone IV E}"
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "lpm_mult_sl.v"]
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "lpm_mult_4_sl.v"]
set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "lpm_mult_4_sl_bb.v"]

View File

@ -4,7 +4,7 @@
// MODULE: lpm_mult
// ============================================================
// File Name: lpm_mult_sl.v
// File Name: lpm_mult_4_sl.v
// Megafunction Name(s):
// lpm_mult
//
@ -14,11 +14,11 @@
// ************************************************************
// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
//
// 21.1.0 Build 842 10/21/2021 SJ Lite Edition
// 20.1.1 Build 720 11/11/2020 SJ Lite Edition
// ************************************************************
//Copyright (C) 2021 Intel Corporation. All rights reserved.
//Copyright (C) 2020 Intel Corporation. All rights reserved.
//Your use of Intel Corporation's design tools, logic functions
//and other software and tools, and any partner logic
//functions, and any output files from any of the foregoing
@ -37,7 +37,7 @@
// synopsys translate_off
`timescale 1 ps / 1 ps
// synopsys translate_on
module lpm_mult_sl (
module lpm_mult_4_sl (
clock,
dataa,
datab,
@ -108,10 +108,10 @@ endmodule
// Retrieval info: CONNECT: @dataa 0 0 8 0 dataa 0 0 8 0
// Retrieval info: CONNECT: @datab 0 0 8 0 datab 0 0 8 0
// Retrieval info: CONNECT: result 0 0 8 0 @result 0 0 8 0
// Retrieval info: GEN_FILE: TYPE_NORMAL lpm_mult_sl.v TRUE
// Retrieval info: GEN_FILE: TYPE_NORMAL lpm_mult_sl.inc FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL lpm_mult_sl.cmp FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL lpm_mult_sl.bsf FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL lpm_mult_sl_inst.v FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL lpm_mult_sl_bb.v FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL lpm_mult_4_sl.v TRUE
// Retrieval info: GEN_FILE: TYPE_NORMAL lpm_mult_4_sl.inc FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL lpm_mult_4_sl.cmp FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL lpm_mult_4_sl.bsf FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL lpm_mult_4_sl_inst.v FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL lpm_mult_4_sl_bb.v TRUE
// Retrieval info: LIB_FILE: lpm

View File

@ -1,4 +0,0 @@
set_global_assignment -name IP_TOOL_NAME "LPM_MULT"
set_global_assignment -name IP_TOOL_VERSION "21.1"
set_global_assignment -name IP_GENERATED_DEVICE_FAMILY "{Cyclone IV E}"
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "lpm_mult_hybr_ref_pre.v"]

View File

@ -22,22 +22,17 @@
module ossc (
input clk27,
input ir_rx,
inout scl,
inout sda,
input ir_rx,
input [1:0] btn,
input [1:0] cfg,
input TVP_PCLK_i,
input [7:0] TVP_R_i,
input [7:0] TVP_G_i,
input [7:0] TVP_B_i,
input TVP_HS_i,
input TVP_SOG_i,
input TVP_VSYNC_i,
input [7:0] R_in,
input [7:0] G_in,
input [7:0] B_in,
input FID_in,
input VSYNC_in,
input HSYNC_in,
input PCLK_in,
output HDMI_TX_PCLK,
output reg [7:0] HDMI_TX_RD,
output reg [7:0] HDMI_TX_GD,
@ -46,51 +41,40 @@ module ossc (
output reg HDMI_TX_HS,
output reg HDMI_TX_VS,
input HDMI_TX_INT_N,
input HDMI_TX_MODE,
output hw_reset_n,
output LED_G,
inout LED_R,
output LED_R,
output LCD_RS,
output LCD_CS_N,
output LCD_BL,
output SD_CLK,
inout SD_CMD,
inout [3:0] SD_DAT
);
wire [31:0] sys_ctrl;
wire lt_active = sys_ctrl[15];
wire lt_armed = sys_ctrl[14];
wire [1:0] lt_mode = sys_ctrl[13:12];
wire tvp_vsync_type = sys_ctrl[10];
wire pll_bypass = sys_ctrl[9];
wire remote_event = sys_ctrl[8];
assign SD_DAT[3] = sys_ctrl[7]; //SD_SPI_SS_N
assign LCD_CS_N = sys_ctrl[6];
assign LCD_RS = sys_ctrl[5];
wire lcd_bl_on = sys_ctrl[4]; //hw_reset_n in v1.2 PCB
wire [1:0] lcd_bl_time = sys_ctrl[3:2];
wire enable_sc = sys_ctrl[1];
assign hw_reset_n = sys_ctrl[0]; //HDMI_TX_RST_N in v1.2 PCB
wire [31:0] hv_in_config, hv_in_config2, hv_in_config3, hv_out_config, hv_out_config2, hv_out_config3, xy_out_config, xy_out_config2;
wire [31:0] misc_config, sl_config, sl_config2, sl_config3;
wire pll_clkout, pll_clkswitch, pll_locked;
wire clkmux_clkout;
wire [15:0] sys_ctrl;
wire h_unstable, pll_lock_lost;
wire [31:0] h_config, h_config2, v_config, misc_config, sl_config, sl_config2;
wire [10:0] vmax, vmax_tvp;
wire [1:0] fpga_vsyncgen;
wire ilace_flag, vsync_flag;
wire [19:0] pcnt_frame;
wire [15:0] ir_code;
wire [7:0] ir_code_cnt;
wire [7:0] R_sc, G_sc, B_sc;
wire HSYNC_sc, VSYNC_sc, DE_sc;
wire pll_areset, pll_scanclk, pll_scanclkena, pll_configupdate, pll_scandata, pll_scandone, pll_activeclock;
wire PCLK_sc;
wire pclk_out = PCLK_sc;
wire [7:0] R_out_sc, G_out_sc, B_out_sc;
wire HSYNC_out_sc;
wire VSYNC_out_sc;
wire PCLK_out;
wire DE_out_sc;
wire [7:0] R_out_vg, G_out_vg, B_out_vg;
wire HSYNC_out_vg;
wire VSYNC_out_vg;
wire DE_out_vg;
reg [7:0] po_reset_ctr = 0;
@ -98,36 +82,24 @@ reg po_reset_n = 1'b0;
wire jtagm_reset_req;
wire sys_reset_n = (po_reset_n & ~jtagm_reset_req);
reg [7:0] TVP_R, TVP_G, TVP_B;
reg TVP_HS, TVP_VS, TVP_FID;
reg TVP_VS_sync1_reg, TVP_VS_sync2_reg;
reg TVP_SOG_sync1_reg, TVP_SOG_sync2_reg, TVP_SOG_prev;
reg TVP_HSYNC_sync1_reg, TVP_HSYNC_sync2_reg;
reg TVP_VSYNC_sync1_reg, TVP_VSYNC_sync2_reg;
reg [7:0] R_in_L, G_in_L, B_in_L;
reg HSYNC_in_L, VSYNC_in_L, FID_in_L;
reg [1:0] btn_L, btn_LL;
reg ir_rx_L, ir_rx_LL, HDMI_TX_INT_N_L, HDMI_TX_INT_N_LL;
reg vsync_flag_sync1_reg, vsync_flag_sync2_reg;
reg [1:0] cfg_reg;
reg cfg_stored;
wire TVP_SOG_ALT_i;
wire TVP_HSYNC_i = cfg_reg[1] ? TVP_SOG_i : TVP_SOG_ALT_i;
reg [23:0] resync_led_ctr, warn_pll_lock_lost;
reg resync_strobe_sync1_reg, resync_strobe_sync2_reg, resync_strobe_prev;
wire resync_strobe_i;
wire resync_strobe = resync_strobe_sync2_reg;
wire [31:0] controls = {ir_code_cnt, 3'b000, vsync_flag_sync2_reg, pll_activeclock, cfg_reg[0], btn_LL, ir_code};
reg ir_rx_L, ir_rx_LL, HDMI_TX_INT_N_L, HDMI_TX_INT_N_LL, HDMI_TX_MODE_L, HDMI_TX_MODE_LL;
wire lt_sensor = btn_LL[1];
wire lt_trigger = DE_sc & G_sc[0];
wire lt_active = sys_ctrl[15];
wire lt_armed = sys_ctrl[14];
wire lt_trigger = HDMI_TX_DE & HDMI_TX_GD[0];
wire [1:0] lt_mode = sys_ctrl[13:12];
wire [1:0] lt_mode_synced;
wire [15:0] lt_lat_result;
wire [11:0] lt_stb_result;
wire lt_trig_waiting;
wire lt_finished;
wire remote_event = sys_ctrl[8];
reg remove_event_prev;
reg [14:0] to_ctr, to_ctr_ms;
wire lcd_bl_timeout;
@ -135,99 +107,53 @@ wire lcd_bl_timeout;
wire [1:0] osd_color;
wire osd_enable_pre;
wire osd_enable = osd_enable_pre & ~lt_active;
wire [10:0] xpos_sc;
wire [10:0] ypos_sc;
wire [10:0] xpos, xpos_sc, xpos_vg;
wire [10:0] ypos, ypos_sc, ypos_vg;
wire resync_indicator = (warn_pll_lock_lost != 0) | (resync_led_ctr != 0);
wire LED_R_i = lt_active ? lt_trig_waiting : resync_indicator;
assign LED_G = lt_active ? ~lt_sensor : (ir_code == 0) & (~resync_indicator | cfg_reg[1]);
assign LCD_BL = lcd_bl_on ? (~lcd_bl_timeout | lt_active) : 1'b0;
assign HDMI_TX_PCLK = pclk_out;
wire pll_areset, pll_scanclk, pll_scanclkena, pll_configupdate, pll_scandata, pll_scandone, pll_activeclock;
// TVP7002 RGB digitizer
always @(posedge TVP_PCLK_i) begin
TVP_R <= TVP_R_i;
TVP_G <= TVP_G_i;
TVP_B <= TVP_B_i;
TVP_HS <= TVP_HS_i;
TVP_VS <= TVP_VSYNC_i;
// sync to pclk
TVP_SOG_sync1_reg <= TVP_HSYNC_i;
TVP_SOG_sync2_reg <= TVP_SOG_sync1_reg;
TVP_SOG_prev <= TVP_SOG_sync2_reg;
TVP_VS_sync1_reg <= TVP_VSYNC_i;
TVP_VS_sync2_reg <= TVP_VS_sync1_reg;
// Latch inputs from TVP7002 (synchronized to PCLK_in)
always @(posedge PCLK_in or negedge hw_reset_n)
begin
if (!hw_reset_n) begin
R_in_L <= 8'h00;
G_in_L <= 8'h00;
B_in_L <= 8'h00;
HSYNC_in_L <= 1'b0;
VSYNC_in_L <= 1'b0;
FID_in_L <= 1'b0;
end else begin
R_in_L <= R_in;
G_in_L <= G_in;
B_in_L <= B_in;
HSYNC_in_L <= HSYNC_in;
VSYNC_in_L <= VSYNC_in;
FID_in_L <= FID_in;
end
end
always @(posedge clk27) begin
// sync to always-running fixed meas clk
TVP_HSYNC_sync1_reg <= TVP_HSYNC_i;
TVP_HSYNC_sync2_reg <= TVP_HSYNC_sync1_reg;
TVP_VSYNC_sync1_reg <= TVP_VSYNC_i;
TVP_VSYNC_sync2_reg <= TVP_VSYNC_sync1_reg;
end
wire [7:0] TVP_R_post, TVP_G_post, TVP_B_post;
wire TVP_HSYNC_post, TVP_VSYNC_post, TVP_DE_post, TVP_FID_post, TVP_datavalid_post;
wire TVP_fe_interlace, TVP_fe_frame_change, TVP_sof_scaler, TVP_sync_active;
wire [19:0] TVP_fe_pcnt_frame;
wire [7:0] TVP_hsync_width;
wire [10:0] TVP_fe_vtotal, TVP_fe_xpos, TVP_fe_ypos;
tvp7002_frontend u_tvp_frontend (
.PCLK_i(TVP_PCLK_i),
.CLK_MEAS_i(clk27),
.reset_n(sys_reset_n),
.R_i(TVP_R),
.G_i(TVP_G),
.B_i(TVP_B),
.HS_i(TVP_HS),
.VS_i(TVP_VS_sync2_reg),
.HSYNC_i(TVP_HSYNC_sync2_reg),
.VSYNC_i(TVP_VSYNC_sync2_reg),
.DE_i(1'b0),
.FID_i(1'b0),
.sogref_update_i(TVP_SOG_prev & ~TVP_SOG_sync2_reg),
.vsync_i_type(tvp_vsync_type),
.hv_in_config(hv_in_config),
.hv_in_config2(hv_in_config2),
.hv_in_config3(hv_in_config3),
.misc_config(misc_config),
.R_o(TVP_R_post),
.G_o(TVP_G_post),
.B_o(TVP_B_post),
.HSYNC_o(TVP_HSYNC_post),
.VSYNC_o(TVP_VSYNC_post),
.DE_o(TVP_DE_post),
.FID_o(TVP_FID_post),
.interlace_flag(TVP_fe_interlace),
.datavalid_o(TVP_datavalid_post),
.xpos_o(TVP_fe_xpos),
.ypos_o(TVP_fe_ypos),
.vtotal(TVP_fe_vtotal),
.frame_change(TVP_fe_frame_change),
.sof_scaler(TVP_sof_scaler),
.pcnt_frame(TVP_fe_pcnt_frame),
.hsync_width(TVP_hsync_width),
.sync_active(TVP_sync_active)
);
// Insert synchronizers to async inputs (synchronize to CPU clock)
always @(posedge clk27 or negedge po_reset_n)
begin
if (!po_reset_n) begin
{btn_L, btn_LL} <= '0;
{ir_rx_L, ir_rx_LL} <= '0;
{HDMI_TX_INT_N_L, HDMI_TX_INT_N_LL} <= '0;
{cfg_stored, cfg_reg} <= '0;
btn_L <= 2'b00;
btn_LL <= 2'b00;
ir_rx_L <= 1'b0;
ir_rx_LL <= 1'b0;
HDMI_TX_INT_N_L <= 1'b0;
HDMI_TX_INT_N_LL <= 1'b0;
HDMI_TX_MODE_L <= 1'b0;
HDMI_TX_MODE_LL <= 1'b0;
end else begin
{btn_L, btn_LL} <= {btn, btn_L};
{ir_rx_L, ir_rx_LL} <= {ir_rx, ir_rx_L};
{HDMI_TX_INT_N_L, HDMI_TX_INT_N_LL} <= {HDMI_TX_INT_N, HDMI_TX_INT_N_L};
if (!cfg_stored)
cfg_reg <= cfg;
cfg_stored <= 1'b1;
btn_L <= btn;
btn_LL <= btn_L;
ir_rx_L <= ir_rx;
ir_rx_LL <= ir_rx_L;
HDMI_TX_INT_N_L <= HDMI_TX_INT_N;
HDMI_TX_INT_N_LL <= HDMI_TX_INT_N_L;
HDMI_TX_MODE_L <= HDMI_TX_MODE;
HDMI_TX_MODE_LL <= HDMI_TX_MODE_L;
end
end
@ -240,9 +166,49 @@ begin
po_reset_ctr <= po_reset_ctr + 1'b1;
end
// Sync vsync flag to CPU clock
always @(posedge clk27) begin
{vsync_flag_sync1_reg, vsync_flag_sync2_reg} <= {~VSYNC_sc, vsync_flag_sync1_reg};
assign hw_reset_n = sys_ctrl[0]; //HDMI_TX_RST_N in v1.2 PCB
`ifdef DEBUG
assign LED_R = HSYNC_in_L;
assign LED_G = VSYNC_in_L;
`else
assign LED_R = lt_active ? lt_trig_waiting : (pll_lock_lost|h_unstable);
assign LED_G = lt_active ? ~lt_sensor : (ir_code == 0);
`endif
assign SD_DAT[3] = sys_ctrl[7]; //SD_SPI_SS_N
assign LCD_CS_N = sys_ctrl[6];
assign LCD_RS = sys_ctrl[5];
wire lcd_bl_on = sys_ctrl[4]; //hw_reset_n in v1.2 PCB
wire [1:0] lcd_bl_time = sys_ctrl[3:2];
assign LCD_BL = lcd_bl_on ? (~lcd_bl_timeout | lt_active) : 1'b0;
wire enable_sc = sys_ctrl[1];
assign xpos = enable_sc ? xpos_sc : xpos_vg;
assign ypos = enable_sc ? ypos_sc : ypos_vg;
assign HDMI_TX_PCLK = PCLK_out;
always @(posedge PCLK_out) begin
if (osd_enable) begin
if (osd_color == 2'h0) begin
{HDMI_TX_RD, HDMI_TX_GD, HDMI_TX_BD} <= 24'h000000;
end else if (osd_color == 2'h1) begin
{HDMI_TX_RD, HDMI_TX_GD, HDMI_TX_BD} <= 24'h0000ff;
end else if (osd_color == 2'h2) begin
{HDMI_TX_RD, HDMI_TX_GD, HDMI_TX_BD} <= 24'hffff00;
end else begin
{HDMI_TX_RD, HDMI_TX_GD, HDMI_TX_BD} <= 24'hffffff;
end
end else if (enable_sc) begin
{HDMI_TX_RD, HDMI_TX_GD, HDMI_TX_BD} <= {R_out_sc, G_out_sc, B_out_sc};
end else begin
{HDMI_TX_RD, HDMI_TX_GD, HDMI_TX_BD} <= {R_out_vg, G_out_vg, B_out_vg};
end
HDMI_TX_HS <= enable_sc ? HSYNC_out_sc : HSYNC_out_vg;
HDMI_TX_VS <= enable_sc ? VSYNC_out_sc : VSYNC_out_vg;
HDMI_TX_DE <= enable_sc ? DE_out_sc : DE_out_vg;
end
// LCD backlight timeout counters
@ -271,96 +237,6 @@ begin
remove_event_prev <= remote_event;
end
// Generate a warning signal from sync lock loss
always @(posedge clk27) begin
if (enable_sc) begin
if (~resync_strobe_prev & resync_strobe) begin
resync_led_ctr <= {24{1'b1}};
end else if (resync_led_ctr > 0) begin
resync_led_ctr <= resync_led_ctr - 1'b1;
end
end
resync_strobe_sync1_reg <= resync_strobe_i;
resync_strobe_sync2_reg <= resync_strobe_sync1_reg;
resync_strobe_prev <= resync_strobe_sync2_reg;
end
// Generate a warning signal from PLL lock loss
always @(posedge clk27 or negedge sys_reset_n)
begin
if (!sys_reset_n) begin
warn_pll_lock_lost <= 1'b0;
end else begin
if (~pll_areset & ~pll_locked)
warn_pll_lock_lost <= 1;
else if (warn_pll_lock_lost != 0)
warn_pll_lock_lost <= warn_pll_lock_lost + 1'b1;
end
end
// Control PLL reference clock switchover
always @(posedge clk27)
begin
pll_clkswitch <= (pll_activeclock != enable_sc);
end
// Output registers
always @(posedge pclk_out) begin
if (osd_enable) begin
if (osd_color == 2'h0) begin
{HDMI_TX_RD, HDMI_TX_GD, HDMI_TX_BD} <= 24'h000000;
end else if (osd_color == 2'h1) begin
{HDMI_TX_RD, HDMI_TX_GD, HDMI_TX_BD} <= 24'h0000ff;
end else if (osd_color == 2'h2) begin
{HDMI_TX_RD, HDMI_TX_GD, HDMI_TX_BD} <= 24'hffff00;
end else begin
{HDMI_TX_RD, HDMI_TX_GD, HDMI_TX_BD} <= 24'hffffff;
end
end else begin
{HDMI_TX_RD, HDMI_TX_GD, HDMI_TX_BD} <= {R_sc, G_sc, B_sc};
end
HDMI_TX_HS <= HSYNC_sc;
HDMI_TX_VS <= VSYNC_sc;
HDMI_TX_DE <= DE_sc;
end
// A modified <= v1.7 board uses LED_R for TVP_HSYNC input
ALT_IOBUF led_r_iobuf (.i(LED_R_i), .oe(cfg_reg[1]), .o(TVP_SOG_ALT_i), .io(LED_R));
pll_2x pll_pclk (
.areset(pll_areset),
.clkswitch(pll_clkswitch),
.configupdate(pll_configupdate),
.inclk0(clk27), // set videogen clock to primary (power-on default) since both reference clocks must be running during switchover
.inclk1(TVP_PCLK_i), // is the secondary input clock fully compensated?
.scanclk(pll_scanclk),
.scanclkena(pll_scanclkena),
.scandata(pll_scandata),
.activeclock(pll_activeclock),
.c0(pll_clkout),
.locked(pll_locked),
.scandataout(),
.scandone(pll_scandone)
);
cycloneive_clkctrl clkctrl1 (
.clkselect(pll_bypass ? 2'h0 : 2'h2),
.ena(1'b1),
.inclk({1'b0, pll_clkout, 1'b0, TVP_PCLK_i}), // fitter forbids using both clk27 and pclk_1x here since they're on opposite sides
.outclk(clkmux_clkout)
// synopsys translate_off
,
.devclrn(1'b1),
.devpor(1'b1)
// synopsys translate_on
);
defparam
clkctrl1.clock_type = "Global Clock",
clkctrl1.ena_register_mode = "falling edge",
clkctrl1.lpm_type = "cycloneive_clkctrl";
sys sys_inst(
.clk_clk (clk27),
@ -377,25 +253,19 @@ sys sys_inst(
.i2c_opencores_1_export_sda_pad_io (SD_CMD),
.i2c_opencores_1_export_spi_miso_pad_i (SD_DAT[0]),
.pio_0_sys_ctrl_out_export (sys_ctrl),
.pio_1_controls_in_export (controls),
.sc_config_0_sc_if_fe_status_i ({19'h0, TVP_sync_active, TVP_fe_interlace, TVP_fe_vtotal}),
.sc_config_0_sc_if_fe_status2_i ({4'h0, TVP_hsync_width, TVP_fe_pcnt_frame}),
.sc_config_0_sc_if_lt_status_i (32'h00000000),
.sc_config_0_sc_if_hv_in_config_o (hv_in_config),
.sc_config_0_sc_if_hv_in_config2_o (hv_in_config2),
.sc_config_0_sc_if_hv_in_config3_o (hv_in_config3),
.sc_config_0_sc_if_hv_out_config_o (hv_out_config),
.sc_config_0_sc_if_hv_out_config2_o (hv_out_config2),
.sc_config_0_sc_if_hv_out_config3_o (hv_out_config3),
.sc_config_0_sc_if_xy_out_config_o (xy_out_config),
.sc_config_0_sc_if_xy_out_config2_o (xy_out_config2),
.pio_1_controls_in_export ({ir_code_cnt, 4'b0000, pll_activeclock, HDMI_TX_MODE_LL, btn_LL, ir_code}),
.sc_config_0_sc_if_sc_status_i ({vsync_flag, 2'b00, vmax_tvp, fpga_vsyncgen, 4'h0, ilace_flag, vmax}),
.sc_config_0_sc_if_sc_status2_i ({12'h000, pcnt_frame}),
.sc_config_0_sc_if_lt_status_i ({lt_finished, 3'h0, lt_stb_result, lt_lat_result}),
.sc_config_0_sc_if_h_config_o (h_config),
.sc_config_0_sc_if_h_config2_o (h_config2),
.sc_config_0_sc_if_v_config_o (v_config),
.sc_config_0_sc_if_misc_config_o (misc_config),
.sc_config_0_sc_if_sl_config_o (sl_config),
.sc_config_0_sc_if_sl_config2_o (sl_config2),
.sc_config_0_sc_if_sl_config3_o (sl_config3),
.osd_generator_0_osd_if_vclk (PCLK_sc),
.osd_generator_0_osd_if_xpos (xpos_sc),
.osd_generator_0_osd_if_ypos (ypos_sc),
.osd_generator_0_osd_if_vclk (PCLK_out),
.osd_generator_0_osd_if_xpos (xpos),
.osd_generator_0_osd_if_ypos (ypos),
.osd_generator_0_osd_if_osd_enable (osd_enable_pre),
.osd_generator_0_osd_if_osd_color (osd_color),
.pll_reconfig_0_pll_reconfig_if_areset (pll_areset),
@ -406,65 +276,49 @@ sys sys_inst(
.pll_reconfig_0_pll_reconfig_if_scandone (pll_scandone)
);
scanconverter #(
.EMIF_ENABLE(0),
.NUM_LINE_BUFFERS(2)
) scanconverter_inst (
.PCLK_CAP_i(TVP_PCLK_i),
.PCLK_OUT_i(clkmux_clkout),
.reset_n(hw_reset_n), //TODO: sync to pclk_capture
.R_i(TVP_R_post),
.G_i(TVP_G_post),
.B_i(TVP_B_post),
.HSYNC_i(TVP_HSYNC_post),
.VSYNC_i(TVP_VSYNC_post),
.DE_i(TVP_DE_post),
.FID_i(TVP_FID_post),
.datavalid_i(TVP_datavalid_post),
.interlaced_in_i(TVP_fe_interlace),
.frame_change_i(TVP_fe_frame_change),
.xpos_i(TVP_fe_xpos),
.ypos_i(TVP_fe_ypos),
.h_in_active(hv_in_config[23:12]),
.hv_out_config(hv_out_config),
.hv_out_config2(hv_out_config2),
.hv_out_config3(hv_out_config3),
.xy_out_config(xy_out_config),
.xy_out_config2(xy_out_config2),
.misc_config(misc_config),
.sl_config(sl_config),
.sl_config2(sl_config2),
.sl_config3(sl_config3),
.testpattern_enable(~enable_sc),
.lb_enable(enable_sc),
.ext_sync_mode(1'b0),
.ext_frame_change_i(1'b0),
.ext_R_i(8'h00),
.ext_G_i(8'h00),
.ext_B_i(8'h00),
.PCLK_o(PCLK_sc),
.R_o(R_sc),
.G_o(G_sc),
.B_o(B_sc),
.HSYNC_o(HSYNC_sc),
.VSYNC_o(VSYNC_sc),
.DE_o(DE_sc),
.xpos_o(xpos_sc),
.ypos_o(ypos_sc),
.resync_strobe(resync_strobe_i),
.emif_br_clk(1'b0),
.emif_br_reset(1'b0),
.emif_rd_addr(),
.emif_rd_read(),
.emif_rd_rdata(0),
.emif_rd_waitrequest(0),
.emif_rd_readdatavalid(0),
.emif_rd_burstcount(),
.emif_wr_addr(),
.emif_wr_write(),
.emif_wr_wdata(),
.emif_wr_waitrequest(0),
.emif_wr_burstcount()
scanconverter scanconverter_inst (
.reset_n (hw_reset_n),
.PCLK_in (PCLK_in),
.clk27 (clk27),
.enable_sc (enable_sc),
.HSYNC_in (HSYNC_in_L),
.VSYNC_in (VSYNC_in_L),
.FID_in (FID_in_L),
.R_in (R_in_L),
.G_in (G_in_L),
.B_in (B_in_L),
.h_config (h_config),
.h_config2 (h_config2),
.v_config (v_config),
.misc_config (misc_config),
.sl_config (sl_config),
.sl_config2 (sl_config2),
.R_out (R_out_sc),
.G_out (G_out_sc),
.B_out (B_out_sc),
.PCLK_out (PCLK_out),
.HSYNC_out (HSYNC_out_sc),
.VSYNC_out (VSYNC_out_sc),
.DE_out (DE_out_sc),
.h_unstable (h_unstable),
.fpga_vsyncgen (fpga_vsyncgen),
.pll_lock_lost (pll_lock_lost),
.vmax (vmax),
.vmax_tvp (vmax_tvp),
.pcnt_frame (pcnt_frame),
.ilace_flag (ilace_flag),
.vsync_flag (vsync_flag),
.lt_active (lt_active),
.lt_mode (lt_mode_synced),
.xpos (xpos_sc),
.ypos (ypos_sc),
.pll_areset (pll_areset),
.pll_scanclk (pll_scanclk),
.pll_scanclkena (pll_scanclkena),
.pll_configupdate (pll_configupdate),
.pll_scandata (pll_scandata),
.pll_scandone (pll_scandone),
.pll_activeclock (pll_activeclock)
);
ir_rcv ir0 (
@ -478,12 +332,12 @@ ir_rcv ir0 (
lat_tester lt0 (
.clk27 (clk27),
.pclk (PCLK_sc),
.pclk (PCLK_out),
.active (lt_active),
.armed (lt_armed),
.sensor (lt_sensor),
.trigger (lt_trigger),
.VSYNC_in (VSYNC_sc),
.VSYNC_in (HDMI_TX_VS),
.mode_in (lt_mode),
.mode_synced (lt_mode_synced),
.lat_result (lt_lat_result),
@ -492,8 +346,8 @@ lat_tester lt0 (
.finished (lt_finished)
);
/*Ävideogen vg0 (
.clk27 (PCLK_sc),
videogen vg0 (
.clk27 (PCLK_out),
.reset_n (po_reset_n & ~enable_sc),
.lt_active (lt_active),
.lt_mode (lt_mode_synced),
@ -505,6 +359,6 @@ lat_tester lt0 (
.DE_out (DE_out_vg),
.xpos (xpos_vg),
.ypos (ypos_vg)
);*/
);
endmodule

View File

@ -12,6 +12,7 @@
<pin name="scandata" direction="input" scope="external" />
<pin name="activeclock" direction="output" scope="external" />
<pin name="c0" direction="output" scope="external" source="clock" />
<pin name="c1" direction="output" scope="external" source="clock" />
<pin name="locked" direction="output" scope="external" />
<pin name="scandataout" direction="output" scope="external" />
<pin name="scandone" direction="output" scope="external" />

View File

@ -1,5 +1,7 @@
set_global_assignment -name IP_TOOL_NAME "ALTPLL"
set_global_assignment -name IP_TOOL_VERSION "21.1"
set_global_assignment -name IP_TOOL_VERSION "20.1"
set_global_assignment -name IP_GENERATED_DEVICE_FAMILY "{Cyclone IV E}"
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "pll_2x.v"]
set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "pll_2x_inst.v"]
set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "pll_2x_bb.v"]
set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "pll_2x.ppf"]

View File

@ -14,11 +14,11 @@
// ************************************************************
// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
//
// 21.1.0 Build 842 10/21/2021 SJ Lite Edition
// 20.1.1 Build 720 11/11/2020 SJ Lite Edition
// ************************************************************
//Copyright (C) 2021 Intel Corporation. All rights reserved.
//Copyright (C) 2020 Intel Corporation. All rights reserved.
//Your use of Intel Corporation's design tools, logic functions
//and other software and tools, and any partner logic
//functions, and any output files from any of the foregoing
@ -48,6 +48,7 @@ module pll_2x (
scandata,
activeclock,
c0,
c1,
locked,
scandataout,
scandone);
@ -62,6 +63,7 @@ module pll_2x (
input scandata;
output activeclock;
output c0;
output c1;
output locked;
output scandataout;
output scandone;
@ -79,32 +81,34 @@ module pll_2x (
wire sub_wire0;
wire [4:0] sub_wire1;
wire sub_wire3;
wire sub_wire4;
wire sub_wire5;
wire sub_wire8 = inclk1;
wire sub_wire6;
wire sub_wire9 = inclk1;
wire activeclock = sub_wire0;
wire [1:1] sub_wire3 = sub_wire1[1:1];
wire [0:0] sub_wire2 = sub_wire1[0:0];
wire c0 = sub_wire2;
wire locked = sub_wire3;
wire scandataout = sub_wire4;
wire scandone = sub_wire5;
wire sub_wire6 = inclk0;
wire [1:0] sub_wire7 = {sub_wire8, sub_wire6};
wire c1 = sub_wire3;
wire locked = sub_wire4;
wire scandataout = sub_wire5;
wire scandone = sub_wire6;
wire sub_wire7 = inclk0;
wire [1:0] sub_wire8 = {sub_wire9, sub_wire7};
altpll altpll_component (
.areset (areset),
.clkswitch (clkswitch),
.configupdate (configupdate),
.inclk (sub_wire7),
.inclk (sub_wire8),
.scanclk (scanclk),
.scanclkena (scanclkena),
.scandata (scandata),
.activeclock (sub_wire0),
.clk (sub_wire1),
.locked (sub_wire3),
.scandataout (sub_wire4),
.scandone (sub_wire5),
.locked (sub_wire4),
.scandataout (sub_wire5),
.scandone (sub_wire6),
.clkbad (),
.clkena ({6{1'b1}}),
.clkloss (),
@ -136,6 +140,10 @@ module pll_2x (
altpll_component.clk0_duty_cycle = 50,
altpll_component.clk0_multiply_by = 1,
altpll_component.clk0_phase_shift = "0",
altpll_component.clk1_divide_by = 1,
altpll_component.clk1_duty_cycle = 50,
altpll_component.clk1_multiply_by = 1,
altpll_component.clk1_phase_shift = "0",
altpll_component.compensate_clock = "CLK0",
altpll_component.inclk0_input_frequency = 37037,
altpll_component.inclk1_input_frequency = 37037,
@ -170,7 +178,7 @@ module pll_2x (
altpll_component.port_scanread = "PORT_UNUSED",
altpll_component.port_scanwrite = "PORT_UNUSED",
altpll_component.port_clk0 = "PORT_USED",
altpll_component.port_clk1 = "PORT_UNUSED",
altpll_component.port_clk1 = "PORT_USED",
altpll_component.port_clk2 = "PORT_UNUSED",
altpll_component.port_clk3 = "PORT_UNUSED",
altpll_component.port_clk4 = "PORT_UNUSED",
@ -219,8 +227,11 @@ endmodule
// Retrieval info: PRIVATE: CUR_FBIN_CLK STRING "c0"
// Retrieval info: PRIVATE: DEVICE_SPEED_GRADE STRING "8"
// Retrieval info: PRIVATE: DIV_FACTOR0 NUMERIC "1"
// Retrieval info: PRIVATE: DIV_FACTOR1 NUMERIC "1"
// Retrieval info: PRIVATE: DUTY_CYCLE0 STRING "50.00000000"
// Retrieval info: PRIVATE: DUTY_CYCLE1 STRING "50.00000000"
// Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE0 STRING "27.000000"
// Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE1 STRING "27.000000"
// Retrieval info: PRIVATE: EXPLICIT_SWITCHOVER_COUNTER STRING "0"
// Retrieval info: PRIVATE: EXT_FEEDBACK_RADIO STRING "0"
// Retrieval info: PRIVATE: GLOCKED_COUNTER_EDIT_CHANGED STRING "1"
@ -241,18 +252,26 @@ endmodule
// Retrieval info: PRIVATE: LVDS_MODE_DATA_RATE STRING "Not Available"
// Retrieval info: PRIVATE: LVDS_MODE_DATA_RATE_DIRTY NUMERIC "0"
// Retrieval info: PRIVATE: LVDS_PHASE_SHIFT_UNIT0 STRING "deg"
// Retrieval info: PRIVATE: LVDS_PHASE_SHIFT_UNIT1 STRING "ps"
// Retrieval info: PRIVATE: MIG_DEVICE_SPEED_GRADE STRING "Any"
// Retrieval info: PRIVATE: MIRROR_CLK0 STRING "0"
// Retrieval info: PRIVATE: MIRROR_CLK1 STRING "0"
// Retrieval info: PRIVATE: MULT_FACTOR0 NUMERIC "1"
// Retrieval info: PRIVATE: MULT_FACTOR1 NUMERIC "1"
// Retrieval info: PRIVATE: NORMAL_MODE_RADIO STRING "1"
// Retrieval info: PRIVATE: OUTPUT_FREQ0 STRING "100.00000000"
// Retrieval info: PRIVATE: OUTPUT_FREQ1 STRING "100.00000000"
// Retrieval info: PRIVATE: OUTPUT_FREQ_MODE0 STRING "0"
// Retrieval info: PRIVATE: OUTPUT_FREQ_MODE1 STRING "0"
// Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT0 STRING "MHz"
// Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT1 STRING "MHz"
// Retrieval info: PRIVATE: PHASE_RECONFIG_FEATURE_ENABLED STRING "1"
// Retrieval info: PRIVATE: PHASE_RECONFIG_INPUTS_CHECK STRING "0"
// Retrieval info: PRIVATE: PHASE_SHIFT0 STRING "0.00000000"
// Retrieval info: PRIVATE: PHASE_SHIFT1 STRING "0.00000000"
// Retrieval info: PRIVATE: PHASE_SHIFT_STEP_ENABLED_CHECK STRING "0"
// Retrieval info: PRIVATE: PHASE_SHIFT_UNIT0 STRING "deg"
// Retrieval info: PRIVATE: PHASE_SHIFT_UNIT1 STRING "ps"
// Retrieval info: PRIVATE: PLL_ADVANCED_PARAM_CHECK STRING "0"
// Retrieval info: PRIVATE: PLL_ARESET_CHECK STRING "1"
// Retrieval info: PRIVATE: PLL_AUTOPLL_CHECK NUMERIC "1"
@ -275,11 +294,14 @@ endmodule
// Retrieval info: PRIVATE: SPREAD_USE STRING "0"
// Retrieval info: PRIVATE: SRC_SYNCH_COMP_RADIO STRING "0"
// Retrieval info: PRIVATE: STICKY_CLK0 STRING "1"
// Retrieval info: PRIVATE: STICKY_CLK1 STRING "1"
// Retrieval info: PRIVATE: SWITCHOVER_COUNT_EDIT NUMERIC "1"
// Retrieval info: PRIVATE: SWITCHOVER_FEATURE_ENABLED STRING "1"
// Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0"
// Retrieval info: PRIVATE: USE_CLK0 STRING "1"
// Retrieval info: PRIVATE: USE_CLK1 STRING "1"
// Retrieval info: PRIVATE: USE_CLKENA0 STRING "0"
// Retrieval info: PRIVATE: USE_CLKENA1 STRING "0"
// Retrieval info: PRIVATE: USE_MIL_SPEED_GRADE NUMERIC "0"
// Retrieval info: PRIVATE: ZERO_DELAY_RADIO STRING "0"
// Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all
@ -288,6 +310,10 @@ endmodule
// Retrieval info: CONSTANT: CLK0_DUTY_CYCLE NUMERIC "50"
// Retrieval info: CONSTANT: CLK0_MULTIPLY_BY NUMERIC "1"
// Retrieval info: CONSTANT: CLK0_PHASE_SHIFT STRING "0"
// Retrieval info: CONSTANT: CLK1_DIVIDE_BY NUMERIC "1"
// Retrieval info: CONSTANT: CLK1_DUTY_CYCLE NUMERIC "50"
// Retrieval info: CONSTANT: CLK1_MULTIPLY_BY NUMERIC "1"
// Retrieval info: CONSTANT: CLK1_PHASE_SHIFT STRING "0"
// Retrieval info: CONSTANT: COMPENSATE_CLOCK STRING "CLK0"
// Retrieval info: CONSTANT: INCLK0_INPUT_FREQUENCY NUMERIC "37037"
// Retrieval info: CONSTANT: INCLK1_INPUT_FREQUENCY NUMERIC "37037"
@ -321,7 +347,7 @@ endmodule
// Retrieval info: CONSTANT: PORT_SCANREAD STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_SCANWRITE STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_clk0 STRING "PORT_USED"
// Retrieval info: CONSTANT: PORT_clk1 STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_clk1 STRING "PORT_USED"
// Retrieval info: CONSTANT: PORT_clk2 STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_clk3 STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_clk4 STRING "PORT_UNUSED"
@ -345,6 +371,7 @@ endmodule
// Retrieval info: USED_PORT: activeclock 0 0 0 0 OUTPUT GND "activeclock"
// Retrieval info: USED_PORT: areset 0 0 0 0 INPUT GND "areset"
// Retrieval info: USED_PORT: c0 0 0 0 0 OUTPUT_CLK_EXT VCC "c0"
// Retrieval info: USED_PORT: c1 0 0 0 0 OUTPUT_CLK_EXT VCC "c1"
// Retrieval info: USED_PORT: clkswitch 0 0 0 0 INPUT GND "clkswitch"
// Retrieval info: USED_PORT: configupdate 0 0 0 0 INPUT GND "configupdate"
// Retrieval info: USED_PORT: inclk0 0 0 0 0 INPUT_CLK_EXT GND "inclk0"
@ -365,6 +392,7 @@ endmodule
// Retrieval info: CONNECT: @scandata 0 0 0 0 scandata 0 0 0 0
// Retrieval info: CONNECT: activeclock 0 0 0 0 @activeclock 0 0 0 0
// Retrieval info: CONNECT: c0 0 0 0 0 @clk 0 0 1 0
// Retrieval info: CONNECT: c1 0 0 0 0 @clk 0 0 1 1
// Retrieval info: CONNECT: locked 0 0 0 0 @locked 0 0 0 0
// Retrieval info: CONNECT: scandataout 0 0 0 0 @scandataout 0 0 0 0
// Retrieval info: CONNECT: scandone 0 0 0 0 @scandone 0 0 0 0
@ -373,8 +401,8 @@ endmodule
// Retrieval info: GEN_FILE: TYPE_NORMAL pll_2x.inc FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL pll_2x.cmp FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL pll_2x.bsf FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL pll_2x_inst.v FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL pll_2x_bb.v FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL pll_2x_inst.v TRUE
// Retrieval info: GEN_FILE: TYPE_NORMAL pll_2x_bb.v TRUE
// Retrieval info: GEN_FILE: TYPE_NORMAL pll_2x.mif TRUE
// Retrieval info: GEN_FILE: TYPE_NORMAL pll_2x.hex TRUE
// Retrieval info: LIB_FILE: altera_mf

File diff suppressed because it is too large Load Diff

View File

@ -1,410 +0,0 @@
//
// Copyright (C) 2022-2023 Markus Hiienkari <mhiienka@niksula.hut.fi>
//
// This file is part of Open Source Scan Converter project.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
module tvp7002_frontend (
input PCLK_i,
input CLK_MEAS_i,
input reset_n,
input [7:0] R_i,
input [7:0] G_i,
input [7:0] B_i,
input HS_i,
input VS_i,
input HSYNC_i,
input VSYNC_i,
input DE_i,
input FID_i,
input sogref_update_i,
input vsync_i_type,
input [31:0] hv_in_config,
input [31:0] hv_in_config2,
input [31:0] hv_in_config3,
input [31:0] misc_config,
output [7:0] R_o,
output [7:0] G_o,
output [7:0] B_o,
output HSYNC_o,
output VSYNC_o,
output DE_o,
output FID_o,
output reg interlace_flag,
output datavalid_o,
output [10:0] xpos_o,
output [10:0] ypos_o,
output reg [10:0] vtotal,
output reg frame_change,
output reg sof_scaler,
output reg [19:0] pcnt_frame,
output reg [7:0] hsync_width,
output reg sync_active
);
localparam FID_EVEN = 1'b0;
localparam FID_ODD = 1'b1;
localparam VSYNC_SEPARATED = 1'b0;
localparam VSYNC_RAW = 1'b1;
localparam PP_PL_START = 1;
localparam PP_RLPF_START = PP_PL_START + 1;
localparam PP_RLPF_LENGTH = 3;
localparam PP_RLPF_END = PP_RLPF_START + PP_RLPF_LENGTH;
localparam PP_PL_END = PP_RLPF_END;
reg [11:0] h_cnt, h_cnt_sogref;
reg [10:0] v_cnt;
reg [10:0] vmax_cnt;
reg HS_i_prev, VS_i_np_prev;
reg HSYNC_i_np_prev, VSYNC_i_np_prev;
reg [1:0] fid_next_ctr;
reg fid_next;
reg [3:0] h_ctr;
reg [7:0] R_pp[PP_PL_START:PP_PL_END] /* synthesis ramstyle = "logic" */;
reg [7:0] G_pp[PP_PL_START:PP_PL_END] /* synthesis ramstyle = "logic" */;
reg [7:0] B_pp[PP_PL_START:PP_PL_END] /* synthesis ramstyle = "logic" */;
reg HSYNC_pp[PP_PL_START:PP_PL_END] /* synthesis ramstyle = "logic" */;
reg VSYNC_pp[PP_PL_START:PP_PL_END] /* synthesis ramstyle = "logic" */;
reg FID_pp[PP_PL_START:PP_PL_END] /* synthesis ramstyle = "logic" */;
reg DE_pp[PP_PL_START:PP_PL_END] /* synthesis ramstyle = "logic" */;
reg datavalid_pp[PP_PL_START:PP_PL_END] /* synthesis ramstyle = "logic" */;
reg [10:0] xpos_pp[PP_PL_START:PP_PL_END] /* synthesis ramstyle = "logic" */;
reg [10:0] ypos_pp[PP_PL_START:PP_PL_END] /* synthesis ramstyle = "logic" */;
// Reverse LPF
wire rlpf_trigger_act;
reg signed [14:0] R_diff_s15_pre, G_diff_s15_pre, B_diff_s15_pre, R_diff_s15, G_diff_s15, B_diff_s15;
reg [7:0] R_pp_prev_rlpf, G_pp_prev_rlpf, B_pp_prev_rlpf;
// Measurement registers
reg [20:0] pcnt_frame_ctr;
reg [17:0] syncpol_det_ctr, hsync_hpol_ctr, vsync_hpol_ctr;
reg [3:0] sync_inactive_ctr;
reg [11:0] pcnt_line, pcnt_line_ctr, meas_h_cnt, meas_h_cnt_sogref;
reg [7:0] hs_ctr;
reg pcnt_line_stored;
reg [10:0] meas_v_cnt;
reg meas_hl_det, meas_fid;
reg hsync_i_pol, vsync_i_pol;
wire [11:0] H_TOTAL = hv_in_config[11:0];
wire [11:0] H_ACTIVE = hv_in_config[23:12];
wire [7:0] H_SYNCLEN = hv_in_config[31:24];
wire [8:0] H_BACKPORCH = hv_in_config2[8:0];
wire [10:0] V_ACTIVE = hv_in_config2[30:20];
wire [3:0] V_SYNCLEN = hv_in_config3[3:0];
wire [8:0] V_BACKPORCH = hv_in_config3[12:4];
wire [5:0] MISC_REV_LPF_STR = (misc_config[11:7] + 6'd16);
wire MISC_REV_LPF_ENABLE = (misc_config[11:7] != 5'h0);
wire [11:0] h_cnt_ref = (vsync_i_type == VSYNC_SEPARATED) ? h_cnt_sogref : h_cnt;
wire [11:0] even_min_thold = (H_TOTAL / 12'd4);
wire [11:0] even_max_thold = (H_TOTAL / 12'd2) + (H_TOTAL / 12'd4);
wire [11:0] meas_h_cnt_ref = (vsync_i_type == VSYNC_SEPARATED) ? meas_h_cnt_sogref : meas_h_cnt;
wire [11:0] meas_even_min_thold = (pcnt_line / 12'd4);
wire [11:0] meas_even_max_thold = (pcnt_line / 12'd2) + (pcnt_line / 12'd4);
wire meas_vblank_region = ((pcnt_frame_ctr < (pcnt_frame/16)) | (pcnt_frame_ctr > (pcnt_frame - (pcnt_frame/16))));
wire [11:0] glitch_filt_thold = meas_vblank_region ? (pcnt_line/4) : (pcnt_line/8);
// TODO: calculate H/V polarity independently
wire VS_i_np = (VS_i ^ ~vsync_i_pol);
wire VSYNC_i_np = (VSYNC_i ^ ~vsync_i_pol);
wire HSYNC_i_np = (HSYNC_i ^ ~hsync_i_pol);
// Sample skip for low-res optimized modes
wire [3:0] H_SKIP = hv_in_config3[27:24];
wire [3:0] H_SAMPLE_SEL = hv_in_config3[31:28];
// SOF position for scaler
wire [10:0] V_SOF_LINE = hv_in_config3[23:13];
function [7:0] apply_reverse_lpf;
input [7:0] data_prev;
input signed [14:0] diff;
reg signed [10:0] result;
begin
result = {3'b0,data_prev} + ~diff[14:4]; // allow for a small error to reduce adder length
apply_reverse_lpf = result[10] ? 8'h00 : |result[9:8] ? 8'hFF : result[7:0];
end
endfunction
always @(posedge PCLK_i) begin
R_pp[1] <= R_i;
G_pp[1] <= G_i;
B_pp[1] <= B_i;
DE_pp[1] <= (h_cnt >= H_SYNCLEN+H_BACKPORCH) & (h_cnt < H_SYNCLEN+H_BACKPORCH+H_ACTIVE) & (v_cnt >= V_SYNCLEN+V_BACKPORCH) & (v_cnt < V_SYNCLEN+V_BACKPORCH+V_ACTIVE);
datavalid_pp[1] <= (h_ctr == H_SAMPLE_SEL);
xpos_pp[1] <= (h_cnt-H_SYNCLEN-H_BACKPORCH);
ypos_pp[1] <= (v_cnt-V_SYNCLEN-V_BACKPORCH);
HS_i_prev <= HS_i;
VS_i_np_prev <= VS_i_np;
if (HS_i_prev & ~HS_i) begin
h_cnt <= 0;
h_ctr <= 0;
HSYNC_pp[1] <= 1'b0;
if (fid_next_ctr > 0)
fid_next_ctr <= fid_next_ctr - 1'b1;
if (fid_next_ctr == 2'h1) begin
// regenerated output timings start lagging by one scanline due to vsync detection,
// compensate by starting v_cnt from 1 (effectively reduces V_SYNCLEN by 1)
v_cnt <= 1;
if (~(interlace_flag & (fid_next == FID_EVEN))) begin
vmax_cnt <= 0;
//vtotal <= vmax_cnt + 1'b1;
frame_change <= 1'b1;
end else begin
vmax_cnt <= vmax_cnt + 1'b1;
end
end else begin
v_cnt <= v_cnt + 1'b1;
vmax_cnt <= vmax_cnt + 1'b1;
frame_change <= 1'b0;
end
sof_scaler <= (vmax_cnt == V_SOF_LINE);
end else begin
if (h_ctr == H_SKIP) begin
h_cnt <= h_cnt + 1'b1;
h_ctr <= 0;
if (h_cnt == H_SYNCLEN-1)
HSYNC_pp[1] <= 1'b1;
end else begin
h_ctr <= h_ctr + 1'b1;
end
end
// vsync leading edge processing per quadrant
if (VS_i_np_prev & ~VS_i_np) begin
if (h_cnt_ref < even_min_thold) begin
fid_next <= FID_ODD;
fid_next_ctr <= 2'h1;
end else if ((h_cnt_ref > even_max_thold) | ~interlace_flag) begin
fid_next <= FID_ODD;
fid_next_ctr <= 2'h2;
end else begin
fid_next <= FID_EVEN;
fid_next_ctr <= 2'h2;
end
end
// record starting position of csync leading edge for later FID detection
if (sogref_update_i) begin
h_cnt_sogref <= (h_cnt > even_max_thold) ? 0 : h_cnt;
end
if (((fid_next == FID_ODD) & (HS_i_prev & ~HS_i)) | ((fid_next == FID_EVEN) & (h_cnt == (H_TOTAL/2)-1'b1))) begin
if (fid_next_ctr == 2'h1) begin
VSYNC_pp[1] <= 1'b0;
FID_pp[1] <= fid_next;
//interlace_flag <= FID_pp[1] ^ fid_next;
end else begin
if (v_cnt == V_SYNCLEN-1)
VSYNC_pp[1] <= 1'b1;
end
end
end
// Pipeline stages 2-
integer pp_idx;
always @(posedge PCLK_i) begin
for(pp_idx = PP_PL_START+1; pp_idx <= PP_PL_END; pp_idx = pp_idx+1) begin
R_pp[pp_idx] <= R_pp[pp_idx-1];
G_pp[pp_idx] <= G_pp[pp_idx-1];
B_pp[pp_idx] <= B_pp[pp_idx-1];
HSYNC_pp[pp_idx] <= HSYNC_pp[pp_idx-1];
VSYNC_pp[pp_idx] <= VSYNC_pp[pp_idx-1];
FID_pp[pp_idx] <= FID_pp[pp_idx-1];
DE_pp[pp_idx] <= DE_pp[pp_idx-1];
datavalid_pp[pp_idx] <= datavalid_pp[pp_idx-1];
xpos_pp[pp_idx] <= xpos_pp[pp_idx-1];
ypos_pp[pp_idx] <= ypos_pp[pp_idx-1];
end
/* ---------- Reverse LPF (3 cycles) ---------- */
// Store a copy of valid sample data
if (datavalid_pp[PP_RLPF_START]) begin
R_pp_prev_rlpf <= R_pp[PP_RLPF_START];
G_pp_prev_rlpf <= G_pp[PP_RLPF_START];
B_pp_prev_rlpf <= B_pp[PP_RLPF_START];
end
// Push previous valid data into pipeline when RLPF enabled
if (MISC_REV_LPF_ENABLE) begin
R_pp[PP_RLPF_START+1] <= R_pp_prev_rlpf;
G_pp[PP_RLPF_START+1] <= G_pp_prev_rlpf;
B_pp[PP_RLPF_START+1] <= B_pp_prev_rlpf;
end
// Calculate diff to previous valid data
R_diff_s15_pre <= (R_pp_prev_rlpf - R_pp[PP_RLPF_START]);
G_diff_s15_pre <= (G_pp_prev_rlpf - G_pp[PP_RLPF_START]);
B_diff_s15_pre <= (B_pp_prev_rlpf - B_pp[PP_RLPF_START]);
// Cycle 2
R_diff_s15 <= (R_diff_s15_pre * MISC_REV_LPF_STR);
G_diff_s15 <= (G_diff_s15_pre * MISC_REV_LPF_STR);
B_diff_s15 <= (B_diff_s15_pre * MISC_REV_LPF_STR);
// Cycle 3
if (MISC_REV_LPF_ENABLE) begin
R_pp[PP_RLPF_END] <= apply_reverse_lpf(R_pp[PP_RLPF_START+2], R_diff_s15);
G_pp[PP_RLPF_END] <= apply_reverse_lpf(G_pp[PP_RLPF_START+2], G_diff_s15);
B_pp[PP_RLPF_END] <= apply_reverse_lpf(B_pp[PP_RLPF_START+2], B_diff_s15);
end
end
// Output
assign R_o = R_pp[PP_PL_END];
assign G_o = G_pp[PP_PL_END];
assign B_o = B_pp[PP_PL_END];
assign HSYNC_o = HSYNC_pp[PP_PL_END];
assign VSYNC_o = VSYNC_pp[PP_PL_END];
assign FID_o = FID_pp[PP_PL_END];
assign DE_o = DE_pp[PP_PL_END];
assign datavalid_o = datavalid_pp[PP_PL_END];
assign xpos_o = xpos_pp[PP_PL_END];
assign ypos_o = ypos_pp[PP_PL_END];
// Calculate horizontal and vertical counts
always @(posedge CLK_MEAS_i) begin
if ((VSYNC_i_np_prev & ~VSYNC_i_np) & (~interlace_flag | (meas_fid == FID_EVEN))) begin
pcnt_frame_ctr <= 1;
pcnt_line_stored <= 1'b0;
pcnt_frame <= interlace_flag ? (pcnt_frame_ctr>>1) : pcnt_frame_ctr[19:0];
end else if (pcnt_frame_ctr < 21'h1fffff) begin
pcnt_frame_ctr <= pcnt_frame_ctr + 1'b1;
end
if (HSYNC_i_np_prev & ~HSYNC_i_np) begin
pcnt_line_ctr <= 1;
hs_ctr <= 1;
// store count 1ms after vsync
if (~pcnt_line_stored & (pcnt_frame_ctr > 21'd27000)) begin
pcnt_line <= pcnt_line_ctr;
hsync_width <= hs_ctr;
pcnt_line_stored <= 1'b1;
end
end else begin
pcnt_line_ctr <= pcnt_line_ctr + 1'b1;
if (~HSYNC_i_np)
hs_ctr <= hs_ctr + 1'b1;
end
HSYNC_i_np_prev <= HSYNC_i_np;
VSYNC_i_np_prev <= VSYNC_i_np;
end
// Detect sync polarities and activity
always @(posedge CLK_MEAS_i) begin
if (syncpol_det_ctr == 0) begin
hsync_i_pol <= (hsync_hpol_ctr > 18'h1ffff);
vsync_i_pol <= (vsync_hpol_ctr > 18'h1ffff);
hsync_hpol_ctr <= 0;
vsync_hpol_ctr <= 0;
if ((vsync_hpol_ctr == '0) | (vsync_hpol_ctr == '1)) begin
if (sync_inactive_ctr == '1)
sync_active <= 1'b0;
else
sync_inactive_ctr <= sync_inactive_ctr + 1'b1;
end else begin
sync_inactive_ctr <= 0;
sync_active <= 1'b1;
end
end else begin
if (HSYNC_i)
hsync_hpol_ctr <= hsync_hpol_ctr + 1'b1;
if (VSYNC_i)
vsync_hpol_ctr <= vsync_hpol_ctr + 1'b1;
end
syncpol_det_ctr <= syncpol_det_ctr + 1'b1;
end
// Detect interlace and line count
always @(posedge CLK_MEAS_i) begin
if ((HSYNC_i_np_prev & ~HSYNC_i_np) & (meas_h_cnt > glitch_filt_thold)) begin
// detect half-line equalization pulses
if ((meas_h_cnt > ((pcnt_line/2) - (pcnt_line/4))) && (meas_h_cnt < ((pcnt_line/2) + (pcnt_line/4)))) begin
/*if (meas_hl_det) begin
meas_hl_det <= 1'b0;
meas_h_cnt <= 0;
meas_v_cnt <= meas_v_cnt + 1'b1;
end else begin*/
meas_hl_det <= 1'b1;
meas_h_cnt <= meas_h_cnt + 1'b1;
//end
end else begin
meas_hl_det <= 1'b0;
meas_h_cnt <= 0;
meas_v_cnt <= meas_v_cnt + 1'b1;
end
meas_h_cnt_sogref <= meas_h_cnt;
end else if (~VSYNC_i_np & (meas_h_cnt >= pcnt_line)) begin
// hsync may be missing during vsync, force line change detect if pcnt_line is exceeded
meas_hl_det <= 1'b0;
meas_h_cnt <= 0;
meas_v_cnt <= meas_v_cnt + 1'b1;
end else begin
meas_h_cnt <= meas_h_cnt + 1'b1;
end
if (VSYNC_i_np_prev & ~VSYNC_i_np) begin
if ((meas_h_cnt_ref < meas_even_min_thold) | (meas_h_cnt_ref > meas_even_max_thold)) begin
meas_fid <= FID_ODD;
interlace_flag <= (meas_fid == FID_EVEN);
if (vsync_i_type == VSYNC_RAW) begin
// vsync leading edge may occur at hsync edge or either side of it
if ((HSYNC_i_np_prev & ~HSYNC_i_np) | (meas_h_cnt >= pcnt_line)) begin
meas_v_cnt <= 1;
vtotal <= meas_v_cnt;
end else if (meas_h_cnt < meas_even_min_thold) begin
meas_v_cnt <= 1;
vtotal <= meas_v_cnt - 1'b1;
end else begin
meas_v_cnt <= 0;
vtotal <= meas_v_cnt;
end
end else begin
meas_v_cnt <= 0;
vtotal <= meas_v_cnt;
end
end else begin
meas_fid <= FID_EVEN;
interlace_flag <= (meas_fid == FID_ODD);
if (meas_fid == FID_EVEN) begin
meas_v_cnt <= 0;
vtotal <= meas_v_cnt;
end
end
end
end
endmodule

View File

@ -1,13 +1,5 @@
#Select the master service type and check for available service paths.
while 1 {
set service_paths [get_service_paths master]
if {[llength $service_paths] > 0} {
break
}
puts "Refreshing connections..."
refresh_connections
after 100
}
set service_paths [get_service_paths master]
#Set the master service path.
set master_service_path [lindex $service_paths 0]
@ -16,7 +8,7 @@ set master_service_path [lindex $service_paths 0]
set claim_path [claim_service master $master_service_path mylib]
puts "Halting CPU"
master_write_32 $claim_path 0x0 0x10000
master_write_32 $claim_path 0x0 0x1
puts "Writing block RAM"
master_write_from_file $claim_path mem_init/sys_onchip_memory2_0.bin 0x10000

View File

@ -33,7 +33,7 @@
<Extensions>
<![CDATA[*.cpp;*.c;*.h;*.hpp;*.xrc;*.wxcp;*.fbp]]>
</Extensions>
<Topleveldir>./</Topleveldir>
<Topleveldir>/home/markus/Code/ossc/software</Topleveldir>
</Reconciliation>
<VirtualDirectory Name="sys_controller">
<VirtualDirectory Name="ths7353">
@ -61,7 +61,9 @@
<File Name="sys_controller/spi_charlcd/lcd.h"/>
</VirtualDirectory>
<VirtualDirectory Name="tvp7002">
<File Name="sys_controller/tvp7002/video_modes.c"/>
<File Name="sys_controller/tvp7002/tvp7002_regs.h"/>
<File Name="sys_controller/tvp7002/video_modes.h"/>
<File Name="sys_controller/tvp7002/tvp7002.h"/>
<File Name="sys_controller/tvp7002/tvp7002.c"/>
</VirtualDirectory>
@ -87,9 +89,6 @@
<File Name="sys_controller/ossc/firmware.c"/>
<File Name="sys_controller/ossc/userdata.h"/>
<File Name="sys_controller/ossc/userdata.c"/>
<File Name="sys_controller/ossc/video_modes.h"/>
<File Name="sys_controller/ossc/video_modes.c"/>
<File Name="sys_controller/ossc/video_modes_list.c"/>
</VirtualDirectory>
<VirtualDirectory Name="ulibSD">
<File Name="sys_controller/ulibSD/integer.h"/>

View File

@ -38,13 +38,13 @@ ALT_LDFLAGS :=
#------------------------------------------------------------------------------
# The adjust-path macro
#
#
# If COMSPEC/ComSpec is defined, Make is launched from Windows through
# Cygwin. The adjust-path macro converts absolute windows paths into
# unix style paths (Example: c:/dir -> /c/dir). This will ensture
# paths are readable by GNU Make.
#
# If COMSPEC/ComSpec is not defined, Make is launched from linux, and no
# If COMSPEC/ComSpec is not defined, Make is launched from linux, and no
# adjustment is necessary
#
#------------------------------------------------------------------------------
@ -57,7 +57,7 @@ endif # COMSPEC
ifdef COMSPEC # if Windows OS
ifeq ($(MAKE_VERSION),3.81)
ifeq ($(MAKE_VERSION),3.81)
#
# adjust-path/adjust-path-mixed for Mingw Gnu Make on Windows
#
@ -69,10 +69,10 @@ ifeq ($(MAKE_VERSION),3.81)
#
# adjust-path
# - converts back slash characters into forward slashes
# - converts back slash characters into forward slashes
# - if input arg ($1) is an empty string then return the empty string
# - if input arg ($1) does not contain the string ":/", then return input arg
# - using sed, convert mixed path [c:/...] into mingw path [/c/...]
# - using sed, convert mixed path [c:/...] into mingw path [/c/...]
define adjust-path
$(strip \
$(if $1,\
@ -83,13 +83,13 @@ endef
#
# adjust-path-mixed
# - converts back slash characters into forward slashes
# - converts back slash characters into forward slashes
# - if input arg ($1) is an empty string then return the empty string
# - if input arg ($1) does not begin with a forward slash '/' char, then
# - if input arg ($1) does not begin with a forward slash '/' char, then
# return input arg
# - using sed, convert mingw path [/c/...] or cygwin path [/c/cygdrive/...]
# into a mixed path [c:/...]
define adjust-path-mixed
# - using sed, convert mingw path [/c/...] or cygwin path [/c/cygdrive/...]
# into a mixed path [c:/...]
define adjust-path-mixed
$(strip \
$(if $1,\
$(if $(findstring $(subst \,/,$1),$(patsubst /%,%,$(subst \,/,$1))),\
@ -97,7 +97,7 @@ $(subst \,/,$1),\
$(shell echo $(subst \,/,$1) | sed -e 's,^/cygdrive/\([a-zA-Z]\)/,\1:/,' -e 's,^/\([a-zA-Z]\)/,\1:/,'))))
endef
else # MAKE_VERSION != 3.81 (MAKE_VERSION == 3.80 or MAKE_VERSION == 3.79)
else # MAKE_VERSION != 3.81 (MAKE_VERSION == 3.80 or MAKE_VERSION == 3.79)
#
# adjust-path for Cygwin Gnu Make
# $(call adjust-path,c:/aaa/bbb) = /cygdrive/c/aaa/bbb
@ -123,22 +123,22 @@ endif # COMSPEC
ACTIVE_BUILD_CONFIG := default
BUILD_CONFIGS := default
# The following TYPE comment allows tools to identify the 'type' of target this
# makefile is associated with.
# The following TYPE comment allows tools to identify the 'type' of target this
# makefile is associated with.
# TYPE: APP_MAKEFILE
# This following VERSION comment indicates the version of the tool used to
# generate this makefile. A makefile variable is provided for VERSION as well.
# This following VERSION comment indicates the version of the tool used to
# generate this makefile. A makefile variable is provided for VERSION as well.
# ACDS_VERSION: 14.1
ACDS_VERSION := 14.1
# This following BUILD_NUMBER comment indicates the build number of the tool
# used to generate this makefile.
# This following BUILD_NUMBER comment indicates the build number of the tool
# used to generate this makefile.
# BUILD_NUMBER: 190
# Define path to the application ELF.
# It may be used by the makefile fragments so is defined before including them.
#
# Define path to the application ELF.
# It may be used by the makefile fragments so is defined before including them.
#
ELF := sys_controller.elf
# Paths to C, C++, and assembly source files.
@ -149,6 +149,7 @@ C_SRCS += it6613/it6613.c
C_SRCS += it6613/it6613_drv.c
C_SRCS += it6613/it6613_sys.c
C_SRCS += tvp7002/tvp7002.c
C_SRCS += tvp7002/video_modes.c
C_SRCS += ths7353/ths7353.c
C_SRCS += pcm1862/pcm1862.c
C_SRCS += spi_charlcd/lcd.c
@ -170,7 +171,6 @@ else
C_SRCS += ossc/userdata.c
endif
C_SRCS += ossc/utils.c
C_SRCS += ossc/video_modes.c
C_SRCS += ulibSD/sd_io.c
C_SRCS += ulibSD/spi_io.c
CXX_SRCS :=
@ -257,7 +257,7 @@ endif
all:
@$(ECHO) [$(APP_NAME) build complete]
all : build_pre_process libs app build_post_process
all : build_pre_process libs app build_post_process
#------------------------------------------------------------------------------
@ -283,25 +283,25 @@ ABS_BSP_ROOT_DIR := $(call adjust-path-mixed,$(shell cd "$(BSP_ROOT_DIR)"; pwd))
BSP_INCLUDE_FILE := $(BSP_ROOT_DIR)/public.mk
ALT_LIBRARY_ROOT_DIR := $(BSP_ROOT_DIR)
include $(BSP_INCLUDE_FILE)
# C2H will need this to touch the BSP public.mk and avoid the sopc file
# C2H will need this to touch the BSP public.mk and avoid the sopc file
# out-of-date error during a BSP make
ABS_BSP_INCLUDE_FILE := $(ABS_BSP_ROOT_DIR)/public.mk
ifneq ($(WARNING.SMALL_STACK_SIZE),)
# This WARNING is here to protect you from unknowingly using a very small stack
# If the warning is set, increase your stack size or enable the BSP small stack
# If the warning is set, increase your stack size or enable the BSP small stack
# setting to eliminate the warning
$(warning WARNING: $(WARNING.SMALL_STACK_SIZE))
endif
# If the BSP public.mk indicates that ALT_SIM_OPTIMIZE is set, rename the ELF
# by prefixing it with RUN_ON_HDL_SIMULATOR_ONLY_.
# If the BSP public.mk indicates that ALT_SIM_OPTIMIZE is set, rename the ELF
# by prefixing it with RUN_ON_HDL_SIMULATOR_ONLY_.
ifneq ($(filter -DALT_SIM_OPTIMIZE,$(ALT_CPPFLAGS)),)
ELF := RUN_ON_HDL_SIMULATOR_ONLY_$(ELF)
endif
# If the BSP public.mk indicates that ALT_PROVIDE_GMON is set, add option to
# If the BSP public.mk indicates that ALT_PROVIDE_GMON is set, add option to
# download_elf target
ifneq ($(filter -DALT_PROVIDE_GMON,$(ALT_CPPFLAGS)),)
GMON_OUT_FILENAME := gmon.out
@ -434,22 +434,22 @@ ifeq ($(CREATE_LINKER_MAP), 1)
APP_LDFLAGS += -Wl,-Map=$(LINKER_MAP_NAME)
endif
# QUARTUS_PROJECT_DIR and SOPC_NAME need to be defined if you want the
# mem_init_install target of the mem_init.mk (located in the associated BSP)
# to know how to copy memory initialization files (e.g. .dat, .hex) into
# QUARTUS_PROJECT_DIR and SOPC_NAME need to be defined if you want the
# mem_init_install target of the mem_init.mk (located in the associated BSP)
# to know how to copy memory initialization files (e.g. .dat, .hex) into
# directories required for Quartus compilation or RTL simulation.
# Defining QUARTUS_PROJECT_DIR causes mem_init_install to copy memory
# initialization files into your Quartus project directory. This is required
# to provide the initial memory contents of FPGA memories that can be
# initialized by the programming file (.sof) or Hardcopy ROMs. It is also used
# Defining QUARTUS_PROJECT_DIR causes mem_init_install to copy memory
# initialization files into your Quartus project directory. This is required
# to provide the initial memory contents of FPGA memories that can be
# initialized by the programming file (.sof) or Hardcopy ROMs. It is also used
# for VHDL simulation of on-chip memories.
# Defining SOPC_NAME causes the mem_init_install target to copy memory
# initialization files into your RTL simulation directory. This is required
# to provide the initial memory contents of all memories that can be
# initialized by RTL simulation. This variable should be set to the same name
# as your SOPC Builder system name. For example, if you have a system called
# Defining SOPC_NAME causes the mem_init_install target to copy memory
# initialization files into your RTL simulation directory. This is required
# to provide the initial memory contents of all memories that can be
# initialized by RTL simulation. This variable should be set to the same name
# as your SOPC Builder system name. For example, if you have a system called
# "foo.sopc", this variable should be set to "foo".
# If SOPC_NAME is not set and QUARTUS_PROJECT_DIR is set, then derive SOPC_NAME.
@ -459,23 +459,23 @@ SOPC_NAME := $(basename $(notdir $(wildcard $(QUARTUS_PROJECT_DIR)/*.sopcinfo)))
endif
endif
# Defining JDI_FILE is required to specify the JTAG Debug Information File
# path. This file is generated by Quartus, and is needed along with the
# .sopcinfo file to resolve processor instance ID's from names in a multi-CPU
# systems. For multi-CPU systems, the processor instance ID is used to select
# Defining JDI_FILE is required to specify the JTAG Debug Information File
# path. This file is generated by Quartus, and is needed along with the
# .sopcinfo file to resolve processor instance ID's from names in a multi-CPU
# systems. For multi-CPU systems, the processor instance ID is used to select
# from multiple CPU's during ELF download.
# Both JDI_FILE and SOPCINFO_FILE are provided by the BSP if they found during
# BSP creation. If JDI_FILE is not set and QUARTUS_PROJECT_DIR is set, then
# derive JDI_FILE. We do not attempt to derive SOPCINFO_FILE since there may be
# multiple .sopcinfo files in a Quartus project.
# Both JDI_FILE and SOPCINFO_FILE are provided by the BSP if they found during
# BSP creation. If JDI_FILE is not set and QUARTUS_PROJECT_DIR is set, then
# derive JDI_FILE. We do not attempt to derive SOPCINFO_FILE since there may be
# multiple .sopcinfo files in a Quartus project.
ifeq ($(JDI_FILE),)
ifneq ($(QUARTUS_PROJECT_DIR),)
JDI_FILE := $(firstword $(wildcard $(QUARTUS_PROJECT_DIR)/output_files/*.jdi) $(wildcard $(QUARTUS_PROJECT_DIR)/*.jdi))
endif
endif
# Path to root runtime directory used for hdl simulation
# Path to root runtime directory used for hdl simulation
RUNTIME_ROOT_DIR := $(CONFIG_OBJ_DIR)/runtime
@ -523,7 +523,7 @@ SDIR_OBJ_LIST := $(sort $(SDIR_OBJ_LIST_C) $(SDIR_OBJ_LIST_CPP) \
# Relative-pathed objects that being with "../" are handled differently.
#
# Regular objects are created as
# Regular objects are created as
# $(CONFIG_OBJ_DIR)/<path>/<filename>.o
# where the path structure is maintained under the obj directory. This
# applies for both absolute and relative paths; in the absolute path
@ -531,16 +531,16 @@ SDIR_OBJ_LIST := $(sort $(SDIR_OBJ_LIST_C) $(SDIR_OBJ_LIST_CPP) \
# directory. This is done to allow two source files with the same name
# to be included as part of the project.
#
# Note: On Cygwin, the path recreated under the obj directory will be
# Note: On Cygwin, the path recreated under the obj directory will be
# the cygpath -u output path.
#
# Relative-path objects that begin with "../" cause problems under this
# Relative-path objects that begin with "../" cause problems under this
# scheme, as $(CONFIG_OBJ_DIR)/../<rest of path>/ can potentially put the object
# files anywhere in the system, creating clutter and polluting the source tree.
# As such, their paths are flattened - the object file created will be
# $(CONFIG_OBJ_DIR)/<filename>.o. Due to this, two files specified with
# "../" in the beginning cannot have the same name in the project. VPATH
# will be set for these sources to allow make to relocate the source file
# As such, their paths are flattened - the object file created will be
# $(CONFIG_OBJ_DIR)/<filename>.o. Due to this, two files specified with
# "../" in the beginning cannot have the same name in the project. VPATH
# will be set for these sources to allow make to relocate the source file
# via %.o rules.
#
# The following lines separate the object list into the flatten and regular
@ -628,7 +628,7 @@ ifneq ($(wildcard $(SOPCINFO_FILE)),)
ELF_PATCH_FLAG += --sopcinfo $(SOPCINFO_FILE)
endif
# Use the DOWNLOAD_CABLE variable to specify which JTAG cable to use.
# Use the DOWNLOAD_CABLE variable to specify which JTAG cable to use.
# This is not needed if you only have one cable.
ifneq ($(DOWNLOAD_CABLE),)
DOWNLOAD_CABLE_FLAG := --cable '$(DOWNLOAD_CABLE)'
@ -793,7 +793,7 @@ $(AS) -MP -MMD -c $(APP_CPPFLAGS) $(APP_CFLAGS) $(APP_ASFLAGS) -o $@ $<
$(AS_POST_PROCESS)
endef
ifeq ($(MAKE_VERSION),3.81)
ifeq ($(MAKE_VERSION),3.81)
.SECONDEXPANSION:
$(APP_OBJS_C): $(CONFIG_OBJ_DIR)/%.o: $$(call adjust-path-mixed,%.c)
@ -891,7 +891,7 @@ help :
@$(ECHO) " all (default) - Application and all libraries (including BSP)"
@$(ECHO) " bsp - Just the BSP"
@$(ECHO) " libs - All libraries (including BSP)"
@$(ECHO) " flash - All flash files"
@$(ECHO) " flash - All flash files"
@$(ECHO) " mem_init_generate - All memory initialization files"
ifeq ($(QSYS),1)
@$(ECHO) " mem_init_install - This target is deprecated for QSys Systems"
@ -952,7 +952,7 @@ $(APP_LDDEPS): libs
endif
# Rules to force your project to rebuild or relink
# .force_relink file will cause any application that depends on this project to relink
# .force_relink file will cause any application that depends on this project to relink
# .force_rebuild file will cause this project to rebuild object files
# .force_rebuild_all file will cause this project and any project that depends on this project to rebuild object files
@ -1019,9 +1019,9 @@ download-elf : $(ELF)
else \
$(ECHO) Info: Downloading $(ELF); \
$(DOWNLOAD) --go --cpu_name=$(CPU_NAME) $(DOWNLOAD_CABLE_FLAG) $(SOPC_SYSID_FLAG) $(DOWNLOAD_JDI_FLAG) $(WRITE_GMON_OPTION) $(ELF); \
fi
fi
# Delete the target of a rule if it has changed and its commands exit
# Delete the target of a rule if it has changed and its commands exit
# with a nonzero exit status.
.DELETE_ON_ERROR:

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
//
// Copyright (C) 2015-2023 Markus Hiienkari <mhiienka@niksula.hut.fi>
// Copyright (C) 2015-2022 Markus Hiienkari <mhiienka@niksula.hut.fi>
//
// This file is part of Open Source Scan Converter project.
//
@ -33,6 +33,7 @@
#include "sdcard.h"
#include "menu.h"
#include "avconfig.h"
#include "sysconfig.h"
#include "firmware.h"
#include "userdata.h"
#include "it6613.h"
@ -42,19 +43,19 @@
#include "sd_io.h"
#include "sys/alt_timestamp.h"
#define STABLE_THOLD 1
#define MIN_LINES_PROGRESSIVE 200
#define MIN_LINES_INTERLACED 400
#define STATUS_TIMEOUT_US 25000
#define SYNC_LOCK_THOLD 3
#define SYNC_LOSS_THOLD -5
#define STATUS_TIMEOUT 100000
#define PCNT_TOLERANCE 50
#define HSYNC_WIDTH_TOLERANCE 8
alt_u32 sys_ctrl;
alt_u16 sys_ctrl;
// Current mode
avmode_t cm;
extern mode_data_t video_modes_plm[];
extern mode_data_t video_modes[];
extern ypbpr_to_rgb_csc_t csc_coeffs[];
extern alt_u16 rc_keymap[REMOTE_MAX_KEYS];
extern alt_u16 rc_keymap_default[REMOTE_MAX_KEYS];
@ -63,11 +64,11 @@ extern alt_u32 btn_code, btn_code_prev;
extern alt_u8 remote_rpt, remote_rpt_prev;
extern avconfig_t tc, tc_default;
extern alt_u8 vm_sel;
extern char target_profile_name[PROFILE_NAME_LEN+1];
tvp_input_t target_tvp;
tvp_sync_input_t target_tvp_sync;
alt_u8 target_type;
alt_u8 stable_frames;
alt_u8 update_cur_vm;
alt_u8 profile_sel, profile_sel_menu, input_profiles[AV_LAST], lt_sel, def_input, profile_link, lcd_bl_timeout;
@ -81,13 +82,9 @@ avinput_t target_input;
alt_u8 pcm1862_active;
uint8_t sl_def_iv_x, sl_def_iv_y;
alt_u32 pclk_out;
alt_u32 read_it2(alt_u32 regaddr);
mode_data_t vmode_in, vmode_out;
vm_proc_config_t vm_conf;
// Manually (see cyiv-51005.pdf) or automatically (MIF/HEX from PLL megafunction) generated config may not
// provide fully correct scan chain data (e.g. mismatches in C3) and lead to incorrect PLL configuration.
// To get correct scan chain data, do the following:
@ -101,12 +98,9 @@ vm_proc_config_t vm_conf;
// 8. Compare your MIF/HEX to the captured scan chain and update it accordingly
// 9. Dump the updated scan chain data to an array like below (last 16 bits are 0)
// 10. PLL can be then reconfigured with custom pll_reconfig as shown in program_mode()
const pll_config_t pll_configs[] = { {{0x0d806000, 0x00402010, 0x08800020, 0x00080002, 0x00000000}}, // 1x (default)
{{0x0d806000, 0x00402008, 0x04800020, 0x00080002, 0x00000000}}, // 2x (~20-40MHz)
{{0x0d806000, 0x00441c07, 0x02800020, 0x00080002, 0x00000000}}, // 3x (~20-40MHz)
{{0x0d806000, 0x00402004, 0x02800020, 0x00080002, 0x00000000}}, // 4x (~20-40MHz)
{{0x0d806000, 0x00441c05, 0x01800020, 0x00080002, 0x00000000}}, // 5x (~20-40MHz)
{{0x0e406000, 0x00281407, 0x02800020, 0x00080002, 0x00000000}} }; // 2x (~75MHz)
const pll_config_t pll_configs[] = { {{0x0d806000, 0x00402010, 0x08040220, 0x00004022, 0x00000000}}, // 1x, 1x (default)
{{0x0dc06000, 0x00783c11, 0x070180e0, 0x0000180e, 0x00000000}}, // 2x, 5x
{{0x0d806000, 0x00301804, 0x02014060, 0x00001406, 0x00000000}} }; // 3x, 4x
volatile sc_regs *sc = (volatile sc_regs*)SC_CONFIG_0_BASE;
volatile osd_regs *osd = (volatile osd_regs*)OSD_GENERATOR_0_BASE;
@ -154,7 +148,7 @@ inline void SetupAudio(tx_mode_t mode)
EnableAudioInfoFrame(FALSE, NULL);
if (mode != TX_DVI) {
EnableAudioOutput4OSSC(cm.pclk_o_hz, tc.audio_dw_sampl, tc.audio_swap_lr);
EnableAudioOutput4OSSC(pclk_out, tc.audio_dw_sampl, tc.audio_swap_lr);
HDMITX_SetAudioInfoFrame((BYTE)tc.audio_dw_sampl);
#ifdef DEBUG
Switch_HDMITX_Bank(1);
@ -181,7 +175,7 @@ inline void TX_enable(tx_mode_t mode)
EnableVideoOutput(cm.hdmitx_pclk_level ? PCLK_HIGH : PCLK_MEDIUM, COLOR_RGB444, (mode == TX_HDMI_YCBCR444) ? COLOR_YUV444 : COLOR_RGB444, (mode != TX_DVI));
if (mode != TX_DVI) {
HDMITX_SetAVIInfoFrame(vmode_out.vic, (mode == TX_HDMI_RGB) ? F_MODE_RGB444 : F_MODE_YUV444, 0, 0, tc.hdmi_itc, cm.hdmitx_pixr_ifr);
HDMITX_SetAVIInfoFrame(cm.hdmitx_vic, (mode == TX_HDMI_RGB) ? F_MODE_RGB444 : F_MODE_YUV444, 0, 0, tc.hdmi_itc, cm.hdmitx_pixr_ifr);
cm.cc.hdmi_itc = tc.hdmi_itc;
}
@ -231,7 +225,8 @@ void pll_reconfigure(alt_u8 id)
void set_lpf(alt_u8 lpf)
{
alt_u32 pclk;
pclk = estimate_dotclk(&vmode_in, (TVP_EXTCLK_HZ/cm.clkcnt));
pclk = (TVP_EXTCLK_HZ/cm.clkcnt)*video_modes[cm.id].h_total;
printf("PCLK_in: %luHz\n", pclk);
//Auto
if (lpf == 0) {
@ -250,6 +245,7 @@ void set_lpf(alt_u8 lpf)
ths_set_lpf(THS_LPF_16MHZ);
break;
case VIDEO_SDTV:
case VIDEO_LDTV:
default:
ths_set_lpf(THS_LPF_9MHZ);
break;
@ -285,87 +281,151 @@ inline int check_linecnt(alt_u8 progressive, alt_u32 totlines) {
return (totlines >= MIN_LINES_INTERLACED);
}
void set_sampler_phase(uint8_t sampler_phase) {
uint32_t sample_rng_x1000;
uint8_t tvp_phase;
vmode_in.sampler_phase = sampler_phase;
if (vm_conf.h_skip == 0) {
vm_conf.h_sample_sel = 0;
tvp_phase = sampler_phase;
} else {
sample_rng_x1000 = 360000 / (vm_conf.h_skip+1);
vm_conf.h_sample_sel = (sampler_phase*11250)/sample_rng_x1000;
tvp_phase = ((((sampler_phase*11250) % sample_rng_x1000)*32)/sample_rng_x1000);
}
if (vm_conf.h_skip > 0)
printf("Sample sel: %u/%u\n", (vm_conf.h_sample_sel+1), (vm_conf.h_skip+1));
tvp_set_hpll_phase(tvp_phase);
}
// Check if input video status / target configuration has changed
status_t get_status(tvp_sync_input_t syncinput)
{
alt_u32 totlines, clkcnt, pcnt_frame;
alt_u8 progressive, sync_active, valid_linecnt, hsync_width;
status_t status = NO_CHANGE;
alt_timestamp_type start_ts = alt_timestamp();
alt_u32 data1, data2;
alt_u32 totlines, clkcnt;
alt_u8 progressive;
//alt_u8 refclk;
alt_u8 sync_active;
alt_u8 vsyncmode;
alt_u16 totlines_tvp;
alt_u16 h_samplerate;
status_t status;
static alt_8 act_ctr;
alt_u32 ctr;
int valid_linecnt;
alt_u8 h_mult;
status = NO_CHANGE;
// Wait until vsync active (avoid noise coupled to I2C bus on earlier prototypes)
while (alt_timestamp() < start_ts + STATUS_TIMEOUT_US*(TIMER_0_FREQ/1000000)) {
if (IORD_ALTERA_AVALON_PIO_DATA(PIO_1_BASE) & VSYNC_FLAG_MASK)
for (ctr=0; ctr<STATUS_TIMEOUT; ctr++) {
if (sc->sc_status.vsync_flag) {
//printf("ctrval %u\n", ctr);
break;
}
}
//sync_active = tvp_check_sync(syncinput);
sync_active = sc->fe_status.sync_active;
sync_active = tvp_check_sync(syncinput);
vsyncmode = cm.sync_active ? sc->sc_status.fpga_vsyncgen : 0;
// Read sync information from TVP7002 frontend
totlines = sc->fe_status.vtotal;
progressive = !sc->fe_status.interlace_flag;
pcnt_frame = (unsigned long)sc->fe_status2.pcnt_frame;
hsync_width = (unsigned long)sc->fe_status2.hsync_width;
clkcnt = pcnt_frame/(totlines>>!progressive);
// Read sync information from TVP7002 status registers
data1 = tvp_readreg(TVP_LINECNT1);
data2 = tvp_readreg(TVP_LINECNT2);
totlines = ((data2 & 0x0f) << 8) | data1;
progressive = !!(data2 & (1<<5));
cm.macrovis = !!(data2 & (1<<6));
data1 = tvp_readreg(TVP_CLKCNT1);
data2 = tvp_readreg(TVP_CLKCNT2);
clkcnt = ((data2 & 0x0f) << 8) | data1;
// Read how many lines TVP7002 outputs in reality (valid only if output enabled)
totlines_tvp = sc->sc_status.vmax_tvp+1;
// NOTE: "progressive" may not have correct value if H-PLL is not locked (!cm.sync_active)
if ((vsyncmode == 0x2) || (!cm.sync_active && (totlines < MIN_LINES_INTERLACED))) {
progressive = 1;
} else if (vsyncmode == 0x1) {
progressive = 0;
totlines = totlines_tvp; //compensate skipped vsync
}
valid_linecnt = check_linecnt(progressive, totlines);
// Check sync activity
// TVP7002 may randomly report "no sync" (especially with arcade boards),
// thus disable output only after N consecutive "no sync"-events
if (!cm.sync_active && sync_active && valid_linecnt) {
cm.sync_active = 1;
status = ACTIVITY_CHANGE;
printf("Sync up in %d...\n", SYNC_LOCK_THOLD-act_ctr);
if (act_ctr >= SYNC_LOCK_THOLD) {
act_ctr = 0;
cm.sync_active = 1;
status = ACTIVITY_CHANGE;
} else {
act_ctr++;
}
} else if (cm.sync_active && (!sync_active || !valid_linecnt)) {
cm.sync_active = 0;
status = ACTIVITY_CHANGE;
printf("Sync down in %d...\n", act_ctr-SYNC_LOSS_THOLD);
if (act_ctr <= SYNC_LOSS_THOLD) {
act_ctr = 0;
cm.sync_active = 0;
status = ACTIVITY_CHANGE;
} else {
act_ctr--;
}
} else {
act_ctr = 0;
}
if (valid_linecnt) {
if ((totlines != cm.totlines) ||
(progressive != cm.progressive) ||
(pcnt_frame < (cm.pcnt_frame - PCNT_TOLERANCE)) ||
(pcnt_frame > (cm.pcnt_frame + PCNT_TOLERANCE)) ||
(abs(((int)hsync_width - (int)cm.hsync_width)) > HSYNC_WIDTH_TOLERANCE)) {
printf("totlines: %lu (cur) / %lu (prev), pcnt_frame: %lu (cur) / %lu (prev), hsync_width: %lu (cur) / %lu (prev)\n", totlines, cm.totlines, pcnt_frame, cm.pcnt_frame, hsync_width, cm.hsync_width);
status = (status < MODE_CHANGE) ? MODE_CHANGE : status;
// Line count reported in TVP7002 status registers is sometimes +-1 line off and may alternate with correct value. Ignore these events
if ((totlines > cm.totlines+1) || (totlines+1 < cm.totlines) || (clkcnt != cm.clkcnt) || (progressive != cm.progressive)) {
printf("totlines: %lu (cur) / %lu (prev), clkcnt: %lu (cur) / %lu (prev). totlines_tvp: %u, VSM: %u\n", totlines, cm.totlines, clkcnt, cm.clkcnt, totlines_tvp, vsyncmode);
/*if (!cm.sync_active)
act_ctr = 0;*/
stable_frames = 0;
} else if (stable_frames != STABLE_THOLD) {
stable_frames++;
if (stable_frames == STABLE_THOLD)
status = (status < MODE_CHANGE) ? MODE_CHANGE : status;
}
if (memcmp(&tc, &cm.cc, offsetof(avconfig_t, sl_mode)) || (update_cur_vm == 1))
if ((tc.pm_240p != cm.cc.pm_240p) ||
(tc.pm_384p != cm.cc.pm_384p) ||
(tc.pm_480i != cm.cc.pm_480i) ||
(tc.pm_480p != cm.cc.pm_480p) ||
(tc.pm_1080i != cm.cc.pm_1080i) ||
(tc.l2_mode != cm.cc.l2_mode) ||
(tc.l3_mode != cm.cc.l3_mode) ||
(tc.l4_mode != cm.cc.l4_mode) ||
(tc.l5_mode != cm.cc.l5_mode) ||
(tc.l5_fmt != cm.cc.l5_fmt) ||
(tc.tvp_hpll2x != cm.cc.tvp_hpll2x) ||
(tc.upsample2x != cm.cc.upsample2x) ||
(tc.vga_ilace_fix != cm.cc.vga_ilace_fix) ||
(tc.default_vic != cm.cc.default_vic) ||
(tc.clamp_offset != cm.cc.clamp_offset))
status = (status < MODE_CHANGE) ? MODE_CHANGE : status;
if ((vm_conf.si_pclk_mult > 1) && (pll_reconfig->pll_config_status.c_config_id != 5) && (vm_conf.si_pclk_mult-1 != pll_reconfig->pll_config_status.c_config_id))
if ((tc.s480p_mode != cm.cc.s480p_mode) && (video_modes[cm.id].v_total == 525))
status = (status < MODE_CHANGE) ? MODE_CHANGE : status;
if ((tc.s400p_mode != cm.cc.s400p_mode) && (video_modes[cm.id].v_total == 449))
status = (status < MODE_CHANGE) ? MODE_CHANGE : status;
if (cm.pll_config != pll_reconfig->pll_config_status.c_config_id)
status = (status < MODE_CHANGE) ? MODE_CHANGE : status;
if (update_cur_vm) {
cm.h_mult_total = (video_modes[cm.id].h_total*cm.sample_mult) + ((cm.sample_mult*video_modes[cm.id].h_total_adj*5 + 50) / 100);
tvp_setup_hpll(cm.h_mult_total, clkcnt, cm.cc.tvp_hpll2x && (video_modes[cm.id].flags & MODE_PLLDIVBY2));
cm.sample_sel = tvp_set_hpll_phase(video_modes[cm.id].sampler_phase, cm.sample_mult);
status = (status < SC_CONFIG_CHANGE) ? SC_CONFIG_CHANGE : status;
}
cm.totlines = totlines;
cm.clkcnt = clkcnt;
cm.pcnt_frame = pcnt_frame;
cm.hsync_width = hsync_width;
cm.progressive = progressive;
}
if (memcmp(&tc.sl_mode, &cm.cc.sl_mode, offsetof(avconfig_t, sync_vth) - offsetof(avconfig_t, sl_mode)))
if ((tc.sl_mode != cm.cc.sl_mode) ||
(tc.sl_type != cm.cc.sl_type) ||
(tc.sl_hybr_str != cm.cc.sl_hybr_str) ||
(tc.sl_method != cm.cc.sl_method) ||
(tc.sl_str != cm.cc.sl_str) ||
memcmp(tc.sl_cust_l_str, cm.cc.sl_cust_l_str, 5) ||
memcmp(tc.sl_cust_c_str, cm.cc.sl_cust_c_str, 6) ||
(tc.sl_altern != cm.cc.sl_altern) ||
(tc.sl_altiv != cm.cc.sl_altiv) ||
(tc.sl_id != cm.cc.sl_id) ||
(tc.h_mask != cm.cc.h_mask) ||
(tc.v_mask != cm.cc.v_mask) ||
(tc.mask_br != cm.cc.mask_br) ||
(tc.mask_color != cm.cc.mask_color) ||
(tc.ar_256col != cm.cc.ar_256col) ||
(tc.reverse_lpf != cm.cc.reverse_lpf) ||
(tc.panasonic_hack != cm.cc.panasonic_hack))
status = (status < SC_CONFIG_CHANGE) ? SC_CONFIG_CHANGE : status;
if (tc.sync_vth != cm.cc.sync_vth)
@ -408,12 +468,6 @@ status_t get_status(tvp_sync_input_t syncinput)
if (pcm1862_active && (tc.audio_gain != cm.cc.audio_gain))
pcm_set_gain(tc.audio_gain-AUDIO_GAIN_0DB);
if (pcm1862_active && (tc.audio_mono != cm.cc.audio_mono)) {
DisableAudioOutput();
pcm_set_stereo_mode(tc.audio_mono);
SetupAudio(cm.cc.tx_mode);
}
#endif
cm.cc = tc;
@ -422,254 +476,286 @@ status_t get_status(tvp_sync_input_t syncinput)
return status;
}
void update_sc_config(mode_data_t *vm_in, mode_data_t *vm_out, vm_proc_config_t *vm_conf, avconfig_t *avconfig)
void update_sc_config()
{
int i;
hv_config_reg hv_in_config = {.data=0x00000000};
hv_config2_reg hv_in_config2 = {.data=0x00000000};
hv_config3_reg hv_in_config3 = {.data=0x00000000};
hv_config_reg hv_out_config = {.data=0x00000000};
hv_config2_reg hv_out_config2 = {.data=0x00000000};
hv_config3_reg hv_out_config3 = {.data=0x00000000};
xy_config_reg xy_out_config = {.data=0x00000000};
xy_config2_reg xy_out_config2 = {.data=0x00000000};
h_config_reg h_config = {.data=0x00000000};
h_config2_reg h_config2 = {.data=0x00000000};
v_config_reg v_config = {.data=0x00000000};
misc_config_reg misc_config = {.data=0x00000000};
sl_config_reg sl_config = {.data=0x00000000};
sl_config2_reg sl_config2 = {.data=0x00000000};
sl_config3_reg sl_config3 = {.data=0x00000000};
// Set input params
hv_in_config.h_total = vm_in->timings.h_total;
hv_in_config.h_active = vm_in->timings.h_active;
hv_in_config.h_synclen = vm_in->timings.h_synclen;
hv_in_config2.h_backporch = vm_in->timings.h_backporch;
hv_in_config2.v_active = vm_in->timings.v_active;
hv_in_config3.v_synclen = vm_in->timings.v_synclen;
hv_in_config3.v_backporch = vm_in->timings.v_backporch;
hv_in_config2.interlaced = vm_in->timings.interlaced;
hv_in_config3.v_startline = vm_in->timings.v_synclen+vm_in->timings.v_backporch+12;
hv_in_config3.h_skip = vm_conf->h_skip;
hv_in_config3.h_sample_sel = vm_conf->h_sample_sel;
alt_u8 sl_no_altern = 0;
alt_u8 sl_l_overlay = 0, sl_c_overlay = 0;
alt_u32 sl_l_str_arr = 0, sl_c_str_arr = 0;
// Set output params
hv_out_config.h_total = vm_out->timings.h_total;
hv_out_config.h_active = vm_out->timings.h_active;
hv_out_config.h_synclen = vm_out->timings.h_synclen;
hv_out_config2.h_backporch = vm_out->timings.h_backporch;
hv_out_config2.v_total = vm_out->timings.v_total;
hv_out_config2.v_active = vm_out->timings.v_active;
hv_out_config3.v_synclen = vm_out->timings.v_synclen;
hv_out_config3.v_backporch = vm_out->timings.v_backporch;
hv_out_config2.interlaced = vm_out->timings.interlaced;
hv_out_config3.v_startline = vm_conf->framesync_line;
alt_u8 h_opt_scale = cm.sample_mult;
alt_u16 h_opt_startoffs = 0;
alt_u16 h_synclen = video_modes[cm.id].h_synclen;
alt_u16 h_border, h_mask;
alt_u16 v_active = video_modes[cm.id].v_active;
alt_u16 v_backporch = video_modes[cm.id].v_backporch;
xy_out_config.x_size = vm_conf->x_size;
xy_out_config.y_size = vm_conf->y_size;
xy_out_config.y_offset = vm_conf->y_offset;
xy_out_config2.x_offset = vm_conf->x_offset;
xy_out_config2.x_start_lb = vm_conf->x_start_lb;
xy_out_config2.y_start_lb = vm_conf->y_start_lb;
xy_out_config2.x_rpt = vm_conf->x_rpt;
xy_out_config2.y_rpt = vm_conf->y_rpt;
int i;
misc_config.mask_br = avconfig->mask_br;
misc_config.mask_color = avconfig->mask_color;
misc_config.reverse_lpf = avconfig->reverse_lpf;
misc_config.lm_deint_mode = 0;
misc_config.nir_even_offset = 0;
misc_config.ypbpr_cs = (avconfig->ypbpr_cs == 0) ? ((vm_in->type & VIDEO_HDTV) ? 1 : 0) : avconfig->ypbpr_cs-1;
misc_config.vip_enable = 0;
misc_config.bfi_enable = 0;
misc_config.bfi_str = 0;
// set default/custom scanline interval
sl_def_iv_y = (vm_conf->y_rpt > 0) ? vm_conf->y_rpt : 1;
sl_def_iv_x = (vm_conf->x_rpt > 0) ? vm_conf->x_rpt : sl_def_iv_y;
sl_config3.sl_iv_x = ((avconfig->sl_type == 3) && (avconfig->sl_cust_iv_x)) ? avconfig->sl_cust_iv_x : sl_def_iv_x;
sl_config3.sl_iv_y = ((avconfig->sl_type == 3) && (avconfig->sl_cust_iv_y)) ? avconfig->sl_cust_iv_y : sl_def_iv_y;
// construct custom/default scanline overlay
for (i=0; i<6; i++) {
if (avconfig->sl_type == 3) {
sl_config.sl_l_str_arr |= ((avconfig->sl_cust_l_str[i]-1)&0xf)<<(4*i);
sl_config.sl_l_overlay |= (avconfig->sl_cust_l_str[i]!=0)<<i;
// construct default scanline overlay
if ((cm.cc.sl_type == 0) || (cm.cc.sl_type == 2)) {
if (cm.cc.sl_altiv) {
sl_l_overlay = 1<<(cm.cc.sl_id);
} else {
sl_config.sl_l_str_arr |= avconfig->sl_str<<(4*i);
if ((i==5) && ((avconfig->sl_type == 0) || (avconfig->sl_type == 2))) {
sl_config.sl_l_overlay = (1<<((sl_config3.sl_iv_y+1)/2))-1;
if (avconfig->sl_id)
sl_config.sl_l_overlay <<= (sl_config3.sl_iv_y+2)/2;
switch (cm.fpga_vmultmode) {
case FPGA_V_MULTMODE_3X:
sl_l_overlay = 1<<(2*(cm.cc.sl_id));
break;
case FPGA_V_MULTMODE_4X:
sl_l_overlay = 3<<(2*(cm.cc.sl_id));
break;
case FPGA_V_MULTMODE_5X:
sl_l_overlay = 3<<(3*(cm.cc.sl_id));
break;
default: //1x, 2x
sl_l_overlay = 1<<(cm.cc.sl_id);
break;
}
}
}
for (i=0; i<10; i++) {
if (avconfig->sl_type == 3) {
if (i<8)
sl_config2.sl_c_str_arr_l |= ((avconfig->sl_cust_c_str[i]-1)&0xf)<<(4*i);
else
sl_config3.sl_c_str_arr_h |= ((avconfig->sl_cust_c_str[i]-1)&0xf)<<(4*(i-8));
sl_config3.sl_c_overlay |= (avconfig->sl_cust_c_str[i]!=0)<<i;
if ((cm.cc.sl_type == 1) || (cm.cc.sl_type == 2)) {
if (cm.sample_mult <= 4)
sl_c_overlay = (1<<((cm.sample_mult-1)*(cm.cc.sl_id)));
else
sl_c_overlay = (3<<((cm.sample_mult-2)*(cm.cc.sl_id)));
}
// construct custom scanline overlay and strength arrays
for (i=0; i<5; i++) {
if (cm.cc.sl_type == 3) {
sl_l_str_arr |= ((cm.cc.sl_cust_l_str[i]-1)&0xf)<<(4*i);
sl_l_overlay |= (cm.cc.sl_cust_l_str[i]!=0)<<i;
} else {
if (i<8)
sl_config2.sl_c_str_arr_l |= avconfig->sl_str<<(4*i);
else
sl_config3.sl_c_str_arr_h |= avconfig->sl_str<<(4*(i-8));
if ((i==9) && ((avconfig->sl_type == 1) || (avconfig->sl_type == 2)))
sl_config3.sl_c_overlay = (1<<((sl_config3.sl_iv_x+1)/2))-1;
sl_l_str_arr |= cm.cc.sl_str<<(4*i);
}
}
sl_config.sl_method = avconfig->sl_method;
sl_config.sl_altern = avconfig->sl_altern;
sl_config3.sl_hybr_str = avconfig->sl_hybr_str;
// disable scanlines if configured so
if (((avconfig->sl_mode == 1) && (!vm_conf->y_rpt)) || (avconfig->sl_mode == 0)) {
sl_config.sl_l_overlay = 0;
sl_config3.sl_c_overlay = 0;
for (i=0; i<6; i++) {
if (cm.cc.sl_type == 3) {
sl_c_str_arr |= ((cm.cc.sl_cust_c_str[i]-1)&0xf)<<(4*i);
sl_c_overlay |= (cm.cc.sl_cust_c_str[i]!=0)<<i;
} else {
sl_c_str_arr |= cm.cc.sl_str<<(4*i);
}
}
// enable/disable alternating scanlines
if ((video_modes[cm.id].flags & MODE_INTERLACED) && (cm.fpga_vmultmode))
sl_no_altern = !cm.cc.sl_altern;
// oevrride scanline mode
if (cm.cc.sl_mode == 1) { //auto
//disable scanlines
if ((cm.fpga_vmultmode==0) || (video_modes[cm.id].group == GROUP_480P)) {
sl_l_overlay = 0;
sl_c_overlay = 0;
}
} else if (cm.cc.sl_mode == 0) { //off
//disable scanlines
sl_l_overlay = 0;
sl_c_overlay = 0;
}
sc->hv_in_config = hv_in_config;
sc->hv_in_config2 = hv_in_config2;
sc->hv_in_config3 = hv_in_config3;
sc->hv_out_config = hv_out_config;
sc->hv_out_config2 = hv_out_config2;
sc->hv_out_config3 = hv_out_config3;
sc->xy_out_config = xy_out_config;
sc->xy_out_config2 = xy_out_config2;
switch (cm.target_lm) {
case MODE_L2_240x360:
h_opt_scale = 4;
break;
case MODE_L2_256_COL:
h_opt_scale = 6-2*cm.cc.ar_256col;
break;
case MODE_L3_320_COL:
h_opt_scale = 3;
break;
case MODE_L3_256_COL:
h_opt_scale = 4-cm.cc.ar_256col;
break;
case MODE_L3_240x360:
h_opt_scale = 6;
break;
case MODE_L4_256_COL:
h_opt_scale = 5-cm.cc.ar_256col;
break;
case MODE_L5_256_COL:
h_opt_scale = 6-cm.cc.ar_256col;
break;
default:
break;
}
if (cm.target_lm >= MODE_L5_GEN_4_3 && cm.cc.l5_fmt == L5FMT_1920x1080) {
v_active -= 24;
v_backporch += 12;
}
// CEA-770.3 HDTV modes use tri-level syncs which have twice the width of bi-level syncs of corresponding CEA-861 modes
if (target_type == VIDEO_HDTV)
h_synclen *= 2;
// 1920x* modes need short hsync
if (h_synclen > cm.hsync_cut)
h_synclen -= cm.hsync_cut;
else
h_synclen = 1;
h_border = (((cm.sample_mult-h_opt_scale)*video_modes[cm.id].h_active)/2);
h_mask = h_border + h_opt_scale*cm.cc.h_mask;
h_opt_startoffs = h_border + (cm.sample_mult-h_opt_scale)*(h_synclen+(alt_u16)video_modes[cm.id].h_backporch);
printf("h_border: %u, h_opt_startoffs: %u\n", h_border, h_opt_startoffs);
h_config.h_multmode = cm.fpga_hmultmode;
h_config.h_l5fmt = (cm.cc.l5_fmt!=L5FMT_1600x1200);
h_config.h_l3_240x360 = (cm.target_lm==MODE_L3_240x360);
h_config.h_synclen = (cm.sample_mult*h_synclen);
h_config.h_backporch = (cm.sample_mult*(alt_u16)video_modes[cm.id].h_backporch);
h_config.h_active = (cm.sample_mult*video_modes[cm.id].h_active);
h_config2.h_mask = h_mask;
h_config2.h_opt_scale = h_opt_scale;
h_config2.h_opt_sample_sel = cm.sample_sel;
h_config2.h_opt_sample_mult = cm.sample_mult;
h_config2.h_opt_startoff = h_opt_startoffs;
v_config.v_multmode = cm.fpga_vmultmode;
v_config.v_mask = cm.cc.v_mask;
v_config.v_synclen = video_modes[cm.id].v_synclen;
v_config.v_backporch = v_backporch;
v_config.v_active = v_active;
misc_config.rev_lpf_str = cm.cc.reverse_lpf;
misc_config.mask_br = cm.cc.mask_br;
misc_config.mask_color = cm.cc.mask_color;
misc_config.panasonic_hack = cm.cc.panasonic_hack;
sl_config.sl_l_str_arr = sl_l_str_arr;
sl_config.sl_l_overlay = sl_l_overlay;
sl_config.sl_hybr_str = cm.cc.sl_hybr_str;
sl_config.sl_method = cm.cc.sl_method;
sl_config.sl_no_altern = sl_no_altern;
sl_config2.sl_c_str_arr = sl_c_str_arr;
sl_config2.sl_c_overlay = sl_c_overlay;
sl_config2.sl_altiv = cm.cc.sl_altiv;
sc->h_config = h_config;
sc->h_config2 = h_config2;
sc->v_config = v_config;
sc->misc_config = misc_config;
sc->sl_config = sl_config;
sc->sl_config2 = sl_config2;
sc->sl_config3 = sl_config3;
}
// Configure TVP7002 and scan converter logic based on the video mode
void program_mode()
{
int retval;
alt_u8 h_syncinlen, v_syncinlen, macrovis, hdmitx_pclk_level, osd_x_size, osd_y_size;
alt_u32 h_hz, h_synclen_px, pclk_i_hz, dotclk_hz, pll_h_total;
alt_u8 h_syncinlen, v_syncinlen, hdmitx_pclk_level, osd_x_size, osd_y_size;
alt_u32 h_hz, v_hz_x100, h_synclen_px;
memset(&vmode_in, 0, sizeof(mode_data_t));
cm.tx_pixelrep = cm.hdmitx_pixr_ifr = 0;
// Mark as stable (needed after sync up to avoid unnecessary mode switch)
stable_frames = STABLE_THOLD;
vmode_in.timings.v_hz_x100 = (100*27000000UL)/cm.pcnt_frame;
h_hz = (100*27000000UL)/((100*cm.pcnt_frame*(1+!cm.progressive))/cm.totlines);
if ((cm.clkcnt != 0) && (cm.totlines != 0)) { //prevent div by 0
h_hz = TVP_EXTCLK_HZ/cm.clkcnt;
v_hz_x100 = cm.progressive ? ((100*TVP_EXTCLK_HZ)/cm.totlines)/cm.clkcnt : (2*((100*TVP_EXTCLK_HZ)/cm.totlines))/cm.clkcnt;
} else {
h_hz = 15700;
v_hz_x100 = 6000;
}
printf("\nLines: %u %c\n", (unsigned)cm.totlines, cm.progressive ? 'p' : 'i');
printf("Clocks per line: %u\n", (unsigned)cm.clkcnt);
printf("Clocks per line: %u : HS %u.%.3u kHz VS %u.%.2u Hz\n", (unsigned)cm.clkcnt, (unsigned)(h_hz/1000), (unsigned)(h_hz%1000), (unsigned)(v_hz_x100/100), (unsigned)(v_hz_x100%100));
//h_syncinlen = tvp_readreg(TVP_HSINWIDTH);
h_syncinlen = cm.hsync_width;
#ifdef DEBUG
h_syncinlen = tvp_readreg(TVP_HSINWIDTH);
v_syncinlen = tvp_readreg(TVP_VSINWIDTH);
macrovis = !!(tvp_readreg(TVP_LINECNT2) & (1<<6));
printf("Hswidth: %u Vswidth: %u Macrovision: %u\n", (unsigned)h_syncinlen, (unsigned)(v_syncinlen & 0x1F), (unsigned)macrovis);
#endif
vmode_in.timings.h_synclen = h_syncinlen;
vmode_in.timings.v_total = cm.totlines;
vmode_in.timings.interlaced = !cm.progressive;
printf("Hswidth: %u Vswidth: %u Macrovision: %u\n", (unsigned)h_syncinlen, (unsigned)(v_syncinlen & 0x1F), (unsigned)cm.macrovis);
sniprintf(row1, LCD_ROW_LEN+1, "%s %u-%c", avinput_str[cm.avinput], (unsigned)cm.totlines, cm.progressive ? 'p' : 'i');
sniprintf(row2, LCD_ROW_LEN+1, "%u.%.2ukHz %u.%.2uHz", (unsigned)(h_hz/1000), (unsigned)((h_hz%1000)/10), (unsigned)(vmode_in.timings.v_hz_x100/100), (unsigned)(vmode_in.timings.v_hz_x100%100));
sniprintf(row2, LCD_ROW_LEN+1, "%u.%.2ukHz %u.%.2uHz", (unsigned)(h_hz/1000), (unsigned)((h_hz%1000)/10), (unsigned)(v_hz_x100/100), (unsigned)(v_hz_x100%100));
ui_disp_status(1);
retval = get_pure_lm_mode(&cm.cc, &vmode_in, &vmode_out, &vm_conf);
//printf ("Get mode id with %u %u %f\n", totlines, progressive, hz);
cm.id = get_mode_id(cm.totlines, cm.progressive, v_hz_x100/100, h_syncinlen);
if (retval == -1) {
printf ("ERROR: no suitable mode preset found\n");
vm_conf.si_pclk_mult = 0;
return;
if (cm.id == -1) {
printf ("Error: no suitable mode found, defaulting to 240p\n");
cm.id = 4;
}
cm.id = retval;
vm_sel = cm.id;
// Double TVP7002 PLL sampling rate when possible to minimize jitter
while (1) {
pll_h_total = (vm_conf.h_skip+1) * vmode_in.timings.h_total + (((vm_conf.h_skip+1) * vmode_in.timings.h_total_adj * 5 + 50) / 100);
pclk_i_hz = h_hz * pll_h_total;
if ((pclk_i_hz < 25000000UL) && ((vm_conf.si_pclk_mult % 2) == 0)) {
vm_conf.h_skip = 2*(vm_conf.h_skip+1)-1;
vm_conf.si_pclk_mult /= 2;
} else {
break;
}
}
// Tweak infoframe pixel repetition indicator if passing thru horizontally multiplied mode
if ((vm_conf.y_rpt == 0) && (vm_conf.h_skip > 0))
cm.hdmitx_pixr_ifr = vm_conf.h_skip;
dotclk_hz = estimate_dotclk(&vmode_in, h_hz);
cm.pclk_o_hz = calculate_pclk(pclk_i_hz, &vmode_out, &vm_conf);
printf("H: %lu.%.2lukHz V: %u.%.2uHz\n", (h_hz+5)/1000, ((h_hz+5)%1000)/10, (vmode_in.timings.v_hz_x100/100), (vmode_in.timings.v_hz_x100%100));
printf("Estimated source dot clock: %lu.%.2luMHz\n", (dotclk_hz+5000)/1000000, ((dotclk_hz+5000)%1000000)/10000);
printf("PCLK_IN: %luHz PCLK_OUT: %luHz\n", pclk_i_hz, cm.pclk_o_hz);
cm.h_mult_total = (video_modes[cm.id].h_total*cm.sample_mult) + ((cm.sample_mult*video_modes[cm.id].h_total_adj*5 + 50) / 100);
// Trilevel sync is used with HDTV modes using composite sync
// CEA-770.3 HDTV modes use tri-level syncs which have twice the width of bi-level syncs of corresponding CEA-861 modes
if (video_modes_plm[cm.id].type & VIDEO_HDTV) {
if (video_modes[cm.id].type & VIDEO_HDTV)
target_type = (target_tvp_sync <= TVP_SOG3) ? VIDEO_HDTV : VIDEO_PC;
if (target_type == VIDEO_HDTV)
vmode_in.timings.h_synclen *= 2;
} else {
target_type = video_modes_plm[cm.id].type;
}
else
target_type = video_modes[cm.id].type;
h_synclen_px = ((alt_u32)h_syncinlen * pll_h_total) / cm.clkcnt;
h_synclen_px = ((alt_u32)h_syncinlen * (alt_u32)cm.h_mult_total) / cm.clkcnt;
printf("Mode %s selected - hsync width: %upx\n", video_modes_plm[cm.id].name, (unsigned)h_synclen_px);
printf("Mode %s selected - hsync width: %upx\n", video_modes[cm.id].name, (unsigned)h_synclen_px);
tvp_source_setup(target_type,
pll_h_total,
cm.h_mult_total,
cm.clkcnt,
0,
cm.cc.tvp_hpll2x && (video_modes[cm.id].flags & MODE_PLLDIVBY2),
(alt_u8)h_synclen_px,
(alt_8)(cm.cc.clamp_offset-SIGNED_NUMVAL_ZERO));
set_lpf(cm.cc.video_lpf);
set_csc(cm.cc.ypbpr_cs);
cm.sample_sel = tvp_set_hpll_phase(video_modes[cm.id].sampler_phase, cm.sample_mult);
set_sampler_phase(video_modes_plm[cm.id].sampler_phase);
pll_reconfig->pll_config_status.reset = (cm.fpga_vmultmode == FPGA_V_MULTMODE_1X);
pll_reconfig->pll_config_status.reset = (vm_conf.si_pclk_mult <= 1);
if (vm_conf.si_pclk_mult > 1) {
if ((vm_conf.si_pclk_mult == 2) && (pclk_i_hz > 50000000UL))
pll_reconfigure(5);
else
pll_reconfigure(vm_conf.si_pclk_mult-1);
sys_ctrl &= ~PLL_BYPASS;
} else {
sys_ctrl |= PLL_BYPASS;
switch (cm.fpga_vmultmode) {
case FPGA_V_MULTMODE_2X:
case FPGA_V_MULTMODE_5X:
cm.pll_config = PLL_CONFIG_2X_5X;
break;
case FPGA_V_MULTMODE_3X:
case FPGA_V_MULTMODE_4X:
cm.pll_config = PLL_CONFIG_3X_4X;
break;
default:
break;
}
IOWR_ALTERA_AVALON_PIO_DATA(PIO_0_BASE, sys_ctrl);
pll_reconfigure(cm.pll_config);
update_osd_size(&vmode_out);
if (cm.fpga_vmultmode == FPGA_V_MULTMODE_1X) {
osd_y_size = (video_modes[cm.id].v_active > 700) ? 1 : 0;
osd_x_size = osd_y_size + !!(video_modes[cm.id].flags & MODE_INTERLACED);
} else {
osd_x_size = 1 - cm.tx_pixelrep + (cm.fpga_hmultmode == FPGA_H_MULTMODE_OPTIMIZED_1X) + (cm.fpga_vmultmode > FPGA_V_MULTMODE_3X);
osd_y_size = 0;
}
osd->osd_config.x_size = osd_x_size;
osd->osd_config.y_size = osd_y_size;
update_sc_config(&vmode_in, &vmode_out, &vm_conf, &cm.cc);
update_sc_config();
TX_SetPixelRepetition(cm.tx_pixelrep, ((cm.cc.tx_mode!=TX_DVI) && (cm.tx_pixelrep == cm.hdmitx_pixr_ifr)) ? 1 : 0);
if (cm.pclk_o_hz > 85000000)
pclk_out = (TVP_EXTCLK_HZ/cm.clkcnt)*cm.h_mult_total*(cm.fpga_vmultmode+1);
pclk_out *= 1+cm.tx_pixelrep;
if (cm.fpga_hmultmode == FPGA_H_MULTMODE_OPTIMIZED_1X)
pclk_out /= 2;
else if (cm.fpga_hmultmode == FPGA_H_MULTMODE_ASPECTFIX)
pclk_out = (pclk_out*4)/3;
printf("PCLK_out: %luHz\n", pclk_out);
if (pclk_out > 85000000)
hdmitx_pclk_level = 1;
else if (cm.pclk_o_hz < 75000000)
else if (pclk_out < 75000000)
hdmitx_pclk_level = 0;
else
hdmitx_pclk_level = cm.hdmitx_pclk_level;
printf("PCLK level: %u, PR: %u, IPR: %u, ITC: %u\n", hdmitx_pclk_level, cm.tx_pixelrep, cm.hdmitx_pixr_ifr, cm.cc.hdmi_itc);
// Full TX initialization increases mode switch delay, use only when necessary
if (cm.cc.full_tx_setup || (cm.hdmitx_pclk_level != hdmitx_pclk_level)) {
cm.hdmitx_pclk_level = hdmitx_pclk_level;
TX_enable(cm.cc.tx_mode);
} else if (cm.cc.tx_mode!=TX_DVI) {
HDMITX_SetAVIInfoFrame(vmode_out.vic, (cm.cc.tx_mode == TX_HDMI_RGB) ? F_MODE_RGB444 : F_MODE_YUV444, 0, 0, cm.cc.hdmi_itc, cm.hdmitx_pixr_ifr);
HDMITX_SetAVIInfoFrame(cm.hdmitx_vic, (cm.cc.tx_mode == TX_HDMI_RGB) ? F_MODE_RGB444 : F_MODE_YUV444, 0, 0, cm.cc.hdmi_itc, cm.hdmitx_pixr_ifr);
#ifdef ENABLE_AUDIO
#ifdef MANUAL_CTS
SetupAudio(cm.cc.tx_mode);
@ -719,9 +805,8 @@ int init_hw()
// Reset hardware
IOWR_ALTERA_AVALON_PIO_DATA(PIO_0_BASE, AV_RESET_N|LCD_BL);
IOWR_ALTERA_AVALON_PIO_DATA(PIO_0_BASE, 0x0000);
sc->hv_in_config.data = 0x00000000;
sc->hv_in_config2.data = 0x00000000;
sc->hv_in_config3.data = 0x00000000;
sc->h_config.data = 0x00000000;
sc->v_config.data = 0x00000000;
usleep(10000);
// unreset hw
@ -785,18 +870,21 @@ int init_hw()
memcpy(&cm.cc, &tc_default, sizeof(avconfig_t));
memcpy(rc_keymap, rc_keymap_default, sizeof(rc_keymap));
// Init menu
init_menu();
// Load initconfig and profile
read_userdata(INIT_CONFIG_SLOT, 0);
read_userdata(profile_sel, 0);
// Setup test pattern
get_vmode(VMODE_480p, &vmode_in, &vmode_out, &vm_conf);
update_sc_config(&vmode_in, &vmode_out, &vm_conf, &cm.cc);
// Setup OSD
osd->osd_config.x_size = 0;
osd->osd_config.y_size = 0;
osd->osd_config.x_offset = 3;
osd->osd_config.y_offset = 3;
osd->osd_config.enable = !!osd_enable;
osd->osd_config.status_timeout = osd_status_timeout;
osd->osd_config.border_color = 1;
// init always in HDMI mode (fixes yellow screen bug)
cm.hdmitx_vic = HDMI_480p60;
TX_enable(TX_HDMI_RGB);
// Setup remote keymap
@ -806,39 +894,6 @@ int init_hw()
return 0;
}
void print_vm_stats() {
int row = 0;
if (!menu_active) {
memset((void*)osd->osd_array.data, 0, sizeof(osd_char_array));
read_userdata(profile_sel, 1);
sniprintf((char*)osd->osd_array.data[row][0], OSD_CHAR_COLS, "Mode preset:");
sniprintf((char*)osd->osd_array.data[row][1], OSD_CHAR_COLS, "%s", vmode_out.name);
sniprintf((char*)osd->osd_array.data[++row][0], OSD_CHAR_COLS, "Refresh rate:");
sniprintf((char*)osd->osd_array.data[row][1], OSD_CHAR_COLS, "%u.%.2uHz", vmode_out.timings.v_hz_x100/100, vmode_out.timings.v_hz_x100%100);
sniprintf((char*)osd->osd_array.data[++row][0], OSD_CHAR_COLS, "H/V synclen:");
sniprintf((char*)osd->osd_array.data[row][1], OSD_CHAR_COLS, "%-5u %-5u", vmode_out.timings.h_synclen, vmode_out.timings.v_synclen);
sniprintf((char*)osd->osd_array.data[++row][0], OSD_CHAR_COLS, "H/V backporch:");
sniprintf((char*)osd->osd_array.data[row][1], OSD_CHAR_COLS, "%-5u %-5u", vmode_out.timings.h_backporch, vmode_out.timings.v_backporch);
sniprintf((char*)osd->osd_array.data[++row][0], OSD_CHAR_COLS, "H/V active:");
sniprintf((char*)osd->osd_array.data[row][1], OSD_CHAR_COLS, "%-5u %-5u", vmode_out.timings.h_active, vmode_out.timings.v_active);
sniprintf((char*)osd->osd_array.data[++row][0], OSD_CHAR_COLS, "H/V total:");
sniprintf((char*)osd->osd_array.data[row][1], OSD_CHAR_COLS, "%-5u %-5u", vmode_out.timings.h_total, vmode_out.timings.v_total);
row++;
sniprintf((char*)osd->osd_array.data[++row][0], OSD_CHAR_COLS, "Profile:");
sniprintf((char*)osd->osd_array.data[row][1], OSD_CHAR_COLS, "%u: %s", profile_sel, (target_profile_name[0] == 0) ? "<empty>" : target_profile_name);
sniprintf((char*)osd->osd_array.data[++row][0], OSD_CHAR_COLS, "Firmware:");
sniprintf((char*)osd->osd_array.data[row][1], OSD_CHAR_COLS, "%u.%.2u" FW_SUFFIX1 FW_SUFFIX2 " @ " __DATE__, FW_VER_MAJOR, FW_VER_MINOR);
osd->osd_config.status_refresh = 1;
osd->osd_row_color.mask = 0;
osd->osd_sec_enable[0].mask = (1<<(row+1))-1;
osd->osd_sec_enable[1].mask = (1<<(row+1))-1;
}
}
int latency_test() {
lt_status_reg lt_status;
alt_u16 latency_ms_x100, stb_ms_x100;
@ -900,6 +955,18 @@ int latency_test() {
return 0;
}
// Enable chip outputs
void enable_outputs()
{
// enable TVP output
tvp_enable_output();
// program video mode
program_mode();
// enable and unmute TX
TX_enable(tc.tx_mode);
}
int main()
{
ths_input_t target_ths = 0;
@ -924,7 +991,7 @@ int main()
printf("### DIY VIDEO DIGITIZER / SCANCONVERTER INIT OK ###\n\n");
sniprintf(row1, LCD_ROW_LEN+1, "OSSC fw. %u.%.2u" FW_SUFFIX1 FW_SUFFIX2, FW_VER_MAJOR, FW_VER_MINOR);
#ifndef DEBUG
strncpy(row2, "2014-2023 marqs", LCD_ROW_LEN+1);
strncpy(row2, "2014-2022 marqs", LCD_ROW_LEN+1);
#else
strncpy(row2, "** DEBUG BUILD *", LCD_ROW_LEN+1);
#endif
@ -1084,7 +1151,7 @@ int main()
cm.avinput = target_input;
cm.sync_active = 0;
ths_source_sel(target_ths, (cm.cc.video_lpf > 1) ? (VIDEO_LPF_MAX-cm.cc.video_lpf) : THS_LPF_BYPASS);
tvp_powerdown();
tvp_disable_output();
#ifdef ENABLE_AUDIO
DisableAudioOutput();
if (pcm1862_active)
@ -1092,10 +1159,6 @@ int main()
#endif
tvp_source_sel(target_tvp, target_tvp_sync, target_format);
cm.clkcnt = 0; //TODO: proper invalidate
sys_ctrl &= ~VSYNC_I_TYPE;
if (target_format == FORMAT_RGBHV)
sys_ctrl |= VSYNC_I_TYPE;
IOWR_ALTERA_AVALON_PIO_DATA(PIO_0_BASE, sys_ctrl);
strncpy(row1, avinput_str[cm.avinput], LCD_ROW_LEN+1);
strncpy(row2, " NO SYNC", LCD_ROW_LEN+1);
ui_disp_status(1);
@ -1111,7 +1174,7 @@ int main()
// Check here to enable regardless of input
if (tc.tx_mode != cm.cc.tx_mode) {
HDMITX_SetAVIInfoFrame(vmode_out.vic, F_MODE_RGB444, 0, 0, 0, 0);
HDMITX_SetAVIInfoFrame(cm.hdmitx_vic, F_MODE_RGB444, 0, 0, 0, 0);
TX_enable(tc.tx_mode);
cm.cc.tx_mode = tc.tx_mode;
cm.clkcnt = 0; //TODO: proper invalidate
@ -1119,7 +1182,7 @@ int main()
if ((tc.tx_mode != TX_DVI) && (tc.hdmi_itc != cm.cc.hdmi_itc)) {
//EnableAVIInfoFrame(FALSE, NULL);
printf("setting ITC to %d\n", tc.hdmi_itc);
HDMITX_SetAVIInfoFrame(vmode_out.vic, (tc.tx_mode == TX_HDMI_RGB) ? F_MODE_RGB444 : F_MODE_YUV444, 0, 0, tc.hdmi_itc, cm.hdmitx_pixr_ifr);
HDMITX_SetAVIInfoFrame(cm.hdmitx_vic, (tc.tx_mode == TX_HDMI_RGB) ? F_MODE_RGB444 : F_MODE_YUV444, 0, 0, tc.hdmi_itc, cm.hdmitx_pixr_ifr);
cm.cc.hdmi_itc = tc.hdmi_itc;
}
if (tc.av3_alt_rgb != cm.cc.av3_alt_rgb) {
@ -1145,15 +1208,11 @@ int main()
printf("Sync up\n");
sys_ctrl |= VIDGEN_OFF;
IOWR_ALTERA_AVALON_PIO_DATA(PIO_0_BASE, sys_ctrl);
tvp_powerup();
program_mode();
#ifdef ENABLE_AUDIO
SetupAudio(cm.cc.tx_mode);
#endif
enable_outputs();
} else {
printf("Sync lost\n");
cm.clkcnt = 0; //TODO: proper invalidate
tvp_powerdown();
tvp_disable_output();
//ths_source_sel(THS_STANDBY, 0);
strncpy(row1, avinput_str[cm.avinput], LCD_ROW_LEN+1);
strncpy(row2, " NO SYNC", LCD_ROW_LEN+1);
@ -1172,7 +1231,7 @@ int main()
case SC_CONFIG_CHANGE:
if (cm.sync_active) {
printf("Scanconverter config change\n");
update_sc_config(&vmode_in, &vmode_out, &vm_conf, &cm.cc);
update_sc_config();
}
break;
default:

View File

@ -1,5 +1,5 @@
//
// Copyright (C) 2015-2023 Markus Hiienkari <mhiienka@niksula.hut.fi>
// Copyright (C) 2015-2019 Markus Hiienkari <mhiienka@niksula.hut.fi>
//
// This file is part of Open Source Scan Converter project.
//
@ -30,8 +30,6 @@
#define LT_ACTIVE (1<<15)
#define LT_ARMED (1<<14)
#define LT_MODE_OFFS 12
#define VSYNC_I_TYPE (1<<10)
#define PLL_BYPASS (1<<9)
#define REMOTE_EVENT (1<<8)
#define SD_SPI_SS_N (1<<7)
#define LCD_CS_N (1<<6)
@ -41,18 +39,37 @@
#define VIDGEN_OFF (1<<1)
#define AV_RESET_N (1<<0)
#define LT_CTRL_MASK 0xf000
#define LT_CTRL_MASK 0xf000
// HDMI_TX definitions
#define HDMITX_MODE_MASK 0x00040000
#define PLL_ACTIVECLK_MASK 0x00080000
#define VSYNC_FLAG_MASK 0x00100000
#define TX_PIXELREP_DISABLE 0
#define TX_PIXELREP_2X 1
#define TX_PIXELREP_4X 3
// FPGA macros
#define FPGA_V_MULTMODE_1X 0
#define FPGA_V_MULTMODE_2X 1
#define FPGA_V_MULTMODE_3X 2
#define FPGA_V_MULTMODE_4X 3
#define FPGA_V_MULTMODE_5X 4
#define FPGA_H_MULTMODE_FULLWIDTH 0
#define FPGA_H_MULTMODE_ASPECTFIX 1
#define FPGA_H_MULTMODE_OPTIMIZED 2
#define FPGA_H_MULTMODE_OPTIMIZED_1X 3
#define AUTO_OFF 0
#define AUTO_CURRENT_INPUT 1
#define AUTO_MAX_COUNT 100
#define AUTO_MAX_COUNT 100
#define AUTO_CURRENT_MAX_COUNT 6
#define PLL_CONFIG_VG 0
#define PLL_CONFIG_2X_5X 1
#define PLL_CONFIG_3X_4X 2
// In reverse order of importance
typedef enum {
@ -76,17 +93,24 @@ typedef struct {
//TODO: transform binary values into flags
typedef struct {
alt_u32 totlines;
alt_u32 pcnt_frame;
alt_u32 hsync_width;
alt_u32 clkcnt;
alt_u8 progressive;
alt_u8 macrovis;
alt_8 id;
alt_u8 sync_active;
alt_u8 fpga_vmultmode;
alt_u8 fpga_hmultmode;
alt_u8 tx_pixelrep;
alt_u8 hdmitx_pixr_ifr;
alt_u8 hdmitx_pclk_level;
alt_u32 pclk_o_hz;
HDMI_Video_Type hdmitx_vic;
alt_u8 sample_mult;
alt_u8 sample_sel;
alt_u8 hsync_cut;
alt_u16 h_mult_total;
mode_flags target_lm;
avinput_t avinput;
alt_u8 pll_config;
// Current configuration
avconfig_t cc;
} avmode_t;
@ -94,12 +118,9 @@ typedef struct {
void ui_disp_menu(alt_u8 osd_mode);
void ui_disp_status(alt_u8 refresh_osd_timer);
void set_sampler_phase(uint8_t sampler_phase);
int load_profile();
int save_profile();
void print_vm_stats();
int latency_test();
#endif

View File

@ -1,5 +1,5 @@
//
// Copyright (C) 2015-2023 Markus Hiienkari <mhiienka@niksula.hut.fi>
// Copyright (C) 2015-2019 Markus Hiienkari <mhiienka@niksula.hut.fi>
//
// This file is part of Open Source Scan Converter project.
//
@ -26,6 +26,7 @@
#define DEFAULT_ON 1
extern mode_data_t video_modes[], video_modes_default[];
extern alt_u8 update_cur_vm;
// Target configuration
@ -33,21 +34,24 @@ avconfig_t tc;
// Default configuration
const avconfig_t tc_default = {
.l3_mode = 1,
.pm_240p = 1,
.pm_384p = 1,
.pm_480i = 1,
.pm_1080i = 1,
.l3_mode = 1,
.clamp_offset = SIGNED_NUMVAL_ZERO,
.sl_altern = 1,
.tvp_hpll2x = DEFAULT_ON,
.sync_vth = DEFAULT_SYNC_VTH,
.linelen_tol = DEFAULT_LINELEN_TOL,
.vsync_thold = DEFAULT_VSYNC_THOLD,
.sync_lpf = DEFAULT_SYNC_LPF,
.pre_coast = DEFAULT_PRE_COAST,
.post_coast = DEFAULT_POST_COAST,
.sync_lpf = DEFAULT_SYNC_LPF,
.alc_h_filter = DEFAULT_ALC_H_FILTER,
.alc_v_filter = DEFAULT_ALC_V_FILTER,
.sl_altern = 1,
#ifdef ENABLE_AUDIO
.audio_dw_sampl = DEFAULT_ON,
.tx_mode = TX_HDMI_RGB,
.audio_gain = AUDIO_GAIN_0DB,
#endif
.col = {
.r_f_gain = DEFAULT_FINE_GAIN,
.g_f_gain = DEFAULT_FINE_GAIN,
@ -57,21 +61,20 @@ const avconfig_t tc_default = {
.b_f_off = DEFAULT_FINE_OFFSET,
.c_gain = DEFAULT_COARSE_GAIN,
},
.mask_br = 8,
#ifdef ENABLE_AUDIO
.audio_dw_sampl = DEFAULT_ON,
.audio_gain = AUDIO_GAIN_0DB,
#endif
.link_av = AV_LAST,
.clamp_offset = SIGNED_NUMVAL_ZERO,
.alc_h_filter = DEFAULT_ALC_H_FILTER,
.alc_v_filter = DEFAULT_ALC_V_FILTER,
};
int set_default_avconfig()
{
memcpy(&tc, &tc_default, sizeof(avconfig_t));
#ifndef ENABLE_AUDIO
tc.tx_mode = (IORD_ALTERA_AVALON_PIO_DATA(PIO_1_BASE) & HDMITX_MODE_MASK) ? TX_DVI : TX_HDMI_RGB;
#endif
set_default_vm_table();
memcpy(video_modes, video_modes_default, VIDEO_MODES_SIZE);
update_cur_vm = 1;
return 0;

View File

@ -1,5 +1,5 @@
//
// Copyright (C) 2015-2023 Markus Hiienkari <mhiienka@niksula.hut.fi>
// Copyright (C) 2015-2019 Markus Hiienkari <mhiienka@niksula.hut.fi>
//
// This file is part of Open Source Scan Converter project.
//
@ -21,7 +21,7 @@
#define AVCONFIG_H_
#include "alt_types.h"
#include "sysconfig.h"
#include "tvp7002.h"
#define SIGNED_NUMVAL_ZERO 128
@ -73,75 +73,60 @@ typedef enum {
} avinput_t;
typedef struct {
alt_u8 r_f_off;
alt_u8 g_f_off;
alt_u8 b_f_off;
alt_u8 r_f_gain;
alt_u8 g_f_gain;
alt_u8 b_f_gain;
alt_u8 c_gain;
} __attribute__((packed)) color_setup_t;
typedef struct {
/* P-LM mode options */
alt_u8 pm_240p;
alt_u8 pm_384p;
alt_u8 pm_480i;
alt_u8 pm_480p;
alt_u8 pm_1080i;
alt_u8 l2_mode;
alt_u8 l3_mode;
alt_u8 l4_mode;
alt_u8 l5_mode;
alt_u8 l5_fmt;
alt_u8 s480p_mode;
alt_u8 s400p_mode;
alt_u8 upsample2x;
alt_u8 ar_256col;
alt_u8 default_vic;
alt_u8 clamp_offset;
/* Postprocessing settings */
alt_u8 sl_mode;
alt_u8 sl_type;
alt_u8 sl_hybr_str;
alt_u8 sl_method;
alt_u8 sl_altern;
alt_u8 sl_altiv;
alt_u8 sl_str;
alt_u8 sl_id;
alt_u8 sl_cust_l_str[5];
alt_u8 sl_cust_c_str[6];
alt_u8 sl_cust_iv_x;
alt_u8 sl_cust_iv_y;
alt_u8 linemult_target;
alt_u8 l2_mode;
alt_u8 l3_mode;
alt_u8 l4_mode;
alt_u8 l5_mode;
alt_u8 l5_fmt;
alt_u8 pm_240p;
alt_u8 pm_384p;
alt_u8 pm_480i;
alt_u8 pm_480p;
alt_u8 pm_1080i;
alt_u8 ar_256col;
alt_u8 h_mask;
alt_u8 v_mask;
alt_u8 mask_br;
alt_u8 mask_color;
alt_u8 reverse_lpf;
/* AFE settings */
alt_u8 tx_mode;
alt_u8 hdmi_itc;
alt_u8 s480p_mode;
alt_u8 s400p_mode;
alt_u8 tvp_hpll2x;
alt_u8 upsample2x;
alt_u8 ypbpr_cs;
alt_u8 sync_vth;
alt_u8 linelen_tol;
alt_u8 vsync_thold;
alt_u8 pre_coast;
alt_u8 post_coast;
alt_u8 ypbpr_cs;
alt_u8 video_lpf;
alt_u8 sync_lpf;
alt_u8 stc_lpf;
alt_u8 alc_h_filter;
alt_u8 alc_v_filter;
color_setup_t col;
/* Audio settings */
alt_u8 video_lpf;
alt_u8 pre_coast;
alt_u8 post_coast;
alt_u8 full_tx_setup;
alt_u8 vga_ilace_fix;
alt_u8 av3_alt_rgb;
alt_u8 panasonic_hack;
alt_u8 reverse_lpf;
alt_u8 audio_dw_sampl;
alt_u8 audio_swap_lr;
alt_u8 audio_gain;
alt_u8 audio_mono;
/* TX / extra settings */
alt_u8 tx_mode;
alt_u8 hdmi_itc;
alt_u8 full_tx_setup;
alt_u8 av3_alt_rgb;
alt_u8 default_vic;
alt_u8 clamp_offset;
alt_u8 alc_h_filter;
alt_u8 alc_v_filter;
color_setup_t col;
avinput_t link_av;
} __attribute__((packed)) avconfig_t;

View File

@ -1,5 +1,5 @@
//
// Copyright (C) 2015-2023 Markus Hiienkari <mhiienka@niksula.hut.fi>
// Copyright (C) 2015-2019 Markus Hiienkari <mhiienka@niksula.hut.fi>
//
// This file is part of Open Source Scan Converter project.
//
@ -38,24 +38,25 @@ const alt_u16 rc_keymap_default[REMOTE_MAX_KEYS] = {0x3E29, 0x3EA9, 0x3E69, 0x3E
alt_u16 rc_keymap[REMOTE_MAX_KEYS];
extern char menu_row1[LCD_ROW_LEN+1], menu_row2[LCD_ROW_LEN+1];
extern mode_data_t video_modes_plm[];
extern mode_data_t video_modes[];
extern avmode_t cm;
extern avconfig_t tc;
extern avinput_t target_input;
extern alt_u8 menu_active;
extern alt_u32 sys_ctrl;
extern alt_u16 sys_ctrl;
extern alt_u16 tc_sampler_phase;
extern alt_u8 profile_sel, profile_sel_menu;
extern alt_u8 lcd_bl_timeout;
extern alt_u8 vm_edit;
extern alt_u8 update_cur_vm, vm_edit;
extern volatile sc_regs *sc;
extern volatile osd_regs *osd;
extern menu_t menu_scanlines, menu_advtiming;
extern char target_profile_name[PROFILE_NAME_LEN+1];
alt_u32 remote_code;
alt_u8 remote_rpt, remote_rpt_prev;
alt_u32 btn_code, btn_code_prev;
alt_u8 phase_hotkey_enable;
void setup_rc()
{
@ -121,9 +122,13 @@ int parse_control()
alt_u8 pt_only = 0;
avinput_t man_target_input = AV_LAST;
sc_status_reg sc_status;
sc_status2_reg sc_status2;
alt_u32 fpga_v_hz_x100;
// one for each video_group
alt_u8* pmcfg_ptr[] = { &pt_only, &tc.pm_240p, &tc.pm_240p, &tc.pm_384p, &tc.pm_480i, &tc.pm_480i, &tc.pm_480p, &tc.pm_480p, &pt_only, &tc.pm_1080i, &pt_only };
alt_u8 valid_pm[] = { 0x1, 0x1f, 0x1f, 0x7, 0xf, 0xf, 0x3, 0x3, 0x1, 0x3, 0x1 };
alt_u8* pmcfg_ptr[] = { &pt_only, &tc.pm_240p, &tc.pm_384p, &tc.pm_480i, &tc.pm_480p, &tc.pm_480p, &tc.pm_1080i };
alt_u8 valid_pm[] = { 0x1, 0x1f, 0x3, 0xf, 0x3, 0x3, 0x3 };
avinput_t next_input = (cm.avinput == AV3_YPBPR) ? AV1_RGBs : (cm.avinput+1);
@ -164,7 +169,34 @@ int parse_control()
break;
case RC_INFO:
print_vm_stats();
sc_status = sc->sc_status;
sc_status2 = sc->sc_status2;
fpga_v_hz_x100 = (100*TVP_EXTCLK_HZ)/sc_status2.pcnt_frame;
if (!menu_active) {
memset((void*)osd->osd_array.data, 0, sizeof(osd_char_array));
read_userdata(profile_sel, 1);
sniprintf((char*)osd->osd_array.data[0][0], OSD_CHAR_COLS, "Profile:");
sniprintf((char*)osd->osd_array.data[0][1], OSD_CHAR_COLS, "%u: %s", profile_sel, (target_profile_name[0] == 0) ? "<empty>" : target_profile_name);
if (cm.sync_active) {
sniprintf((char*)osd->osd_array.data[1][0], OSD_CHAR_COLS, "Mode preset:");
sniprintf((char*)osd->osd_array.data[1][1], OSD_CHAR_COLS, "%s", video_modes[cm.id].name);
sniprintf((char*)osd->osd_array.data[2][0], OSD_CHAR_COLS, "Imode (FPGA):");
sniprintf((char*)osd->osd_array.data[2][1], OSD_CHAR_COLS, "%lu-%c%c %lu.%.2luHz", (unsigned long)((sc_status.vmax+1)<<sc_status.interlace_flag)+sc_status.interlace_flag,
sc_status.interlace_flag ? 'i' : 'p',
sc_status.fpga_vsyncgen ? '*' : ' ',
fpga_v_hz_x100/100,
fpga_v_hz_x100%100);
sniprintf((char*)osd->osd_array.data[3][0], OSD_CHAR_COLS, "Ccnt / frame:");
sniprintf((char*)osd->osd_array.data[3][1], OSD_CHAR_COLS, "%lu", (unsigned long)sc_status2.pcnt_frame);
}
sniprintf((char*)osd->osd_array.data[4][0], OSD_CHAR_COLS, "Firmware:");
sniprintf((char*)osd->osd_array.data[4][1], OSD_CHAR_COLS, "%u.%.2u" FW_SUFFIX1 FW_SUFFIX2, FW_VER_MAJOR, FW_VER_MINOR);
osd->osd_config.status_refresh = 1;
osd->osd_row_color.mask = 0;
osd->osd_sec_enable[0].mask = 0x1f;
osd->osd_sec_enable[1].mask = 0x1f;
}
break;
case RC_LCDBL:
sys_ctrl ^= LCD_BL;
@ -185,8 +217,8 @@ int parse_control()
case RC_SL_TYPE:
tc.sl_type = (tc.sl_type < SL_TYPE_MAX) ? (tc.sl_type + 1) : 0;
if (!menu_active) {
strncpy((char*)osd->osd_array.data[0][0], menu_scanlines.items[5].name, OSD_CHAR_COLS);
strncpy((char*)osd->osd_array.data[1][0], menu_scanlines.items[5].sel.setting_str[tc.sl_type], OSD_CHAR_COLS);
strncpy((char*)osd->osd_array.data[0][0], menu_scanlines.items[7].name, OSD_CHAR_COLS);
strncpy((char*)osd->osd_array.data[1][0], menu_scanlines.items[7].sel.setting_str[tc.sl_type], OSD_CHAR_COLS);
osd->osd_config.status_refresh = 1;
osd->osd_row_color.mask = 0;
osd->osd_sec_enable[0].mask = 3;
@ -227,14 +259,14 @@ int parse_control()
break;
}
if (video_modes_plm[cm.id].group > GROUP_1080P) {
if (video_modes[cm.id].group > GROUP_1080I) {
printf("WARNING: Corrupted mode (id %d)\n", cm.id);
break;
}
if (i <= RC_BTN5) {
if ((1<<i) & valid_pm[video_modes_plm[cm.id].group]) {
*pmcfg_ptr[video_modes_plm[cm.id].group] = i;
if ((1<<i) & valid_pm[video_modes[cm.id].group]) {
*pmcfg_ptr[video_modes[cm.id].group] = i;
} else {
sniprintf(menu_row2, LCD_ROW_LEN+1, "%ux unsupported", i+1);
ui_disp_menu(1);
@ -253,28 +285,25 @@ int parse_control()
break;
case RC_PHASE_MINUS:
case RC_PHASE_PLUS:
if (phase_hotkey_enable) {
if (i == RC_PHASE_MINUS)
video_modes_plm[cm.id].sampler_phase = video_modes_plm[cm.id].sampler_phase ? (video_modes_plm[cm.id].sampler_phase - 1) : SAMPLER_PHASE_MAX;
else
video_modes_plm[cm.id].sampler_phase = (video_modes_plm[cm.id].sampler_phase < SAMPLER_PHASE_MAX) ? (video_modes_plm[cm.id].sampler_phase + 1) : 0;
if (i == RC_PHASE_MINUS)
video_modes[cm.id].sampler_phase = video_modes[cm.id].sampler_phase ? (video_modes[cm.id].sampler_phase - 1) : SAMPLER_PHASE_MAX;
else
video_modes[cm.id].sampler_phase = (video_modes[cm.id].sampler_phase < SAMPLER_PHASE_MAX) ? (video_modes[cm.id].sampler_phase + 1) : 0;
if (cm.id == vm_edit)
tc_sampler_phase = video_modes_plm[cm.id].sampler_phase;
update_cur_vm = 1;
if (cm.id == vm_edit)
tc_sampler_phase = video_modes[vm_edit].sampler_phase;
set_sampler_phase(video_modes_plm[cm.id].sampler_phase);
if (!menu_active) {
strncpy((char*)osd->osd_array.data[0][0], menu_advtiming.items[8].name, OSD_CHAR_COLS);
sampler_phase_disp(video_modes_plm[cm.id].sampler_phase);
strncpy((char*)osd->osd_array.data[1][0], menu_row2, OSD_CHAR_COLS);
osd->osd_config.status_refresh = 1;
osd->osd_row_color.mask = 0;
osd->osd_sec_enable[0].mask = 3;
osd->osd_sec_enable[1].mask = 0;
} else if (get_current_menunavi()->m == &menu_advtiming) {
render_osd_page();
}
if (!menu_active) {
strncpy((char*)osd->osd_array.data[0][0], menu_advtiming.items[8].name, OSD_CHAR_COLS);
sniprintf(menu_row2, LCD_ROW_LEN+1, "%d deg", (video_modes[cm.id].sampler_phase*1125)/100);
strncpy((char*)osd->osd_array.data[1][0], menu_row2, OSD_CHAR_COLS);
osd->osd_config.status_refresh = 1;
osd->osd_row_color.mask = 0;
osd->osd_sec_enable[0].mask = 3;
osd->osd_sec_enable[1].mask = 0;
} else if (get_current_menunavi()->m == &menu_advtiming) {
render_osd_page();
}
break;
case RC_PROF_HOTKEY:

View File

@ -1,5 +1,5 @@
//
// Copyright (C) 2015-2023 Markus Hiienkari <mhiienka@niksula.hut.fi>
// Copyright (C) 2015-2018 Markus Hiienkari <mhiienka@niksula.hut.fi>
//
// This file is part of Open Source Scan Converter project.
//
@ -33,7 +33,7 @@
extern char menu_row1[LCD_ROW_LEN+1], menu_row2[LCD_ROW_LEN+1];
extern alt_u16 rc_keymap[REMOTE_MAX_KEYS];
extern SD_DEV sdcard_dev;
extern alt_u32 sys_ctrl;
extern alt_u16 sys_ctrl;
static int check_fw_header(alt_u8 *databuf, fw_hdr *hdr)
{
@ -146,7 +146,7 @@ int fw_update()
}
//disable video output
tvp_powerdown();
tvp_disable_output();
sys_ctrl |= VIDGEN_OFF;
IOWR_ALTERA_AVALON_PIO_DATA(PIO_0_BASE, sys_ctrl);
usleep(10000);

View File

@ -1,5 +1,5 @@
//
// Copyright (C) 2015-2023 Markus Hiienkari <mhiienka@niksula.hut.fi>
// Copyright (C) 2015-2022 Markus Hiienkari <mhiienka@niksula.hut.fi>
//
// This file is part of Open Source Scan Converter project.
//
@ -23,14 +23,14 @@
#include "alt_types.h"
#include "sysconfig.h"
#define FW_VER_MAJOR 1
#define FW_VER_MINOR 04
#define FW_VER_MAJOR 0
#define FW_VER_MINOR 90
#define PROFILE_VER_MAJOR 1
#define PROFILE_VER_MINOR 03
#define PROFILE_VER_MAJOR 0
#define PROFILE_VER_MINOR 88
#define INITCFG_VER_MAJOR 1
#define INITCFG_VER_MINOR 00
#define INITCFG_VER_MAJOR 0
#define INITCFG_VER_MINOR 85
#ifdef ENABLE_AUDIO
#define FW_SUFFIX1 "a"

View File

@ -1,5 +1,5 @@
//
// Copyright (C) 2015-2023 Markus Hiienkari <mhiienka@niksula.hut.fi>
// Copyright (C) 2015-2019 Markus Hiienkari <mhiienka@niksula.hut.fi>
//
// This file is part of Open Source Scan Converter project.
//
@ -32,19 +32,17 @@
extern char row1[LCD_ROW_LEN+1], row2[LCD_ROW_LEN+1], menu_row1[LCD_ROW_LEN+1], menu_row2[LCD_ROW_LEN+1];
extern avmode_t cm;
extern avconfig_t tc;
extern mode_data_t video_modes_plm[];
extern mode_data_t video_modes[];
extern alt_u32 remote_code;
extern alt_u16 rc_keymap[REMOTE_MAX_KEYS];
extern alt_u8 vm_sel, profile_sel_menu, lt_sel, def_input, profile_link, lcd_bl_timeout;
extern alt_u8 auto_input, auto_av1_ypbpr, auto_av2_ypbpr, auto_av3_ypbpr;
extern alt_u8 update_cur_vm;
extern alt_u8 osd_enable, osd_status_timeout, phase_hotkey_enable;
extern uint8_t sl_def_iv_x, sl_def_iv_y;
extern alt_u8 osd_enable, osd_status_timeout;
extern char target_profile_name[PROFILE_NAME_LEN+1];
extern volatile osd_regs *osd;
extern const int num_video_modes_plm;
alt_u16 tc_h_samplerate, tc_h_samplerate_adj, tc_h_synclen, tc_h_bporch, tc_h_active, tc_v_synclen, tc_v_bporch, tc_v_active, tc_sampler_phase, tc_h_mask, tc_v_mask;
alt_u16 tc_h_samplerate, tc_h_samplerate_adj, tc_h_synclen, tc_h_bporch, tc_h_active, tc_v_synclen, tc_v_bporch, tc_v_active, tc_sampler_phase;
alt_u8 menu_active;
alt_u8 vm_sel, vm_edit;
@ -60,7 +58,7 @@ static const char *l2l4l5_mode_desc[] = { LNG("Generic 4:3","ジェネリッ
static const char *l5_fmt_desc[] = { "1920x1080", "1600x1200", "1920x1200" };
static const char *pm_240p_desc[] = { LNG("Passthru","パススルー"), "Line2x", "Line3x", "Line4x", "Line5x" };
static const char *pm_480i_desc[] = { LNG("Passthru","パススルー"), "Line2x (bob)", "Line3x (laced)", "Line4x (bob)" };
static const char *pm_384p_desc[] = { LNG("Passthru","パススルー"), "Line2x", "Line3x Generic", "Line2x 240x360", "Line3x 240x360" };
static const char *pm_384p_desc[] = { LNG("Passthru","パススルー"), "Line2x", "Line2x 240x360", "Line3x 240x360", "Line3x Generic" };
static const char *pm_480p_desc[] = { LNG("Passthru","パススルー"), "Line2x" };
static const char *pm_1080i_desc[] = { LNG("Passthru","パススルー"), "Line2x (bob)" };
static const char *ar_256col_desc[] = { "Pseudo 4:3 DAR", "1:1 PAR" };
@ -84,8 +82,6 @@ static void intclks_to_time_disp(alt_u8 v) { sniprintf(menu_row2, LCD_ROW_LEN+1,
static void extclks_to_time_disp(alt_u8 v) { sniprintf(menu_row2, LCD_ROW_LEN+1, "%u.%.2u us", (unsigned)(((1000000U*v)/(TVP_EXTCLK_HZ/1000))/1000), (unsigned)((((1000000U*v)/(TVP_EXTCLK_HZ/1000))%1000)/10)); }
static void sl_str_disp(alt_u8 v) { sniprintf(menu_row2, LCD_ROW_LEN+1, "%u%%", ((v+1)*625)/100); }
static void sl_cust_str_disp(alt_u8 v) { sniprintf(menu_row2, LCD_ROW_LEN+1, "%u%%", ((v)*625)/100); }
static void sl_cust_iv_x_disp(uint8_t v) { sniprintf(menu_row2, LCD_ROW_LEN+1, "%s%u%s", (v ? "" : "Auto ("), (v ? v : sl_def_iv_x)+1, (v ? "" : ")")); }
static void sl_cust_iv_y_disp(uint8_t v) { sniprintf(menu_row2, LCD_ROW_LEN+1, "%s%u%s", (v ? "" : "Auto ("), (v ? v : sl_def_iv_y)+1, (v ? "" : ")")); }
static void sl_hybr_str_disp(alt_u8 v) { sniprintf(menu_row2, LCD_ROW_LEN+1, "%u%%", (v*625)/100); }
static void lines_disp(alt_u8 v) { sniprintf(menu_row2, LCD_ROW_LEN+1, LNG("%u lines","%u ライン"), v); }
static void pixels_disp(alt_u8 v) { sniprintf(menu_row2, LCD_ROW_LEN+1, LNG("%u pixels","%u ドット"), v); }
@ -93,15 +89,14 @@ static void value_disp(alt_u8 v) { sniprintf(menu_row2, LCD_ROW_LEN+1, "%u", v);
static void signed_disp(alt_u8 v) { sniprintf(menu_row2, LCD_ROW_LEN+1, "%d", (alt_8)(v-SIGNED_NUMVAL_ZERO)); }
static void lt_disp(alt_u8 v) { strncpy(menu_row2, lt_desc[v], LCD_ROW_LEN+1); }
static void aud_db_disp(alt_u8 v) { sniprintf(menu_row2, LCD_ROW_LEN+1, "%d dB", ((alt_8)v-AUDIO_GAIN_0DB)); }
static void vm_display_name (alt_u8 v) { strncpy(menu_row2, video_modes_plm[v].name, LCD_ROW_LEN+1); }
static void vm_display_name (alt_u8 v) { strncpy(menu_row2, video_modes[v].name, LCD_ROW_LEN+1); }
static void link_av_desc (avinput_t v) { strncpy(menu_row2, v == AV_LAST ? "No link" : avinput_str[v], LCD_ROW_LEN+1); }
static void profile_disp(alt_u8 v) { read_userdata(v, 1); sniprintf(menu_row2, LCD_ROW_LEN+1, "%u: %s", v, (target_profile_name[0] == 0) ? "<empty>" : target_profile_name); }
static void alc_v_filter_disp(alt_u8 v) { sniprintf(menu_row2, LCD_ROW_LEN+1, LNG("%u lines","%u ライン"), (1<<v)); }
static void alc_h_filter_disp(alt_u8 v) { sniprintf(menu_row2, LCD_ROW_LEN+1, LNG("%u pixels","%u ドット"), (1<<(v+1))); }
void sampler_phase_disp(alt_u8 v) { sniprintf(menu_row2, LCD_ROW_LEN+1, "%d deg", (v*11250)/1000); }
//static void coarse_gain_disp(alt_u8 v) { sniprintf(menu_row2, LCD_ROW_LEN+1, "%u.%u", ((v*10)+50)/100, (((v*10)+50)%100)/10); }
static arg_info_t vm_arg_info = {&vm_sel, 0, vm_display_name};
static const arg_info_t vm_arg_info = {&vm_sel, VIDEO_MODES_CNT-1, vm_display_name};
static const arg_info_t profile_arg_info = {&profile_sel_menu, MAX_PROFILE, profile_disp};
static const arg_info_t lt_arg_info = {&lt_sel, (sizeof(lt_desc)/sizeof(char*))-1, lt_disp};
@ -111,18 +106,14 @@ MENU(menu_advtiming, P99_PROTECT({ \
{ "H. s.rate frac", OPT_AVCONFIG_NUMVAL_U16,{ .num_u16 = { &tc_h_samplerate_adj, 0, H_TOTAL_ADJ_MAX, vm_tweak } } },
{ LNG("H. synclen","H. ドウキナガサ"), OPT_AVCONFIG_NUMVAL_U16,{ .num_u16 = { &tc_h_synclen, H_SYNCLEN_MIN, H_SYNCLEN_MAX, vm_tweak } } },
{ LNG("H. backporch","H. バックポーチ"), OPT_AVCONFIG_NUMVAL_U16,{ .num_u16 = { &tc_h_bporch, H_BPORCH_MIN, H_BPORCH_MAX, vm_tweak } } },
{ LNG("H. active","H. アクティブ"), OPT_AVCONFIG_NUMVAL_U16,{ .num_u16 = { &tc_h_active, H_ACTIVE_MIN, H_ACTIVE_SMP_MAX, vm_tweak } } },
{ LNG("H. active","H. アクティブ"), OPT_AVCONFIG_NUMVAL_U16,{ .num_u16 = { &tc_h_active, H_ACTIVE_MIN, H_ACTIVE_MAX, vm_tweak } } },
{ LNG("V. synclen","V. ドウキナガサ"), OPT_AVCONFIG_NUMVAL_U16,{ .num_u16 = { &tc_v_synclen, V_SYNCLEN_MIN, V_SYNCLEN_MAX, vm_tweak } } },
{ LNG("V. backporch","V. バックポーチ"), OPT_AVCONFIG_NUMVAL_U16,{ .num_u16 = { &tc_v_bporch, V_BPORCH_MIN, V_BPORCH_MAX, vm_tweak } } },
{ LNG("V. active","V. アクティブ"), OPT_AVCONFIG_NUMVAL_U16,{ .num_u16 = { &tc_v_active, V_ACTIVE_MIN, V_ACTIVE_MAX, vm_tweak } } },
{ "H. mask", OPT_AVCONFIG_NUMVAL_U16,{ .num_u16 = { &tc_h_mask, 0, H_MASK_MAX, vm_tweak } } },
{ "V. mask", OPT_AVCONFIG_NUMVAL_U16,{ .num_u16 = { &tc_v_mask, 0, V_MASK_MAX, vm_tweak } } },
{ LNG("Sampling phase","サンプリングフェーズ"), OPT_AVCONFIG_NUMVAL_U16, { .num_u16 = { &tc_sampler_phase, 0, SAMPLER_PHASE_MAX, vm_tweak } } },
}))
MENU(menu_cust_sl, P99_PROTECT({ \
{ "H interval", OPT_AVCONFIG_NUMVALUE, { .num = { &tc.sl_cust_iv_x, OPT_NOWRAP, 0, 4, sl_cust_iv_x_disp } } },
{ "V interval", OPT_AVCONFIG_NUMVALUE, { .num = { &tc.sl_cust_iv_y, OPT_NOWRAP, 0, 5, sl_cust_iv_y_disp } } },
{ "Sub-line 1 str", OPT_AVCONFIG_NUMVALUE, { .num = { &tc.sl_cust_l_str[0], OPT_NOWRAP, 0, SCANLINESTR_MAX+1, sl_cust_str_disp } } },
{ "Sub-line 2 str", OPT_AVCONFIG_NUMVALUE, { .num = { &tc.sl_cust_l_str[1], OPT_NOWRAP, 0, SCANLINESTR_MAX+1, sl_cust_str_disp } } },
{ "Sub-line 3 str", OPT_AVCONFIG_NUMVALUE, { .num = { &tc.sl_cust_l_str[2], OPT_NOWRAP, 0, SCANLINESTR_MAX+1, sl_cust_str_disp } } },
@ -139,7 +130,6 @@ MENU(menu_cust_sl, P99_PROTECT({ \
MENU(menu_vinputproc, P99_PROTECT({ \
{ LNG("Video LPF","ビデオ LPF"), OPT_AVCONFIG_SELECTION, { .sel = { &tc.video_lpf, OPT_WRAP, SETTING_ITEM(video_lpf_desc) } } },
{ LNG("Reverse LPF","ギャクLPF"), OPT_AVCONFIG_NUMVALUE, { .num = { &tc.reverse_lpf, OPT_NOWRAP, 0, REVERSE_LPF_MAX, value_disp } } },
{ LNG("YPbPr in ColSpa","イロクウカンニYPbPr"), OPT_AVCONFIG_SELECTION, { .sel = { &tc.ypbpr_cs, OPT_WRAP, SETTING_ITEM(ypbpr_cs_desc) } } },
{ LNG("R/Pr offset","R/Pr オフセット"), OPT_AVCONFIG_NUMVALUE, { .num = { &tc.col.r_f_off, OPT_NOWRAP, 0, 0xFF, value_disp } } },
{ LNG("G/Y offset","G/Y オフセット"), OPT_AVCONFIG_NUMVALUE, { .num = { &tc.col.g_f_off, OPT_NOWRAP, 0, 0xFF, value_disp } } },
@ -156,6 +146,7 @@ MENU(menu_vinputproc, P99_PROTECT({ \
MENU(menu_sampling, P99_PROTECT({ \
{ LNG("480p in sampler","サンプラーデ480p"), OPT_AVCONFIG_SELECTION, { .sel = { &tc.s480p_mode, OPT_WRAP, SETTING_ITEM(s480p_mode_desc) } } },
{ LNG("400p in sampler","サンプラーデ400p"), OPT_AVCONFIG_SELECTION, { .sel = { &tc.s400p_mode, OPT_WRAP, SETTING_ITEM(s400p_mode_desc) } } },
{ LNG("Allow TVP HPLL2x","TVP HPLL2xキョヨウ"), OPT_AVCONFIG_SELECTION, { .sel = { &tc.tvp_hpll2x, OPT_WRAP, SETTING_ITEM(off_on_desc) } } },
{ LNG("Allow upsample2x","アップサンプル2xキョヨウ"), OPT_AVCONFIG_SELECTION, { .sel = { &tc.upsample2x, OPT_WRAP, SETTING_ITEM(off_on_desc) } } },
{ LNG("<Adv. timing >","<カクシュタイミング>"), OPT_SUBMENU, { .sub = { &menu_advtiming, &vm_arg_info, vm_select } } },
}))
@ -193,27 +184,32 @@ MENU(menu_scanlines, P99_PROTECT({ \
{ "Sl. method", OPT_AVCONFIG_SELECTION, { .sel = { &tc.sl_method, OPT_WRAP, SETTING_ITEM(sl_method_desc) } } },
{ "Sl. alternating", OPT_AVCONFIG_SELECTION, { .sel = { &tc.sl_altern, OPT_WRAP, SETTING_ITEM(off_on_desc) } } },
{ LNG("Sl. alignment","スキャンラインポジション"), OPT_AVCONFIG_SELECTION, { .sel = { &tc.sl_id, OPT_WRAP, SETTING_ITEM(sl_id_desc) } } },
{ "Sl. alt interval", OPT_AVCONFIG_SELECTION, { .sel = { &tc.sl_altiv, OPT_WRAP, SETTING_ITEM(off_on_desc) } } },
{ LNG("Sl. type","スキャンラインルイ"), OPT_AVCONFIG_SELECTION, { .sel = { &tc.sl_type, OPT_WRAP, SETTING_ITEM(sl_type_desc) } } },
{ "< Custom Sl. >", OPT_SUBMENU, { .sub = { &menu_cust_sl, NULL, NULL } } },
}))
MENU(menu_postproc, P99_PROTECT({ \
{ LNG("Horizontal mask","スイヘイマスク"), OPT_AVCONFIG_NUMVALUE, { .num = { &tc.h_mask, OPT_NOWRAP, 0, H_MASK_MAX, pixels_disp } } },
{ LNG("Vertical mask","スイチョクマスク"), OPT_AVCONFIG_NUMVALUE, { .num = { &tc.v_mask, OPT_NOWRAP, 0, V_MASK_MAX, pixels_disp } } },
{ "Mask color", OPT_AVCONFIG_SELECTION, { .sel = { &tc.mask_color, OPT_NOWRAP, SETTING_ITEM(mask_color_desc) } } },
{ LNG("Mask brightness","マスクアカルサ"), OPT_AVCONFIG_NUMVALUE, { .num = { &tc.mask_br, OPT_NOWRAP, 0, HV_MASK_MAX_BR, value_disp } } },
//{ LNG("<DIY lat. test>","DIYチエンテスト"), OPT_FUNC_CALL, { .fun = { latency_test, &lt_arg_info } } },
{ LNG("Reverse LPF","ギャクLPF"), OPT_AVCONFIG_NUMVALUE, { .num = { &tc.reverse_lpf, OPT_NOWRAP, 0, REVERSE_LPF_MAX, value_disp } } },
{ LNG("<DIY lat. test>","DIYチエンテスト"), OPT_FUNC_CALL, { .fun = { latency_test, &lt_arg_info } } },
}))
MENU(menu_compatibility, P99_PROTECT({ \
{ LNG("Full TX setup","フルTXセットアップ"), OPT_AVCONFIG_SELECTION, { .sel = { &tc.full_tx_setup, OPT_WRAP, SETTING_ITEM(off_on_desc) } } },
{ LNG("AV3 interlacefix","AV3インターレースシュウセイ"), OPT_AVCONFIG_SELECTION, { .sel = { &tc.vga_ilace_fix, OPT_WRAP, SETTING_ITEM(off_on_desc) } } },
{ "AV3 use alt. RGB", OPT_AVCONFIG_SELECTION, { .sel = { &tc.av3_alt_rgb, OPT_WRAP, SETTING_ITEM(av3_alt_rgb_desc) } } },
{ "Default HDMI VIC", OPT_AVCONFIG_NUMVALUE, { .num = { &tc.default_vic, OPT_NOWRAP, 0, HDMI_1080p50, value_disp } } },
{ "Panasonic hack", OPT_AVCONFIG_SELECTION, { .sel = { &tc.panasonic_hack, OPT_WRAP, SETTING_ITEM(off_on_desc) } } },
}))
#ifdef ENABLE_AUDIO
MENU(menu_audio, P99_PROTECT({ \
{ LNG("Down-sampling","ダウンサンプリング"), OPT_AVCONFIG_SELECTION, { .sel = { &tc.audio_dw_sampl, OPT_WRAP, SETTING_ITEM(audio_dw_sampl_desc) } } },
{ LNG("Swap left/right","ヒダリ/ミギスワップ"), OPT_AVCONFIG_SELECTION, { .sel = { &tc.audio_swap_lr, OPT_WRAP, SETTING_ITEM(off_on_desc) } } },
{ "Mono mode", OPT_AVCONFIG_SELECTION, { .sel = { &tc.audio_mono, OPT_WRAP, SETTING_ITEM(off_on_desc) } } },
{ "Pre-ADC gain", OPT_AVCONFIG_NUMVALUE, { .num = { &tc.audio_gain, OPT_NOWRAP, 0, AUDIO_GAIN_MAX, aud_db_disp } } },
}))
#define AUDIO_MENU { LNG("Audio options >","オーディオオプション >"), OPT_SUBMENU, { .sub = { &menu_audio, NULL, NULL } } },
@ -222,6 +218,9 @@ MENU(menu_audio, P99_PROTECT({ \
#endif
MENU(menu_settings, P99_PROTECT({ \
{ LNG("<Load profile >","<プロファイルロード >"), OPT_FUNC_CALL, { .fun = { load_profile, &profile_arg_info } } },
{ LNG("<Save profile >","<プロファイルセーブ >"), OPT_FUNC_CALL, { .fun = { save_profile, &profile_arg_info } } },
{ LNG("<Reset settings>","<セッテイヲショキカ >"), OPT_FUNC_CALL, { .fun = { set_default_avconfig, NULL } } },
{ LNG("Link prof->input","Link prof->input"), OPT_AVCONFIG_NUMVALUE, { .num = { &tc.link_av, OPT_WRAP, AV1_RGBs, AV_LAST, link_av_desc } } },
{ LNG("Link input->prof","Link input->prof"), OPT_AVCONFIG_SELECTION, { .sel = { &profile_link, OPT_WRAP, SETTING_ITEM(off_on_desc) } } },
{ LNG("Initial input","ショキニュウリョク"), OPT_AVCONFIG_SELECTION, { .sel = { &def_input, OPT_WRAP, SETTING_ITEM(avinput_str) } } },
@ -232,10 +231,6 @@ MENU(menu_settings, P99_PROTECT({ \
{ "LCD BL timeout", OPT_AVCONFIG_SELECTION, { .sel = { &lcd_bl_timeout, OPT_WRAP, SETTING_ITEM(lcd_bl_timeout_desc) } } },
{ "OSD", OPT_AVCONFIG_SELECTION, { .sel = { &osd_enable, OPT_WRAP, SETTING_ITEM(osd_enable_desc) } } },
{ "OSD status disp.", OPT_AVCONFIG_SELECTION, { .sel = { &osd_status_timeout, OPT_WRAP, SETTING_ITEM(osd_status_desc) } } },
{ "Phase hotkey", OPT_AVCONFIG_SELECTION, { .sel = { &phase_hotkey_enable, OPT_WRAP, SETTING_ITEM(off_on_desc) } } },
{ LNG("<Load profile >","<プロファイルロード >"), OPT_FUNC_CALL, { .fun = { load_profile, &profile_arg_info } } },
{ LNG("<Save profile >","<プロファイルセーブ >"), OPT_FUNC_CALL, { .fun = { save_profile, &profile_arg_info } } },
{ LNG("<Reset settings>","<セッテイヲショキカ >"), OPT_FUNC_CALL, { .fun = { set_default_avconfig, NULL } } },
#ifndef DEBUG
{ LNG("<Import sett. >","<セッテイヨミコミ >"), OPT_FUNC_CALL, { .fun = { import_userdata, NULL } } },
{ LNG("<Export sett. >","<セッテイカキコミ >"), OPT_FUNC_CALL, { .fun = { export_userdata, NULL } } },
@ -265,21 +260,6 @@ menunavi* get_current_menunavi() {
return &navi[navlvl];
}
void init_menu() {
// Set max ids for adv timing
vm_arg_info.max = num_video_modes_plm-1;
// Setup OSD
osd->osd_config.x_size = 0;
osd->osd_config.y_size = 0;
osd->osd_config.x_offset = 3;
osd->osd_config.y_offset = 3;
osd->osd_config.enable = 1;
osd->osd_config.status_timeout = 1;
osd->osd_config.border_color = 1;
}
void write_option_value(menuitem_t *item, int func_called, int retval)
{
switch (item->type) {
@ -470,74 +450,48 @@ void display_menu(alt_u8 forcedisp)
ui_disp_menu(0);
}
void update_osd_size(mode_data_t *vm_out) {
uint8_t osd_size = vm_out->timings.v_active / 700;
uint8_t par = (((100*vm_out->timings.h_active*vm_out->ar.v)/((vm_out->timings.v_active<<vm_out->timings.interlaced)*vm_out->ar.h))+50)/100;
uint8_t par_log2 = 0;
while (par > 1) {
par >>= 1;
par_log2++;
}
osd->osd_config.x_size = osd_size + vm_out->timings.interlaced + par_log2;
osd->osd_config.y_size = osd_size;
if (cm.hdmitx_pixr_ifr)
osd->osd_config.x_size += (cm.hdmitx_pixr_ifr+1)/2;
if (cm.tx_pixelrep)
osd->osd_config.x_size -= (cm.tx_pixelrep+1)/2;
}
static void vm_select() {
vm_edit = vm_sel;
tc_h_samplerate = video_modes_plm[vm_edit].timings.h_total;
tc_h_samplerate_adj = (uint16_t)video_modes_plm[vm_edit].timings.h_total_adj;
tc_h_synclen = (uint16_t)video_modes_plm[vm_edit].timings.h_synclen;
tc_h_bporch = video_modes_plm[vm_edit].timings.h_backporch;
tc_h_active = video_modes_plm[vm_edit].timings.h_active;
tc_v_synclen = (uint16_t)video_modes_plm[vm_edit].timings.v_synclen;
tc_v_bporch = video_modes_plm[vm_edit].timings.v_backporch;
tc_v_active = video_modes_plm[vm_edit].timings.v_active;
tc_h_mask = (uint16_t)video_modes_plm[vm_edit].mask.h;
tc_v_mask = (uint16_t)video_modes_plm[vm_edit].mask.v;
tc_sampler_phase = video_modes_plm[vm_edit].sampler_phase;
tc_h_samplerate = video_modes[vm_edit].h_total;
tc_h_samplerate_adj = (alt_u16)video_modes[vm_edit].h_total_adj;
tc_h_synclen = (alt_u16)video_modes[vm_edit].h_synclen;
tc_h_bporch = (alt_u16)video_modes[vm_edit].h_backporch;
tc_h_active = video_modes[vm_edit].h_active;
tc_v_synclen = (alt_u16)video_modes[vm_edit].v_synclen;
tc_v_bporch = (alt_u16)video_modes[vm_edit].v_backporch;
tc_v_active = video_modes[vm_edit].v_active;
tc_sampler_phase = video_modes[vm_edit].sampler_phase;
}
static void vm_tweak(uint16_t *v) {
int active_mode = (cm.sync_active && (cm.id == vm_edit));
if (active_mode) {
if ((video_modes_plm[cm.id].timings.h_total != tc_h_samplerate) ||
(video_modes_plm[cm.id].timings.h_total_adj != (uint8_t)tc_h_samplerate_adj) ||
(video_modes_plm[cm.id].timings.h_synclen != (uint8_t)tc_h_synclen) ||
(video_modes_plm[cm.id].timings.h_backporch != tc_h_bporch) ||
(video_modes_plm[cm.id].timings.h_active != tc_h_active) ||
(video_modes_plm[cm.id].timings.v_synclen != (uint8_t)tc_v_synclen) ||
(video_modes_plm[cm.id].timings.v_backporch != tc_v_bporch) ||
(video_modes_plm[cm.id].timings.v_active != tc_v_active) ||
(video_modes_plm[cm.id].mask.h != tc_h_mask) ||
(video_modes_plm[cm.id].mask.v != tc_v_mask))
static void vm_tweak(alt_u16 *v) {
if (cm.sync_active && (cm.id == vm_edit)) {
if ((video_modes[cm.id].h_total != tc_h_samplerate) ||
(video_modes[cm.id].h_total_adj != (alt_u8)tc_h_samplerate_adj) ||
(video_modes[cm.id].h_synclen != tc_h_synclen) ||
(video_modes[cm.id].h_backporch != (alt_u8)tc_h_bporch) ||
(video_modes[cm.id].h_active != tc_h_active) ||
(video_modes[cm.id].v_synclen != tc_v_synclen) ||
(video_modes[cm.id].v_backporch != (alt_u8)tc_v_bporch) ||
(video_modes[cm.id].v_active != tc_v_active) ||
(video_modes[cm.id].sampler_phase != tc_sampler_phase))
update_cur_vm = 1;
if (video_modes_plm[cm.id].sampler_phase != tc_sampler_phase)
set_sampler_phase(tc_sampler_phase);
}
video_modes_plm[vm_edit].timings.h_total = tc_h_samplerate;
video_modes_plm[vm_edit].timings.h_total_adj = (uint8_t)tc_h_samplerate_adj;
video_modes_plm[vm_edit].timings.h_synclen = (uint8_t)tc_h_synclen;
video_modes_plm[vm_edit].timings.h_backporch = tc_h_bporch;
video_modes_plm[vm_edit].timings.h_active = tc_h_active;
video_modes_plm[vm_edit].timings.v_synclen = (uint8_t)tc_v_synclen;
video_modes_plm[vm_edit].timings.v_backporch = tc_v_bporch;
video_modes_plm[vm_edit].timings.v_active = tc_v_active;
video_modes_plm[vm_edit].mask.h = tc_h_mask;
video_modes_plm[vm_edit].mask.v = tc_v_mask;
video_modes_plm[vm_edit].sampler_phase = tc_sampler_phase;
video_modes[vm_edit].h_total = tc_h_samplerate;
video_modes[vm_edit].h_total_adj = (alt_u8)tc_h_samplerate_adj;
video_modes[vm_edit].h_synclen = (alt_u8)tc_h_synclen;
video_modes[vm_edit].h_backporch = (alt_u8)tc_h_bporch;
video_modes[vm_edit].h_active = tc_h_active;
video_modes[vm_edit].v_synclen = (alt_u8)tc_v_synclen;
video_modes[vm_edit].v_backporch = (alt_u8)tc_v_bporch;
video_modes[vm_edit].v_active = tc_v_active;
video_modes[vm_edit].sampler_phase = tc_sampler_phase;
if (v == &tc_sampler_phase)
sampler_phase_disp(*v);
else if ((v == &tc_h_samplerate) || (v == &tc_h_samplerate_adj))
sniprintf(menu_row2, LCD_ROW_LEN+1, "%u.%.2u", video_modes_plm[vm_edit].timings.h_total, video_modes_plm[vm_edit].timings.h_total_adj*5);
sniprintf(menu_row2, LCD_ROW_LEN+1, LNG("%d deg","%d ド"), ((*v)*1125)/100);
else if (v == &tc_h_samplerate)
sniprintf(menu_row2, LCD_ROW_LEN+1, "%u", video_modes[vm_edit].h_total);
else if (v == &tc_h_samplerate_adj)
sniprintf(menu_row2, LCD_ROW_LEN+1, ".%.2u", video_modes[vm_edit].h_total_adj*5);
else
sniprintf(menu_row2, LCD_ROW_LEN+1, "%u", *v);
}

View File

@ -1,5 +1,5 @@
//
// Copyright (C) 2015-2023 Markus Hiienkari <mhiienka@niksula.hut.fi>
// Copyright (C) 2015-2016 Markus Hiienkari <mhiienka@niksula.hut.fi>
//
// This file is part of Open Source Scan Converter project.
//
@ -21,9 +21,7 @@
#define MENU_H_
#include "alt_types.h"
#include "sysconfig.h"
#include "controls.h"
#include "video_modes.h"
#ifdef OSDLANG_JP
#define LNG(e, j) j
@ -123,12 +121,10 @@ typedef struct {
} menunavi;
menunavi* get_current_menunavi();
void init_menu();
void render_osd_page();
void display_menu(alt_u8 forcedisp);
void sampler_phase_disp(alt_u8 v);
void update_osd_size(mode_data_t *vm_out);
static void vm_select();
static void vm_tweak(alt_u16 *v);
static void sampler_phase_tweak(alt_u8 v);
#endif

View File

@ -1,5 +1,5 @@
//
// Copyright (C) 2015-2023 Markus Hiienkari <mhiienka@niksula.hut.fi>
// Copyright (C) 2015-2018 Markus Hiienkari <mhiienka@niksula.hut.fi>
//
// This file is part of Open Source Scan Converter project.
//
@ -32,15 +32,10 @@
#include "utils.h"
#include "altera_avalon_pio_regs.h"
// include mode array definitions so that sizeof() can be used
#define VM_STATIC_INCLUDE
#include "video_modes_list.c"
#undef VM_STATIC_INCLUDE
extern alt_u16 rc_keymap[REMOTE_MAX_KEYS];
extern avmode_t cm;
extern avconfig_t tc;
extern mode_data_t video_modes_plm[];
extern mode_data_t video_modes[];
extern avinput_t target_input;
extern alt_u8 update_cur_vm;
extern alt_u8 input_profiles[AV_LAST];
@ -48,7 +43,7 @@ extern alt_u8 profile_sel;
extern alt_u8 def_input, profile_link;
extern alt_u8 lcd_bl_timeout;
extern alt_u8 auto_input, auto_av1_ypbpr, auto_av2_ypbpr, auto_av3_ypbpr;
extern alt_u8 osd_enable, osd_status_timeout, phase_hotkey_enable;
extern alt_u8 osd_enable, osd_status_timeout;
extern SD_DEV sdcard_dev;
extern alt_flash_dev *epcq_dev;
extern char menu_row1[LCD_ROW_LEN+1], menu_row2[LCD_ROW_LEN+1];
@ -88,7 +83,6 @@ int write_userdata(alt_u8 entry)
((ude_initcfg*)databuf)->auto_av3_ypbpr = auto_av3_ypbpr;
((ude_initcfg*)databuf)->osd_enable = osd_enable;
((ude_initcfg*)databuf)->osd_status_timeout = osd_status_timeout;
((ude_initcfg*)databuf)->phase_hotkey_enable = phase_hotkey_enable;
memcpy(((ude_initcfg*)databuf)->keys, rc_keymap, sizeof(rc_keymap));
for (i=0; i<sizeof(ude_initcfg); i++)
databuf[i] = bitswap8(databuf[i]);
@ -101,7 +95,7 @@ int write_userdata(alt_u8 entry)
case UDE_PROFILE:
((ude_hdr*)databuf)->version_major = PROFILE_VER_MAJOR;
((ude_hdr*)databuf)->version_minor = PROFILE_VER_MINOR;
vm_to_write = sizeof(video_modes_plm_default);
vm_to_write = VIDEO_MODES_SIZE;
((ude_profile*)databuf)->avc_data_len = sizeof(avconfig_t);
((ude_profile*)databuf)->vm_data_len = vm_to_write;
@ -116,8 +110,8 @@ int write_userdata(alt_u8 entry)
memcpy(databuf+pageoffset, &tc, sizeof(avconfig_t));
pageoffset += sizeof(avconfig_t);
// erase sector and write a full page first, assume sizeof(video_modes_plm) >> PAGESIZE
memcpy(databuf+pageoffset, (char*)video_modes_plm, PAGESIZE-pageoffset);
// erase sector and write a full page first, assume sizeof(video_modes) >> PAGESIZE
memcpy(databuf+pageoffset, (char*)video_modes, PAGESIZE-pageoffset);
srcoffset = PAGESIZE-pageoffset;
vm_to_write -= PAGESIZE-pageoffset;
for (i=0; i<PAGESIZE; i++)
@ -129,7 +123,7 @@ int write_userdata(alt_u8 entry)
// then write the rest page by page
pageno = 1;
while (vm_to_write > 0) {
memcpy(databuf, (char*)video_modes_plm+srcoffset, (vm_to_write > PAGESIZE) ? PAGESIZE : vm_to_write);
memcpy(databuf, (char*)video_modes+srcoffset, (vm_to_write > PAGESIZE) ? PAGESIZE : vm_to_write);
for (i=0; i<PAGESIZE; i++)
databuf[i] = bitswap8(databuf[i]);
retval = alt_epcq_controller2_write_block(epcq_dev, (USERDATA_OFFSET+entry*SECTORSIZE), (USERDATA_OFFSET+entry*SECTORSIZE+pageno*PAGESIZE), databuf, (vm_to_write > PAGESIZE) ? PAGESIZE : vm_to_write);
@ -141,7 +135,7 @@ int write_userdata(alt_u8 entry)
pageno++;
}
printf("Profile %u data written (%u bytes)\n", entry, sizeof(avconfig_t)+sizeof(video_modes_plm_default));
printf("Profile %u data written (%u bytes)\n", entry, sizeof(avconfig_t)+VIDEO_MODES_SIZE);
break;
default:
break;
@ -179,7 +173,7 @@ int read_userdata(alt_u8 entry, int dry_run)
switch (((ude_hdr*)databuf)->type) {
case UDE_INITCFG:
if ((((ude_hdr*)databuf)->version_major != INITCFG_VER_MAJOR) || (((ude_hdr*)databuf)->version_minor != INITCFG_VER_MINOR)) {
printf("Initconfig version %u.%.2u does not match current one\n", ((ude_hdr*)databuf)->version_major, ((ude_hdr*)databuf)->version_minor);
printf("Initconfig version %u.%u does not match current one\n", ((ude_hdr*)databuf)->version_major, ((ude_hdr*)databuf)->version_minor);
return 2;
}
if (((ude_initcfg*)databuf)->data_len == sizeof(ude_initcfg) - offsetof(ude_initcfg, last_profile)) {
@ -203,17 +197,16 @@ int read_userdata(alt_u8 entry, int dry_run)
profile_link = ((ude_initcfg*)databuf)->profile_link;
profile_sel = input_profiles[AV_TESTPAT]; // Global profile
lcd_bl_timeout = ((ude_initcfg*)databuf)->lcd_bl_timeout;
phase_hotkey_enable = ((ude_initcfg*)databuf)->phase_hotkey_enable;
memcpy(rc_keymap, ((ude_initcfg*)databuf)->keys, sizeof(rc_keymap));
printf("RC data read (%u bytes)\n", sizeof(rc_keymap));
}
break;
case UDE_PROFILE:
if ((((ude_hdr*)databuf)->version_major != PROFILE_VER_MAJOR) || (((ude_hdr*)databuf)->version_minor != PROFILE_VER_MINOR)) {
printf("Profile version %u.%.2u does not match current one\n", ((ude_hdr*)databuf)->version_major, ((ude_hdr*)databuf)->version_minor);
printf("Profile version %u.%u does not match current one\n", ((ude_hdr*)databuf)->version_major, ((ude_hdr*)databuf)->version_minor);
return 2;
}
if ((((ude_profile*)databuf)->avc_data_len == sizeof(avconfig_t)) && (((ude_profile*)databuf)->vm_data_len == sizeof(video_modes_plm_default))) {
if ((((ude_profile*)databuf)->avc_data_len == sizeof(avconfig_t)) && (((ude_profile*)databuf)->vm_data_len == VIDEO_MODES_SIZE)) {
strncpy(target_profile_name, ((ude_profile*)databuf)->name, PROFILE_NAME_LEN+1);
if (dry_run)
return 0;
@ -230,7 +223,7 @@ int read_userdata(alt_u8 entry, int dry_run)
dstoffset = 0;
while (vm_to_read > 0) {
if (vm_to_read >= PAGESIZE-pageoffset) {
memcpy((char*)video_modes_plm+dstoffset, databuf+pageoffset, PAGESIZE-pageoffset);
memcpy((char*)video_modes+dstoffset, databuf+pageoffset, PAGESIZE-pageoffset);
dstoffset += PAGESIZE-pageoffset;
vm_to_read -= PAGESIZE-pageoffset;
pageoffset = 0;
@ -242,14 +235,14 @@ int read_userdata(alt_u8 entry, int dry_run)
if (retval != 0)
return retval;
} else {
memcpy((char*)video_modes_plm+dstoffset, databuf+pageoffset, vm_to_read);
memcpy((char*)video_modes+dstoffset, databuf+pageoffset, vm_to_read);
pageoffset += vm_to_read;
vm_to_read = 0;
}
}
update_cur_vm = 1;
printf("Profile %u data read (%u bytes)\n", entry, sizeof(avconfig_t)+sizeof(video_modes_plm_default));
printf("Profile %u data read (%u bytes)\n", entry, sizeof(avconfig_t)+VIDEO_MODES_SIZE);
}
break;
default:
@ -310,10 +303,10 @@ int import_userdata()
}
if ((header.type == UDE_PROFILE) && ((header.version_major != PROFILE_VER_MAJOR) || (header.version_minor != PROFILE_VER_MINOR))) {
printf("Profile version %u.%.2u does not match current one\n", header.version_major, header.version_minor);
printf("Profile version %u.%u does not match current one\n", header.version_major, header.version_minor);
continue;
} else if ((header.type == UDE_INITCFG) && ((header.version_major != INITCFG_VER_MAJOR) || (header.version_minor != INITCFG_VER_MINOR))) {
printf("Initconfig version %u.%.2u does not match current one\n", header.version_major, header.version_minor);
printf("Initconfig version %u.%u does not match current one\n", header.version_major, header.version_minor);
continue;
} else if (header.type > UDE_PROFILE) {
printf("Unknown userdata entry type %u\n", header.type);
@ -322,7 +315,7 @@ int import_userdata()
// Just blindly write the entry to flash
retval = copy_sd_to_flash((512+n*SECTORSIZE)/SD_BLK_SIZE, (n*PAGES_PER_SECTOR)+(USERDATA_OFFSET/PAGESIZE),
(header.type == UDE_PROFILE) ? (sizeof(ude_profile)+sizeof(video_modes_plm_default)) : sizeof(ude_initcfg), databuf);
(header.type == UDE_PROFILE) ? sizeof(ude_profile) : sizeof(ude_initcfg), databuf);
if (retval != 0) {
printf("Copy from SD to flash failed (error %d)\n", retval);
goto sd_disable;

View File

@ -1,5 +1,5 @@
//
// Copyright (C) 2015-2023 Markus Hiienkari <mhiienka@niksula.hut.fi>
// Copyright (C) 2015-2018 Markus Hiienkari <mhiienka@niksula.hut.fi>
//
// This file is part of Open Source Scan Converter project.
//
@ -62,7 +62,6 @@ typedef struct {
alt_u8 auto_av3_ypbpr;
alt_u8 osd_enable;
alt_u8 osd_status_timeout;
alt_u8 phase_hotkey_enable;
alt_u16 keys[REMOTE_MAX_KEYS];
} __attribute__((packed, __may_alias__)) ude_initcfg;
@ -72,7 +71,7 @@ typedef struct {
alt_u16 avc_data_len;
alt_u16 vm_data_len;
avconfig_t avc;
//mode_data_t vm[VIDEO_MODES_CNT];
mode_data_t vm[VIDEO_MODES_CNT];
} __attribute__((packed, __may_alias__)) ude_profile;
int write_userdata(alt_u8 entry);

View File

@ -1,498 +0,0 @@
//
// Copyright (C) 2015-2023 Markus Hiienkari <mhiienka@niksula.hut.fi>
//
// This file is part of Open Source Scan Converter project.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdint.h>
#include "system.h"
#include "video_modes.h"
#include "av_controller.h"
#include "avconfig.h"
#define VM_OUT_YMULT (vm_conf->y_rpt+1)
#define VM_OUT_XMULT (vm_conf->x_rpt+1)
#define VM_OUT_PCLKMULT (((vm_conf->x_rpt+1)*(vm_conf->y_rpt+1))/(vm_conf->h_skip+1))
#include "video_modes_list.c"
const int num_video_modes_plm = sizeof(video_modes_plm_default)/sizeof(mode_data_t);
mode_data_t video_modes_plm[sizeof(video_modes_plm_default)/sizeof(mode_data_t)];
void set_default_vm_table() {
memcpy(video_modes_plm, video_modes_plm_default, sizeof(video_modes_plm_default));
}
void vmode_hv_mult(mode_data_t *vmode, uint8_t h_mult, uint8_t v_mult) {
uint32_t val, bp_extra;
val = vmode->timings.h_synclen * h_mult;
if (val > H_SYNCLEN_MAX) {
vmode->timings.h_synclen = H_SYNCLEN_MAX;
bp_extra = val - vmode->timings.h_synclen;
} else {
vmode->timings.h_synclen = val;
bp_extra = 0;
}
val = (vmode->timings.h_backporch * h_mult) + bp_extra;
if (val > H_BPORCH_MAX)
vmode->timings.h_backporch = H_BPORCH_MAX;
else
vmode->timings.h_backporch = val;
val = vmode->timings.h_active * h_mult;
if (val > H_ACTIVE_MAX)
vmode->timings.h_active = H_ACTIVE_MAX;
else
vmode->timings.h_active = val;
vmode->timings.h_total = h_mult * vmode->timings.h_total + ((h_mult * vmode->timings.h_total_adj * 5 + 50) / 100);
val = vmode->timings.v_synclen * v_mult;
if (val > V_SYNCLEN_MAX) {
vmode->timings.v_synclen = V_SYNCLEN_MAX;
bp_extra = val - vmode->timings.v_synclen;
} else {
vmode->timings.v_synclen = val;
bp_extra = 0;
}
val = (vmode->timings.v_backporch * v_mult) + bp_extra;
if (val > V_BPORCH_MAX)
vmode->timings.v_backporch = V_BPORCH_MAX;
else
vmode->timings.v_backporch = val;
val = vmode->timings.v_active * v_mult;
if (val > V_ACTIVE_MAX)
vmode->timings.v_active = V_ACTIVE_MAX;
else
vmode->timings.v_active = val;
if (vmode->timings.interlaced && ((v_mult % 2) == 0)) {
vmode->timings.interlaced = 0;
vmode->timings.v_total *= (v_mult / 2);
} else {
vmode->timings.v_total *= v_mult;
}
}
uint32_t estimate_dotclk(mode_data_t *vm_in, uint32_t h_hz) {
if ((vm_in->type & VIDEO_SDTV) ||
(vm_in->type & VIDEO_EDTV))
{
return h_hz * 858;
} else {
return vm_in->timings.h_total * h_hz;
}
}
uint32_t calculate_pclk(uint32_t src_clk_hz, mode_data_t *vm_out, vm_proc_config_t *vm_conf) {
uint32_t pclk_hz;
if (vm_conf->si_pclk_mult > 0) {
pclk_hz = vm_conf->si_pclk_mult*src_clk_hz;
} else if (vm_conf->si_pclk_mult < 0) {
pclk_hz = src_clk_hz/((-1)*vm_conf->si_pclk_mult+1);
} else {
// Round to kHz but maximize accuracy without using 64-bit division
pclk_hz = (((uint32_t)((((uint64_t)vm_out->timings.h_total*vm_out->timings.v_total*vm_out->timings.v_hz_x100)>>vm_out->timings.interlaced)/8)+6250)/12500)*1000;
// Switch to integer mult if possible
if (!vm_conf->framelock) {
if ((pclk_hz >= src_clk_hz) && (pclk_hz % src_clk_hz == 0))
vm_conf->si_pclk_mult = (pclk_hz/src_clk_hz);
else if ((pclk_hz < src_clk_hz) && (src_clk_hz % pclk_hz == 0))
vm_conf->si_pclk_mult = (-1)*((src_clk_hz/pclk_hz)-1);
}
}
return pclk_hz;
}
int get_pure_lm_mode(avconfig_t *cc, mode_data_t *vm_in, mode_data_t *vm_out, vm_proc_config_t *vm_conf)
{
int i, diff_lines, diff_v_hz_x100, mindiff_id=0, mindiff_lines=1000, mindiff_v_hz_x100=10000;
mode_data_t *mode_preset;
mode_flags valid_lm[] = { MODE_PT, (MODE_L2 | (MODE_L2<<cc->l2_mode)), (MODE_L3_GEN_16_9<<cc->l3_mode), (MODE_L4_GEN_4_3<<cc->l4_mode), (MODE_L5_GEN_4_3<<cc->l5_mode) };
mode_flags target_lm, mindiff_lm;
uint8_t pt_only = 0;
uint8_t upsample2x = cc->upsample2x;
// one for each video_group
uint8_t* group_ptr[] = { &pt_only, &cc->pm_240p, &cc->pm_240p, &cc->pm_384p, &cc->pm_480i, &cc->pm_480i, &cc->pm_480p, &cc->pm_480p, &pt_only, &cc->pm_1080i, &pt_only };
for (i=0; i<num_video_modes_plm; i++) {
mode_preset = &video_modes_plm[i];
switch (mode_preset->group) {
case GROUP_384P:
//fixed Line2x/3x mode for 240x360p/400p
valid_lm[2] = MODE_L3_GEN_16_9;
valid_lm[3] = MODE_L2_240x360;
valid_lm[4] = MODE_L3_240x360;
if ((!vm_in->timings.h_total) && (mode_preset->timings.v_total == 449)) {
if (!strncmp(mode_preset->name, "720x400_70", 10)) {
if (cc->s400p_mode == 0)
continue;
} else if (!strncmp(mode_preset->name, "640x400_70", 10)) {
if (cc->s400p_mode == 1)
continue;
}
}
break;
case GROUP_480I:
case GROUP_576I:
//fixed Line3x/4x mode for 480i
valid_lm[2] = MODE_L3_GEN_16_9;
valid_lm[3] = MODE_L4_GEN_4_3;
break;
case GROUP_480P:
if (mode_preset->vic == HDMI_480p60) {
switch (cc->s480p_mode) {
case 0: // Auto
if (vm_in->timings.h_synclen > 82)
continue;
break;
case 1: // DTV 480p
break;
default:
continue;
}
} else if (mode_preset->vic == HDMI_640x480p60) {
switch (cc->s480p_mode) {
case 0: // Auto
case 2: // VESA 640x480@60
break;
default:
continue;
}
}
break;
default:
break;
}
target_lm = valid_lm[*group_ptr[mode_preset->group]];
if ((target_lm & mode_preset->flags) &&
(vm_in->timings.interlaced == mode_preset->timings.interlaced))
{
diff_lines = abs(vm_in->timings.v_total - mode_preset->timings.v_total);
diff_v_hz_x100 = abs(vm_in->timings.v_hz_x100 - mode_preset->timings.v_hz_x100);
if ((diff_lines < mindiff_lines) || ((mode_preset->group >= GROUP_720P) && (diff_lines == mindiff_lines) && (diff_v_hz_x100 < mindiff_v_hz_x100))) {
mindiff_id = i;
mindiff_lines = diff_lines;
mindiff_v_hz_x100 = diff_v_hz_x100;
mindiff_lm = target_lm;
} else if ((mindiff_lines <= 2) && (diff_lines > mindiff_lines)) {
// Break out if suitable mode already found
break;
}
}
}
if (mindiff_lines >= 110)
return -1;
mode_preset = &video_modes_plm[mindiff_id];
vm_in->timings.h_active = mode_preset->timings.h_active;
vm_in->timings.v_active = mode_preset->timings.v_active;
vm_in->timings.h_synclen = mode_preset->timings.h_synclen;
vm_in->timings.v_synclen = mode_preset->timings.v_synclen;
vm_in->timings.h_backporch = mode_preset->timings.h_backporch;
vm_in->timings.v_backporch = mode_preset->timings.v_backporch;
vm_in->timings.h_total = mode_preset->timings.h_total;
vm_in->timings.h_total_adj = mode_preset->timings.h_total_adj;
vm_in->sampler_phase = mode_preset->sampler_phase;
vm_in->mask.h = mode_preset->mask.h;
vm_in->mask.v = mode_preset->mask.v;
vm_in->type = mode_preset->type;
vm_in->group = mode_preset->group;
vm_in->vic = mode_preset->vic;
strncpy(vm_in->name, mode_preset->name, 10);
memcpy(vm_out, vm_in, sizeof(mode_data_t));
vm_out->vic = HDMI_Unknown;
memset(vm_conf, 0, sizeof(vm_proc_config_t));
vm_conf->si_pclk_mult = 1;
mindiff_lm &= mode_preset->flags; //ensure L2 mode uniqueness
switch (mindiff_lm) {
case MODE_PT:
vm_out->vic = vm_in->vic;
// multiply horizontal resolution if necessary to fulfill min. 25MHz TMDS clock requirement. Tweak infoframe pixel repetition indicator later to make sink treat it as original resolution.
while ((((vm_out->timings.v_hz_x100*vm_out->timings.v_total)/100)*vm_out->timings.h_total*(vm_conf->h_skip+1))>>vm_out->timings.interlaced < 25000000UL) {
vm_conf->x_rpt = vm_conf->h_skip = 2*(vm_conf->h_skip+1)-1;
}
vmode_hv_mult(vm_out, VM_OUT_XMULT, VM_OUT_YMULT);
vm_conf->si_pclk_mult = VM_OUT_PCLKMULT;
break;
case MODE_L2:
vm_conf->y_rpt = 1;
// Upsample / pixel-repeat horizontal resolution of 384p/480p/960i modes
if ((mode_preset->group == GROUP_384P) || (mode_preset->group == GROUP_480P) || (mode_preset->group == GROUP_576P) || ((mode_preset->group == GROUP_1080I) && (mode_preset->timings.h_total < 1200))) {
if (upsample2x) {
vmode_hv_mult(vm_in, 2, 1);
vmode_hv_mult(vm_out, 2, VM_OUT_YMULT);
} else {
vm_conf->x_rpt = 1;
vmode_hv_mult(vm_out, VM_OUT_XMULT, VM_OUT_YMULT);
}
} else {
vmode_hv_mult(vm_out, VM_OUT_XMULT, VM_OUT_YMULT);
}
vm_conf->si_pclk_mult = VM_OUT_PCLKMULT;
break;
case MODE_L2_512_COL:
vm_conf->y_rpt = 1;
vm_conf->x_rpt = vm_conf->h_skip = 1;
vmode_hv_mult(vm_out, VM_OUT_XMULT, VM_OUT_YMULT);
vm_conf->si_pclk_mult = VM_OUT_PCLKMULT;
break;
case MODE_L2_384_COL:
case MODE_L2_320_COL:
vm_conf->y_rpt = 1;
vm_conf->x_rpt = vm_conf->h_skip = 1;
vmode_hv_mult(vm_out, VM_OUT_XMULT, VM_OUT_YMULT);
vm_conf->si_pclk_mult = VM_OUT_PCLKMULT;
break;
case MODE_L2_256_COL:
vm_conf->y_rpt = 1;
vm_conf->x_rpt = vm_conf->h_skip = 2;
vmode_hv_mult(vm_out, VM_OUT_XMULT, VM_OUT_YMULT);
vm_conf->si_pclk_mult = VM_OUT_PCLKMULT;
vm_conf->x_rpt -= cc->ar_256col;
break;
case MODE_L2_240x360:
vm_conf->y_rpt = 1;
vm_conf->x_rpt = vm_conf->h_skip = 4;
vmode_hv_mult(vm_out, VM_OUT_XMULT, VM_OUT_YMULT);
vm_conf->si_pclk_mult = VM_OUT_PCLKMULT;
break;
case MODE_L3_GEN_16_9:
vm_conf->y_rpt = 2;
// Upsample / pixel-repeat horizontal resolution of 480i mode
if ((mode_preset->group == GROUP_480I) || (mode_preset->group == GROUP_576I)) {
if (upsample2x) {
vmode_hv_mult(vm_in, 2, 1);
vmode_hv_mult(vm_out, 2, VM_OUT_YMULT);
} else {
vm_conf->x_rpt = 1;
vmode_hv_mult(vm_out, VM_OUT_XMULT, VM_OUT_YMULT);
}
} else {
vmode_hv_mult(vm_out, VM_OUT_XMULT, VM_OUT_YMULT);
}
vm_conf->si_pclk_mult = VM_OUT_PCLKMULT;
break;
case MODE_L3_GEN_4_3:
vm_conf->y_rpt = 2;
vm_conf->x_size = vm_out->timings.h_active-2*vm_in->mask.h;
vm_out->timings.h_synclen /= 3;
vm_out->timings.h_backporch /= 3;
vm_out->timings.h_active /= 3;
vm_out->timings.h_total /= 3;
vm_out->timings.h_total_adj = 0;
vmode_hv_mult(vm_out, 4, VM_OUT_YMULT);
vm_conf->si_pclk_mult = 4;
break;
case MODE_L3_512_COL:
vm_conf->y_rpt = 2;
vm_conf->x_rpt = vm_conf->h_skip = 1;
vmode_hv_mult(vm_out, VM_OUT_XMULT, VM_OUT_YMULT);
vm_conf->si_pclk_mult = VM_OUT_PCLKMULT;
break;
case MODE_L3_384_COL:
vm_conf->y_rpt = 2;
vm_conf->x_rpt = vm_conf->h_skip = 2;
vmode_hv_mult(vm_out, VM_OUT_XMULT, VM_OUT_YMULT);
vm_conf->si_pclk_mult = VM_OUT_PCLKMULT;
break;
case MODE_L3_320_COL:
vm_conf->y_rpt = 2;
vm_conf->x_rpt = vm_conf->h_skip = 3;
vmode_hv_mult(vm_out, VM_OUT_XMULT, VM_OUT_YMULT);
vm_conf->si_pclk_mult = VM_OUT_PCLKMULT;
vm_conf->x_rpt = 2;
break;
case MODE_L3_256_COL:
vm_conf->y_rpt = 2;
vm_conf->x_rpt = vm_conf->h_skip = 4;
vmode_hv_mult(vm_out, VM_OUT_XMULT, VM_OUT_YMULT);
vm_conf->si_pclk_mult = VM_OUT_PCLKMULT;
vm_conf->x_rpt = cc->ar_256col ? 2 : 3;
break;
case MODE_L3_240x360:
vm_conf->y_rpt = 2;
vm_conf->x_rpt = vm_conf->h_skip = 6;
vmode_hv_mult(vm_out, VM_OUT_XMULT, VM_OUT_YMULT);
vm_conf->si_pclk_mult = VM_OUT_PCLKMULT;
break;
case MODE_L4_GEN_4_3:
vm_conf->y_rpt = 3;
// Upsample / pixel-repeat horizontal resolution of 480i mode
if ((mode_preset->group == GROUP_480I) || (mode_preset->group == GROUP_576I)) {
if (upsample2x) {
vmode_hv_mult(vm_in, 2, 1);
vmode_hv_mult(vm_out, 2, VM_OUT_YMULT);
} else {
vm_conf->x_rpt = 1;
vmode_hv_mult(vm_out, VM_OUT_XMULT, VM_OUT_YMULT);
}
} else {
vmode_hv_mult(vm_out, VM_OUT_XMULT, VM_OUT_YMULT);
}
vm_conf->si_pclk_mult = VM_OUT_PCLKMULT;
break;
case MODE_L4_512_COL:
vm_conf->y_rpt = 3;
vm_conf->x_rpt = vm_conf->h_skip = 1;
vmode_hv_mult(vm_out, VM_OUT_XMULT, VM_OUT_YMULT);
vm_conf->si_pclk_mult = VM_OUT_PCLKMULT;
break;
case MODE_L4_384_COL:
vm_conf->y_rpt = 3;
vm_conf->x_rpt = vm_conf->h_skip = 2;
vmode_hv_mult(vm_out, VM_OUT_XMULT, VM_OUT_YMULT);
vm_conf->si_pclk_mult = VM_OUT_PCLKMULT;
break;
case MODE_L4_320_COL:
vm_conf->y_rpt = 3;
vm_conf->x_rpt = vm_conf->h_skip = 3;
vmode_hv_mult(vm_out, VM_OUT_XMULT, VM_OUT_YMULT);
vm_conf->si_pclk_mult = VM_OUT_PCLKMULT;
break;
case MODE_L4_256_COL:
vm_conf->y_rpt = 3;
vm_conf->x_rpt = vm_conf->h_skip = 4;
vmode_hv_mult(vm_out, VM_OUT_XMULT, VM_OUT_YMULT);
vm_conf->si_pclk_mult = VM_OUT_PCLKMULT;
vm_conf->x_rpt -= cc->ar_256col;
break;
case MODE_L5_GEN_4_3:
vm_conf->y_rpt = 4;
vmode_hv_mult(vm_out, VM_OUT_XMULT, VM_OUT_YMULT);
vm_conf->si_pclk_mult = VM_OUT_PCLKMULT;
break;
case MODE_L5_512_COL:
vm_conf->y_rpt = 4;
vm_conf->x_rpt = vm_conf->h_skip = 2;
vmode_hv_mult(vm_out, VM_OUT_XMULT, VM_OUT_YMULT);
vm_conf->si_pclk_mult = VM_OUT_PCLKMULT;
break;
case MODE_L5_384_COL:
vm_conf->y_rpt = 4;
vm_conf->x_rpt = vm_conf->h_skip = 3;
vmode_hv_mult(vm_out, VM_OUT_XMULT, VM_OUT_YMULT);
vm_conf->si_pclk_mult = VM_OUT_PCLKMULT;
break;
case MODE_L5_320_COL:
vm_conf->y_rpt = 4;
vm_conf->x_rpt = vm_conf->h_skip = 4;
vmode_hv_mult(vm_out, VM_OUT_XMULT, VM_OUT_YMULT);
vm_conf->si_pclk_mult = VM_OUT_PCLKMULT;
break;
case MODE_L5_256_COL:
vm_conf->y_rpt = 4;
vm_conf->x_rpt = vm_conf->h_skip = 5;
vmode_hv_mult(vm_out, VM_OUT_XMULT, VM_OUT_YMULT);
vm_conf->si_pclk_mult = VM_OUT_PCLKMULT;
vm_conf->x_rpt -= cc->ar_256col;
break;
default:
printf("WARNING: invalid mindiff_lm\n");
return -1;
break;
}
sniprintf(vm_out->name, 10, "%s x%u", vm_in->name, vm_conf->y_rpt+1);
if (vm_conf->x_size == 0)
vm_conf->x_size = (vm_in->timings.h_active-2*vm_in->mask.h)*(vm_conf->x_rpt+1);
if (vm_conf->y_size == 0)
vm_conf->y_size = vm_out->timings.v_active-2*vm_in->mask.v*(vm_conf->y_rpt+1);
vm_conf->x_offset = ((vm_out->timings.h_active-vm_conf->x_size)/2);
vm_conf->x_start_lb = vm_in->mask.h;
vm_conf->y_offset = ((vm_out->timings.v_active-vm_conf->y_size)/2);
// Line5x format
if (vm_conf->y_rpt == 4) {
// adjust output width to 1920
if (cc->l5_fmt != 1) {
vm_conf->x_offset = (1920-vm_conf->x_size)/2;
vm_out->timings.h_synclen = (vm_out->timings.h_total - 1920)/4;
vm_out->timings.h_backporch = (vm_out->timings.h_total - 1920)/2;
vm_out->timings.h_active = 1920;
}
// adjust output height to 1080
if (cc->l5_fmt == 0) {
vm_conf->y_start_lb = (vm_out->timings.v_active-1080)/10;
vm_out->timings.v_backporch += 5*vm_conf->y_start_lb;
vm_out->timings.v_active = 1080;
vm_conf->y_size = vm_out->timings.v_active-2*vm_in->mask.v*(vm_conf->y_rpt+1);
}
}
// Aspect
if (vm_out->type & VIDEO_HDTV) {
vm_out->ar.h = 16;
vm_out->ar.v = 9;
} else {
vm_out->ar.h = 4;
vm_out->ar.v = 3;
}
#ifdef LM_EMIF_EXTRA_DELAY
vm_conf->framesync_line = ((vm_out->timings.v_total>>vm_out->timings.interlaced)-(1+vm_out->timings.interlaced)*(vm_conf->y_rpt+1));
#else
//vm_conf->framesync_line = vm_in->timings.interlaced ? ((vm_out->timings.v_total>>vm_out->timings.interlaced)-(vm_conf->y_rpt+1)) : 0;
vm_conf->framesync_line = 0;
#endif
vm_conf->framelock = 1;
if (vm_out->vic == HDMI_Unknown)
vm_out->vic = cc->default_vic;
return mindiff_id;
}
int get_vmode(vmode_t vmode_id, mode_data_t *vm_in, mode_data_t *vm_out, vm_proc_config_t *vm_conf)
{
memset(vm_conf, 0, sizeof(vm_proc_config_t));
memset(vm_in, 0, sizeof(mode_data_t));
memcpy(vm_out, &video_modes_plm_default[vmode_id], sizeof(mode_data_t));
vm_out->ar.h = 4;
vm_out->ar.v = 3;
return 0;
}

View File

@ -1,181 +0,0 @@
//
// Copyright (C) 2015-2023 Markus Hiienkari <mhiienka@niksula.hut.fi>
//
// This file is part of Open Source Scan Converter project.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
#ifndef VIDEO_MODES_H_
#define VIDEO_MODES_H_
#include <stdint.h>
#include "sysconfig.h"
#include "avconfig.h"
#include "it6613_sys.h"
#define DEF_PHASE 0x10
#define H_TOTAL_MIN 300
#define H_TOTAL_MAX 2800
#define H_TOTAL_ADJ_MAX 19
#define H_SYNCLEN_MIN 10
#define H_SYNCLEN_MAX 255
#define H_BPORCH_MIN 0
#define H_BPORCH_MAX 511
#define H_ACTIVE_MIN 200
#define H_ACTIVE_MAX 2560
#define H_ACTIVE_SMP_MAX 2048
#define V_SYNCLEN_MIN 1
#define V_SYNCLEN_MAX 15
#define V_BPORCH_MIN 0
#define V_BPORCH_MAX 511
#define V_ACTIVE_MIN 160
#define V_ACTIVE_MAX 1440
typedef enum {
FORMAT_RGBS = 0,
FORMAT_RGBHV = 1,
FORMAT_RGsB = 2,
FORMAT_YPbPr = 3
} video_format;
typedef enum {
VIDEO_SDTV = (1<<0),
VIDEO_EDTV = (1<<1),
VIDEO_HDTV = (1<<2),
VIDEO_PC = (1<<3),
} video_type;
typedef enum {
GROUP_NONE = 0,
GROUP_240P = 1,
GROUP_288P = 2,
GROUP_384P = 3,
GROUP_480I = 4,
GROUP_576I = 5,
GROUP_480P = 6,
GROUP_576P = 7,
GROUP_720P = 8,
GROUP_1080I = 9,
GROUP_1080P = 10,
} video_group;
typedef enum {
MODE_INTERLACED = (1<<0), //deprecated
MODE_CRT = (1<<1),
//at least one of the flags below must be set for each P-LM mode
MODE_PT = (1<<2),
MODE_L2 = (1<<3),
MODE_L2_512_COL = (1<<4),
MODE_L2_384_COL = (1<<5),
MODE_L2_320_COL = (1<<6),
MODE_L2_256_COL = (1<<7),
MODE_L2_240x360 = (1<<8),
MODE_L3_GEN_16_9 = (1<<9),
MODE_L3_GEN_4_3 = (1<<10),
MODE_L3_512_COL = (1<<11),
MODE_L3_384_COL = (1<<12),
MODE_L3_320_COL = (1<<13),
MODE_L3_256_COL = (1<<14),
MODE_L3_240x360 = (1<<15),
MODE_L4_GEN_4_3 = (1<<16),
MODE_L4_512_COL = (1<<17),
MODE_L4_384_COL = (1<<18),
MODE_L4_320_COL = (1<<19),
MODE_L4_256_COL = (1<<20),
MODE_L5_GEN_4_3 = (1<<21),
MODE_L5_512_COL = (1<<22),
MODE_L5_384_COL = (1<<23),
MODE_L5_320_COL = (1<<24),
MODE_L5_256_COL = (1<<25),
} mode_flags;
typedef enum {
VMODE_480p = 24,
} vmode_t;
typedef struct {
uint16_t h_active;
uint16_t v_active;
uint16_t v_hz_x100;
uint16_t h_total;
uint8_t h_total_adj;
uint16_t v_total;
uint16_t h_backporch;
uint16_t v_backporch;
uint8_t h_synclen;
uint8_t v_synclen;
uint8_t interlaced;
} sync_timings_t;
typedef struct {
uint8_t h;
uint8_t v;
} aspect_ratio_t;
typedef struct {
uint8_t h;
uint8_t v;
} mask_t;
typedef enum {
TX_1X = 0,
TX_2X = 1,
TX_4X = 2
} HDMI_pixelrep_t;
typedef struct {
char name[10];
HDMI_Video_Type vic;
sync_timings_t timings;
uint8_t sampler_phase;
union {
aspect_ratio_t ar;
mask_t mask;
};
video_type type;
video_group group;
mode_flags flags;
} mode_data_t;
typedef struct {
int8_t x_rpt;
int8_t y_rpt;
uint8_t h_skip;
uint8_t h_sample_sel;
int16_t x_offset;
int16_t y_offset;
uint16_t x_size;
uint16_t y_size;
uint16_t framesync_line;
uint8_t x_start_lb;
int8_t y_start_lb;
uint8_t framelock;
// for generation from 27MHz clock
int8_t si_pclk_mult;
} vm_proc_config_t;
void set_default_vm_table();
uint32_t estimate_dotclk(mode_data_t *vm_in, uint32_t h_hz);
uint32_t calculate_pclk(uint32_t src_clk_hz, mode_data_t *vm_out, vm_proc_config_t *vm_conf);
int get_pure_lm_mode(avconfig_t *cc, mode_data_t *vm_in, mode_data_t *vm_out, vm_proc_config_t *vm_conf);
int get_vmode(vmode_t vmode_id, mode_data_t *vm_in, mode_data_t *vm_out, vm_proc_config_t *vm_conf);
#endif /* VIDEO_MODES_H_ */

View File

@ -1,84 +0,0 @@
//
// Copyright (C) 2020-2023 Markus Hiienkari <mhiienka@niksula.hut.fi>
//
// This file is part of Open Source Scan Converter project.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
/* Pure LM modes */
#ifdef VM_STATIC_INCLUDE
static
#endif
const mode_data_t video_modes_plm_default[] = {
/* 240p modes */
{ "1600x240", HDMI_Unknown, {1600, 240, 6000, 2046, 0, 262, 202, 15, 150, 3, 0}, DEF_PHASE, {{ 0, 0}}, VIDEO_SDTV, GROUP_240P, (MODE_L5_GEN_4_3), },
{ "1280x240", HDMI_Unknown, {1280, 240, 6000, 1560, 0, 262, 170, 15, 72, 3, 0}, DEF_PHASE, {{ 0, 0}}, VIDEO_SDTV, GROUP_240P, (MODE_L3_GEN_16_9 | MODE_L4_GEN_4_3), },
{ "960x240", HDMI_Unknown, { 960, 240, 6000, 1170, 0, 262, 128, 15, 54, 3, 0}, DEF_PHASE, {{ 0, 0}}, VIDEO_SDTV, GROUP_240P, (MODE_L3_GEN_4_3), },
{ "512x240", HDMI_Unknown, { 512, 240, 6000, 682, 0, 262, 77, 14, 50, 3, 0}, DEF_PHASE, {{ 0, 0}}, VIDEO_SDTV, GROUP_240P, (MODE_L2_512_COL | MODE_L3_512_COL | MODE_L4_512_COL | MODE_L5_512_COL), },
{ "384x240", HDMI_Unknown, { 384, 240, 6000, 512, 0, 262, 59, 14, 37, 3, 0}, DEF_PHASE, {{ 0, 0}}, VIDEO_SDTV, GROUP_240P, (MODE_L2_384_COL | MODE_L3_384_COL | MODE_L4_384_COL | MODE_L5_384_COL), },
{ "320x240", HDMI_Unknown, { 320, 240, 6000, 426, 0, 262, 49, 14, 31, 3, 0}, DEF_PHASE, {{ 0, 0}}, VIDEO_SDTV, GROUP_240P, (MODE_L2_320_COL | MODE_L3_320_COL | MODE_L4_320_COL | MODE_L5_320_COL), },
{ "256x240", HDMI_Unknown, { 256, 240, 6000, 341, 0, 262, 39, 14, 25, 3, 0}, DEF_PHASE, {{ 0, 0}}, VIDEO_SDTV, GROUP_240P, (MODE_L2_256_COL | MODE_L3_256_COL | MODE_L4_256_COL | MODE_L5_256_COL), },
{ "240p", HDMI_240p60, { 720, 240, 6005, 858, 0, 262, 57, 15, 62, 3, 0}, DEF_PHASE, {{ 0, 0}}, VIDEO_SDTV, GROUP_240P, (MODE_PT | MODE_L2), },
/* 288p modes */
{ "1600x240L", HDMI_Unknown, {1600, 240, 5000, 2046, 0, 312, 202, 43, 150, 3, 0}, DEF_PHASE, {{ 0, 0}}, VIDEO_SDTV, GROUP_288P, (MODE_L5_GEN_4_3), },
{ "1280x288", HDMI_Unknown, {1280, 288, 5000, 1560, 0, 312, 170, 19, 72, 3, 0}, DEF_PHASE, {{ 0, 0}}, VIDEO_SDTV, GROUP_288P, (MODE_L3_GEN_16_9 | MODE_L4_GEN_4_3), },
{ "960x288", HDMI_Unknown, { 960, 288, 5000, 1170, 0, 312, 128, 19, 54, 3, 0}, DEF_PHASE, {{ 0, 0}}, VIDEO_SDTV, GROUP_288P, (MODE_L3_GEN_4_3), },
{ "512x240LB", HDMI_Unknown, { 512, 240, 5000, 682, 0, 312, 77, 41, 50, 3, 0}, DEF_PHASE, {{ 0, 0}}, VIDEO_SDTV, GROUP_288P, (MODE_L2_512_COL | MODE_L3_512_COL | MODE_L4_512_COL | MODE_L5_512_COL), },
{ "384x240LB", HDMI_Unknown, { 384, 240, 5000, 512, 0, 312, 59, 41, 37, 3, 0}, DEF_PHASE, {{ 0, 0}}, VIDEO_SDTV, GROUP_288P, (MODE_L2_384_COL | MODE_L3_384_COL | MODE_L4_384_COL | MODE_L5_384_COL), },
{ "320x240LB", HDMI_Unknown, { 320, 240, 5000, 426, 0, 312, 49, 41, 31, 3, 0}, DEF_PHASE, {{ 0, 0}}, VIDEO_SDTV, GROUP_288P, (MODE_L2_320_COL | MODE_L3_320_COL | MODE_L4_320_COL | MODE_L5_320_COL), },
{ "256x240LB", HDMI_Unknown, { 256, 240, 5000, 341, 0, 312, 39, 41, 25, 3, 0}, DEF_PHASE, {{ 0, 0}}, VIDEO_SDTV, GROUP_288P, (MODE_L2_256_COL | MODE_L3_256_COL | MODE_L4_256_COL | MODE_L5_256_COL), },
{ "288p", HDMI_288p50, { 720, 288, 5008, 864, 0, 312, 69, 19, 63, 3, 0}, DEF_PHASE, {{ 0, 0}}, VIDEO_SDTV, GROUP_288P, (MODE_PT | MODE_L2), },
/* 360p: GBI */
{ "480x360", HDMI_Unknown, { 480, 360, 6000, 600, 0, 375, 63, 10, 38, 3, 0}, DEF_PHASE, {{ 0, 0}}, VIDEO_EDTV, GROUP_384P, (MODE_PT | MODE_L2), },
{ "240x360", HDMI_Unknown, { 256, 360, 6000, 300, 0, 375, 24, 10, 18, 3, 0}, DEF_PHASE, {{ 0, 0}}, VIDEO_EDTV, GROUP_384P, (MODE_L2_240x360 | MODE_L3_240x360), },
/* 384p: Sega Model 2 */
{ "384p", HDMI_Unknown, { 496, 384, 5500, 640, 0, 423, 50, 29, 62, 3, 0}, DEF_PHASE, {{ 0, 0}}, VIDEO_EDTV, GROUP_384P, (MODE_PT | MODE_L2), },
/* 400p line3x */
{ "1600x400", HDMI_Unknown, {1600, 400, 7000, 2000, 0, 449, 120, 34, 240, 2, 0}, DEF_PHASE, {{ 0, 0}}, VIDEO_PC, GROUP_384P, (MODE_L3_GEN_16_9), },
/* 720x400@70Hz, VGA Mode 3+/7+ */
{ "720x400_70", HDMI_Unknown, { 720, 400, 7000, 900, 0, 449, 64, 34, 96, 2, 0}, DEF_PHASE, {{ 0, 0}}, VIDEO_PC, GROUP_384P, (MODE_PT | MODE_L2), },
/* 640x400@70Hz, VGA Mode 13h */
{ "640x400_70", HDMI_Unknown, { 640, 400, 7000, 800, 0, 449, 48, 34, 96, 2, 0}, DEF_PHASE, {{ 0, 0}}, VIDEO_PC, GROUP_384P, (MODE_PT | MODE_L2), },
/* 384p: X68k @ 24kHz */
{ "640x384", HDMI_Unknown, { 640, 384, 5500, 800, 0, 492, 48, 63, 96, 2, 0}, DEF_PHASE, {{ 0, 0}}, VIDEO_PC, GROUP_384P, (MODE_PT | MODE_L2), },
/* ~525-line modes */
{ "480i", HDMI_480i60, { 720, 240, 5994, 858, 0, 525, 57, 15, 62, 3, 1}, DEF_PHASE, {{ 0, 0}}, VIDEO_SDTV, GROUP_480I, (MODE_PT | MODE_L2 | MODE_L3_GEN_16_9 | MODE_L4_GEN_4_3), },
{ "480p", HDMI_480p60, { 720, 480, 5994, 858, 0, 525, 60, 30, 62, 6, 0}, DEF_PHASE, {{ 0, 0}}, VIDEO_EDTV, GROUP_480P, (MODE_PT | MODE_L2), },
{ "640x480_60", HDMI_640x480p60, { 640, 480, 6000, 800, 0, 525, 48, 33, 96, 2, 0}, DEF_PHASE, {{ 0, 0}}, VIDEO_PC, GROUP_480P, (MODE_PT | MODE_L2), },
/* 480p PSP in-game */ \
{ "480x272", HDMI_480p60_16x9, { 480, 272, 6000, 858, 0, 525, 177,134, 62, 6, 0}, DEF_PHASE, {{ 0, 0}}, VIDEO_EDTV, GROUP_480P, (MODE_PT | MODE_L2) }, \
/* X68k @ 31kHz */
{ "640x512", HDMI_Unknown, { 640, 512, 6000, 800, 0, 568, 48, 34, 96, 6, 0}, DEF_PHASE, {{ 0, 0}}, VIDEO_PC, GROUP_480P, (MODE_PT | MODE_L2), },
/* ~625-line modes */
{ "576i", HDMI_576i50, { 720, 288, 5000, 864, 0, 625, 69, 19, 63, 3, 1}, DEF_PHASE, {{ 0, 0}}, VIDEO_SDTV, GROUP_576I, (MODE_PT | MODE_L2 | MODE_L3_GEN_16_9 | MODE_L4_GEN_4_3), },
{ "576p", HDMI_576p50, { 720, 576, 5000, 864, 0, 625, 68, 39, 64, 5, 0}, DEF_PHASE, {{ 0, 0}}, VIDEO_EDTV, GROUP_576P, (MODE_PT | MODE_L2), },
{ "800x600_60", HDMI_Unknown, { 800, 600, 6000, 1056, 0, 628, 88, 23, 128, 4, 0}, DEF_PHASE, {{ 0, 0}}, VIDEO_PC, GROUP_NONE, MODE_PT, },
/* CEA 720p modes */
{ "720p_50", HDMI_720p50, {1280, 720, 5000, 1980, 0, 750, 220, 20, 40, 5, 0}, DEF_PHASE, {{ 0, 0}}, (VIDEO_HDTV | VIDEO_PC), GROUP_720P, MODE_PT, },
{ "720p_60", HDMI_720p60, {1280, 720, 6000, 1650, 0, 750, 220, 20, 40, 5, 0}, DEF_PHASE, {{ 0, 0}}, (VIDEO_HDTV | VIDEO_PC), GROUP_720P, MODE_PT, },
/* VESA XGA,1280x960 and SXGA modes */
{ "1024x768", HDMI_Unknown, {1024, 768, 6000, 1344, 0, 806, 160, 29, 136, 6, 0}, DEF_PHASE, {{ 0, 0}}, VIDEO_PC, GROUP_NONE, MODE_PT, },
{ "1280x960", HDMI_Unknown, {1280, 960, 6000, 1800, 0, 1000, 312, 36, 112, 3, 0}, DEF_PHASE, {{ 0, 0}}, VIDEO_PC, GROUP_NONE, MODE_PT, },
{ "1280x1024", HDMI_Unknown, {1280, 1024, 6000, 1688, 0, 1066, 248, 38, 112, 3, 0}, DEF_PHASE, {{ 0, 0}}, VIDEO_PC, GROUP_NONE, MODE_PT, },
/* PS2 GSM 960i mode */
{ "640x960i", HDMI_Unknown, { 640, 480, 6000, 800, 0, 1050, 48, 33, 96, 2, 1}, DEF_PHASE, {{ 0, 0}}, VIDEO_EDTV, GROUP_1080I, (MODE_PT | MODE_L2), },
/* CEA 1080i/p modes */
{ "1080i_50", HDMI_1080i50, {1920, 540, 5000, 2640, 0, 1125, 148, 15, 44, 5, 1}, DEF_PHASE, {{ 0, 0}}, (VIDEO_HDTV | VIDEO_PC), GROUP_1080I, (MODE_PT | MODE_L2), },
{ "1080i_60", HDMI_1080i60, {1920, 540, 6000, 2200, 0, 1125, 148, 15, 44, 5, 1}, DEF_PHASE, {{ 0, 0}}, (VIDEO_HDTV | VIDEO_PC), GROUP_1080I, (MODE_PT | MODE_L2), },
{ "1080p_50", HDMI_1080p50, {1920, 1080, 5000, 2640, 0, 1125, 148, 36, 44, 5, 0}, DEF_PHASE, {{ 0, 0}}, (VIDEO_HDTV | VIDEO_PC), GROUP_1080P, MODE_PT, },
{ "1080p_60", HDMI_1080p60, {1920, 1080, 6000, 2200, 0, 1125, 148, 36, 44, 5, 0}, DEF_PHASE, {{ 0, 0}}, (VIDEO_HDTV | VIDEO_PC), GROUP_1080P, MODE_PT, },
/* VESA UXGA mode */
{ "1600x1200", HDMI_Unknown, {1600, 1200, 6000, 2160, 0, 1250, 304, 46, 192, 3, 0}, DEF_PHASE, {{ 0, 0}}, VIDEO_PC, GROUP_NONE, MODE_PT, },
};

View File

@ -48,41 +48,6 @@ void pcm_source_sel(pcm_input_t input) {
pcm1862_writereg(PCM1862_ADC1R, (1<<6)|adc_ch);
}
void pcm_set_stereo_mode(int mono_enable) {
uint32_t gain;
int i;
const uint8_t chregs[] = {0, 1, 6, 7};
uint32_t stereo_cfg[] = {0x100000, 0x0, 0x0, 0x100000};
uint32_t mono_cfg[] = {0x0804DC, 0x0804DC, 0x0804DC, 0x0804DC};
uint32_t *ch_cfg = mono_enable ? mono_cfg : stereo_cfg;
pcm1862_writereg(PCM1862_PAGESEL, 1);
for (i=0; i<sizeof(chregs); i++) {
pcm1862_writereg(PCM1862_DSP2_ADDR, chregs[i]);
pcm1862_writereg(PCM1862_DSP2_WDATA0, (ch_cfg[i] >> 16) & 0xff);
pcm1862_writereg(PCM1862_DSP2_WDATA1, (ch_cfg[i] >> 8) & 0xff);
pcm1862_writereg(PCM1862_DSP2_WDATA2, ch_cfg[i] & 0xff);
pcm1862_writereg(PCM1862_DSP2_CFG, (1<<0));
while ((pcm1862_readreg(PCM1862_DSP2_CFG) & ((1<<0)|(1<<2))) != 0) {}
}
/*for (i=0; i<12; i++) {
pcm1862_writereg(0x02, i);
pcm1862_writereg(0x01, (1<<1));
while ((pcm1862_readreg(0x01) & (1<<1)) != 0) {}
gain = pcm1862_readreg(0x08) << 16;
gain |= pcm1862_readreg(0x09) << 8;
gain |= pcm1862_readreg(0x0A);
printf("ch%u gain: 0x%x\n", i, gain);
}*/
pcm1862_writereg(PCM1862_PAGESEL, 0);
}
void pcm_set_gain(alt_8 db_gain) {
alt_8 gain_val = 2*db_gain;

View File

@ -32,8 +32,6 @@ typedef enum {
void pcm_source_sel(pcm_input_t input);
void pcm_set_stereo_mode(int mono_enable);
void pcm_set_gain(alt_8 db_gain);
int pcm1862_init();

View File

@ -23,9 +23,6 @@
#define PCM1862_BASE (0x94>>1)
#define PCM1862_PAGESEL 0x00
/* Page 0 registers */
#define PCM1862_PGA1L 0x01
#define PCM1862_PGA1R 0x02
#define PCM1862_PGA2L 0x03
@ -59,17 +56,4 @@
#define PCM1862_PWR_CTRL 0x70
#define PCM1862_DSP_CTRL 0x71
/* Page 1 registers */
#define PCM1862_DSP2_CFG 0x01
#define PCM1862_DSP2_ADDR 0x02
#define PCM1862_DSP2_WDATA0 0x04
#define PCM1862_DSP2_WDATA1 0x05
#define PCM1862_DSP2_WDATA2 0x06
#define PCM1862_DSP2_RDATA0 0x08
#define PCM1862_DSP2_RDATA1 0x09
#define PCM1862_DSP2_RDATA2 0x0A
#endif /* PCM1862_REGS_H_ */

View File

@ -31,7 +31,7 @@
#define WRDELAY 20
#define CLEARDELAY 800
extern alt_u32 sys_ctrl;
extern alt_u16 sys_ctrl;
static void lcd_cmd(alt_u8 cmd, alt_u16 postdelay) {
SPI_write(I2CA_BASE, &cmd, 1);

View File

@ -1,5 +1,5 @@
//
// Copyright (C) 2015-2023 Markus Hiienkari <mhiienka@niksula.hut.fi>
// Copyright (C) 2015-2018 Markus Hiienkari <mhiienka@niksula.hut.fi>
//
// This file is part of Open Source Scan Converter project.
//
@ -65,11 +65,11 @@ static void tvp_set_clamp_alc(video_type type, alt_u8 clamp_ref_offset, alt_8 cl
alt_u8 clamp_width, alc_offset;
switch (type) {
/*case VIDEO_LDTV:
case VIDEO_LDTV:
clamp_pos += 2;
clamp_width = 6;
alc_offset = 1;
break;*/
break;
case VIDEO_HDTV:
clamp_pos += 50;
clamp_width = 32;
@ -91,8 +91,6 @@ static void tvp_set_clamp_alc(video_type type, alt_u8 clamp_ref_offset, alt_8 cl
else if (clamp_pos + clamp_width + alc_offset > 255)
clamp_pos = 255 - alc_offset - clamp_width;
printf("Clamp pos: %u, width: %u (ref_offset: %u, user_offset %d)\n", clamp_pos, clamp_width, clamp_ref_offset, clamp_user_offset);
tvp_writereg(TVP_CLAMPSTART, (alt_u8)clamp_pos);
tvp_writereg(TVP_CLAMPWIDTH, clamp_width);
@ -147,30 +145,24 @@ inline void tvp_reset()
inline void tvp_disable_output()
{
alt_u8 syncproc_rst = tvp_readreg(TVP_MISCCTRL4) | (1<<7);
tvp_writereg(TVP_MISCCTRL1, 0x13);
usleep(10000);
tvp_writereg(TVP_MISCCTRL2, 0x03);
usleep(10000);
tvp_writereg(TVP_MISCCTRL4, syncproc_rst);
usleep(1000);
tvp_writereg(TVP_MISCCTRL4, syncproc_rst & 0x7F);
}
inline void tvp_enable_output()
{
tvp_writereg(TVP_MISCCTRL2, 0x00);
}
inline void tvp_powerdown()
{
alt_u8 syncproc_rst = tvp_readreg(TVP_MISCCTRL4) | (1<<7);
tvp_writereg(TVP_MISCCTRL4, syncproc_rst);
usleep(1000);
tvp_writereg(TVP_MISCCTRL4, syncproc_rst & 0x7F);
usleep(1000);
tvp_writereg(TVP_MISCCTRL1, 0x13);
tvp_writereg(TVP_POWERCTRL, 0x07);
}
inline void tvp_powerup()
{
usleep(10000);
tvp_writereg(TVP_MISCCTRL1, 0x11);
tvp_writereg(TVP_POWERCTRL, 0x00);
usleep(10000);
tvp_writereg(TVP_MISCCTRL2, 0x02);
usleep(10000);
}
inline void tvp_set_hpllcoast(alt_u8 pre, alt_u8 post)
@ -200,6 +192,9 @@ void tvp_init()
.c_gain = DEFAULT_COARSE_GAIN,
};
// disable output
tvp_disable_output();
// Set default configuration (skip those which match register reset values)
// Configure external refclk, HPLL generated pclk
@ -213,9 +208,6 @@ void tvp_init()
// NOTE: Value 1 syncs the edges!
tvp_writereg(TVP_VSOUTALIGN, 1);
// Bypass VSYNC processing
tvp_writereg(TVP_MISCCTRL4, 0x09);
// Set default CSC coeffs.
tvp_sel_csc(&csc_coeffs[0]);
@ -250,10 +242,6 @@ void tvp_init()
//set analog (coarse) gain to max recommended value (-> 91% of the ADC range with 0.7Vpp input)
//set rest of the gain digitally (fine) to utilize 100% of the range at the output (0.91*(1+(26/256)) = 1)
tvp_set_gain_offset(&def_gain_offs);
// Disable PLL and ADC but enable outputs to enable frontend mode detection
tvp_enable_output();
tvp_powerdown();
}
void tvp_set_gain_offset(color_setup_t *col) {
@ -356,12 +344,17 @@ void tvp_set_clp_lpf(alt_u8 val)
printf("CLP LPF value set to 0x%x\n", val);
}
void tvp_set_hpll_phase(alt_u8 val)
alt_u8 tvp_set_hpll_phase(alt_u8 val, alt_u8 sample_mult)
{
alt_u8 sample_sel;
alt_u8 status = tvp_readreg(TVP_HPLLPHASE) & 0x07;
sample_sel = (val*sample_mult)/32;
val = val*sample_mult % 32;
tvp_writereg(TVP_HPLLPHASE, (val<<3)|status);
printf("TVP Phase set to %u/32 (%u deg)\n", val, (val*11250)/1000);
printf("Phase selection: %u/%u (FPGA), %u/32 (TVP)\n", sample_sel+1, sample_mult, val+1);
return sample_sel;
}
void tvp_set_sog_thold(alt_u8 val)
@ -388,14 +381,14 @@ void tvp_source_setup(video_type type, alt_u16 h_samplerate, alt_u16 refclks_per
// Macrovision stripper filters out glitches and serration pulses that may occur outside of sync window (HSYNC_lead +- TVP_MVSWIDTH*37ns). Enabled for all inputs.
switch (type) {
case VIDEO_PC:
tvp_writereg(TVP_MISCCTRL4, 0x0D);
tvp_writereg(TVP_MISCCTRL4, 0x0C);
break;
//case VIDEO_LDTV:
case VIDEO_LDTV:
case VIDEO_SDTV:
case VIDEO_EDTV:
case VIDEO_HDTV:
default:
tvp_writereg(TVP_MISCCTRL4, 0x09);
tvp_writereg(TVP_MISCCTRL4, 0x08);
break;
}
@ -419,7 +412,7 @@ void tvp_source_sel(tvp_input_t input, tvp_sync_input_t syncinput, video_format
else // RGBS
tvp_writereg(TVP_SYNCCTRL1, 0x53);
usleep(100000);
usleep(1000);
sync_status = tvp_readreg(TVP_SYNCSTAT);
if (sync_status & (1<<7))
printf("%s detected, %s polarity\n", (sync_status & (1<<3)) ? "Csync" : "Hsync", (sync_status & (1<<5)) ? "pos" : "neg");

View File

@ -1,5 +1,5 @@
//
// Copyright (C) 2015-2023 Markus Hiienkari <mhiienka@niksula.hut.fi>
// Copyright (C) 2015-2018 Markus Hiienkari <mhiienka@niksula.hut.fi>
//
// This file is part of Open Source Scan Converter project.
//
@ -26,6 +26,7 @@
#define DEFAULT_VSYNC_THOLD 0x44
#define DEFAULT_LINELEN_TOL 0x06
#define DEFAULT_SAMPLER_PHASE 0x10
#define DEFAULT_PRE_COAST 1
#define DEFAULT_POST_COAST 0
#define DEFAULT_SYNC_LPF 0
@ -73,6 +74,16 @@ typedef struct {
alt_u16 B_Pr;
} ypbpr_to_rgb_csc_t;
typedef struct {
alt_u8 r_f_off;
alt_u8 g_f_off;
alt_u8 b_f_off;
alt_u8 r_f_gain;
alt_u8 g_f_gain;
alt_u8 b_f_gain;
alt_u8 c_gain;
} __attribute__((packed)) color_setup_t;
inline alt_u32 tvp_readreg(alt_u32 regaddr);
@ -84,10 +95,6 @@ inline void tvp_disable_output();
inline void tvp_enable_output();
inline void tvp_powerdown();
inline void tvp_powerup();
inline void tvp_set_hpllcoast(alt_u8 pre, alt_u8 post);
inline void tvp_set_linelen_tol(alt_u8 val);
@ -108,7 +115,7 @@ void tvp_set_sync_lpf(alt_u8 val);
void tvp_set_clp_lpf(alt_u8 val);
void tvp_set_hpll_phase(alt_u8 val);
alt_u8 tvp_set_hpll_phase(alt_u8 val, alt_u8 sample_mult);
void tvp_set_sog_thold(alt_u8 val);

View File

@ -0,0 +1,295 @@
//
// Copyright (C) 2015-2017 Markus Hiienkari <mhiienka@niksula.hut.fi>
//
// This file is part of Open Source Scan Converter project.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include "system.h"
#include "av_controller.h"
#include "video_modes.h"
#define LINECNT_MAX_TOLERANCE 30
extern avmode_t cm;
const mode_data_t video_modes_default[] = VIDEO_MODES_DEF;
mode_data_t video_modes[VIDEO_MODES_CNT];
/* TODO: rewrite, check hz etc. */
alt_8 get_mode_id(alt_u32 totlines, alt_u8 progressive, alt_u32 hz, alt_u8 h_syncinlen)
{
alt_8 i;
alt_u8 num_modes = sizeof(video_modes)/sizeof(mode_data_t);
mode_flags valid_lm[] = { MODE_PT, (MODE_L2 | (MODE_L2<<cm.cc.l2_mode)), (MODE_L3_GEN_16_9<<cm.cc.l3_mode), (MODE_L4_GEN_4_3<<cm.cc.l4_mode), (MODE_L5_GEN_4_3<<cm.cc.l5_mode) };
mode_flags target_lm;
alt_u8 pt_only = 0;
// one for each video_group
alt_u8* group_ptr[] = { &pt_only, &cm.cc.pm_240p, &cm.cc.pm_384p, &cm.cc.pm_480i, &cm.cc.pm_480p, &cm.cc.pm_1080i };
for (i=0; i<num_modes; i++) {
switch (video_modes[i].group) {
case GROUP_384P:
//fixed Line2x/3x mode for 240x360p
valid_lm[2] = MODE_L2_240x360;
valid_lm[3] = MODE_L3_240x360;
valid_lm[4] = MODE_L3_GEN_16_9;
if (video_modes[i].v_total == 449) {
if (!strncmp(video_modes[i].name, "720x400", 7)) {
if (cm.cc.s400p_mode == 0)
continue;
} else if (!strncmp(video_modes[i].name, "640x400", 7)) {
if (cm.cc.s400p_mode == 1)
continue;
}
}
break;
case GROUP_480I:
//fixed Line3x/4x mode for 480i
valid_lm[2] = MODE_L3_GEN_16_9;
valid_lm[3] = MODE_L4_GEN_4_3;
break;
case GROUP_480P:
if (video_modes[i].vic == HDMI_480p60) {
switch (cm.cc.s480p_mode) {
case 0: // Auto
if (h_syncinlen > 82)
continue;
break;
case 1: // DTV 480p
break;
default:
continue;
}
} else if (video_modes[i].flags & MODE_L2_480x272) { // hit "480x272" on the list
switch (cm.cc.s480p_mode) {
case 3: // PSP 480x272
// force optimized Line2x mode for 480x272
valid_lm[1] = MODE_L2_480x272;
break;
default:
continue;
}
} else if (video_modes[i].vic == HDMI_640x480p60) {
switch (cm.cc.s480p_mode) {
case 0: // Auto
case 2: // VESA 640x480@60
break;
default:
continue;
}
}
break;
default:
break;
}
// Skip potentially conflicting 50Hz presets if refresh rate is much higher
if ((video_modes[i].vic == HDMI_576p50) ||
(video_modes[i].vic == HDMI_720p50) ||
(video_modes[i].vic == HDMI_1080i50) ||
(video_modes[i].vic == HDMI_1080p50))
{
if (hz >= 55)
continue;
}
target_lm = valid_lm[*group_ptr[video_modes[i].group]];
if ((target_lm & video_modes[i].flags) && (progressive == !(video_modes[i].flags & MODE_INTERLACED)) && (totlines <= (video_modes[i].v_total+LINECNT_MAX_TOLERANCE))) {
// defaults
cm.tx_pixelrep = TX_PIXELREP_DISABLE;
cm.hdmitx_pixr_ifr = 0;
cm.hdmitx_vic = HDMI_Unknown;
cm.sample_mult = 1;
cm.hsync_cut = 0;
cm.target_lm = target_lm & video_modes[i].flags; //ensure L2 mode uniqueness
switch (cm.target_lm) {
case MODE_PT:
cm.fpga_vmultmode = FPGA_V_MULTMODE_1X;
cm.fpga_hmultmode = FPGA_H_MULTMODE_FULLWIDTH;
cm.hdmitx_vic = video_modes[i].vic;
// Upsample / pixel-repeat horizontal resolution of 240p/480i/384p modes to fulfill min. 25MHz TMDS clock requirement
if ((video_modes[i].group == GROUP_240P) || (video_modes[i].group == GROUP_480I) || ((video_modes[i].group == GROUP_384P) && (video_modes[i].flags & MODE_PLLDIVBY2))) {
if (cm.cc.upsample2x)
cm.sample_mult = 2;
else
cm.tx_pixelrep = TX_PIXELREP_2X;
cm.hdmitx_pixr_ifr = TX_PIXELREP_2X;
}
break;
case MODE_L2:
cm.fpga_vmultmode = FPGA_V_MULTMODE_2X;
// Use native 2x sampling with low-res modes when possible to minimize jitter and generate min. 25MHz input pclk for FPGA PLL
if ((!cm.cc.vga_ilace_fix) && (video_modes[i].h_total < 1400) && ((video_modes[i].group == GROUP_240P) || (video_modes[i].group == GROUP_384P) || (video_modes[i].group == GROUP_480I))) {
cm.fpga_hmultmode = FPGA_H_MULTMODE_OPTIMIZED_1X;
cm.sample_mult = 2;
} else {
cm.fpga_hmultmode = FPGA_H_MULTMODE_FULLWIDTH;
}
// Upsample / pixel-repeat horizontal resolution of 384p/480p/960i modes
if ((video_modes[i].group == GROUP_384P) || (video_modes[i].group == GROUP_480P) || ((video_modes[i].group == GROUP_1080I) && (video_modes[i].h_total < 1200))) {
if (cm.cc.upsample2x) {
cm.fpga_hmultmode = FPGA_H_MULTMODE_FULLWIDTH;
cm.sample_mult = 2;
} else {
cm.tx_pixelrep = TX_PIXELREP_2X;
}
}
break;
case MODE_L2_512_COL:
case MODE_L2_480x272:
cm.fpga_vmultmode = FPGA_V_MULTMODE_2X;
cm.fpga_hmultmode = FPGA_H_MULTMODE_OPTIMIZED;
cm.sample_mult = 2;
break;
case MODE_L2_256_COL:
cm.fpga_vmultmode = FPGA_V_MULTMODE_2X;
cm.fpga_hmultmode = FPGA_H_MULTMODE_OPTIMIZED_1X;
cm.sample_mult = 6;
break;
case MODE_L2_320_COL:
case MODE_L2_384_COL:
cm.fpga_vmultmode = FPGA_V_MULTMODE_2X;
cm.fpga_hmultmode = FPGA_H_MULTMODE_OPTIMIZED_1X;
cm.sample_mult = 4;
break;
case MODE_L2_240x360:
cm.fpga_vmultmode = FPGA_V_MULTMODE_2X;
cm.fpga_hmultmode = FPGA_H_MULTMODE_OPTIMIZED;
cm.sample_mult = 5;
break;
case MODE_L3_GEN_16_9:
cm.fpga_vmultmode = FPGA_V_MULTMODE_3X;
cm.fpga_hmultmode = FPGA_H_MULTMODE_FULLWIDTH;
// Upsample / pixel-repeat horizontal resolution of 480i mode
if (video_modes[i].group == GROUP_480I) {
if (cm.cc.upsample2x)
cm.sample_mult = 2;
else
cm.tx_pixelrep = TX_PIXELREP_2X;
}
break;
case MODE_L3_GEN_4_3:
cm.fpga_vmultmode = FPGA_V_MULTMODE_3X;
cm.fpga_hmultmode = FPGA_H_MULTMODE_ASPECTFIX;
break;
case MODE_L3_512_COL:
cm.fpga_vmultmode = FPGA_V_MULTMODE_3X;
cm.fpga_hmultmode = FPGA_H_MULTMODE_OPTIMIZED;
cm.sample_mult = 2;
break;
case MODE_L3_384_COL:
cm.fpga_vmultmode = FPGA_V_MULTMODE_3X;
cm.fpga_hmultmode = FPGA_H_MULTMODE_OPTIMIZED;
cm.sample_mult = 3;
break;
case MODE_L3_320_COL:
cm.fpga_vmultmode = FPGA_V_MULTMODE_3X;
cm.fpga_hmultmode = FPGA_H_MULTMODE_OPTIMIZED;
cm.sample_mult = 4;
break;
case MODE_L3_256_COL:
cm.fpga_vmultmode = FPGA_V_MULTMODE_3X;
cm.fpga_hmultmode = FPGA_H_MULTMODE_OPTIMIZED;
cm.sample_mult = 5;
break;
case MODE_L3_240x360:
cm.fpga_vmultmode = FPGA_V_MULTMODE_3X;
cm.fpga_hmultmode = FPGA_H_MULTMODE_OPTIMIZED;
cm.sample_mult = 7;
cm.hsync_cut = 13;
break;
case MODE_L4_GEN_4_3:
cm.fpga_vmultmode = FPGA_V_MULTMODE_4X;
cm.fpga_hmultmode = FPGA_H_MULTMODE_FULLWIDTH;
// Upsample / pixel-repeat horizontal resolution of 480i mode
if (video_modes[i].group == GROUP_480I) {
if (cm.cc.upsample2x)
cm.sample_mult = 2;
else
cm.tx_pixelrep = TX_PIXELREP_2X;
}
break;
case MODE_L4_512_COL:
cm.fpga_vmultmode = FPGA_V_MULTMODE_4X;
cm.fpga_hmultmode = FPGA_H_MULTMODE_OPTIMIZED;
cm.sample_mult = 2;
break;
case MODE_L4_384_COL:
cm.fpga_vmultmode = FPGA_V_MULTMODE_4X;
cm.fpga_hmultmode = FPGA_H_MULTMODE_OPTIMIZED;
cm.sample_mult = 3;
break;
case MODE_L4_320_COL:
cm.fpga_vmultmode = FPGA_V_MULTMODE_4X;
cm.fpga_hmultmode = FPGA_H_MULTMODE_OPTIMIZED;
cm.sample_mult = 4;
break;
case MODE_L4_256_COL:
cm.fpga_vmultmode = FPGA_V_MULTMODE_4X;
cm.fpga_hmultmode = FPGA_H_MULTMODE_OPTIMIZED;
cm.sample_mult = 5;
break;
case MODE_L5_GEN_4_3:
cm.fpga_vmultmode = FPGA_V_MULTMODE_5X;
cm.fpga_hmultmode = FPGA_H_MULTMODE_FULLWIDTH;
cm.hsync_cut = 120;
break;
case MODE_L5_512_COL:
cm.fpga_vmultmode = FPGA_V_MULTMODE_5X;
cm.fpga_hmultmode = FPGA_H_MULTMODE_OPTIMIZED;
cm.sample_mult = 3;
cm.hsync_cut = 40;
break;
case MODE_L5_384_COL:
cm.fpga_vmultmode = FPGA_V_MULTMODE_5X;
cm.fpga_hmultmode = FPGA_H_MULTMODE_OPTIMIZED;
cm.sample_mult = 4;
cm.hsync_cut = 30;
break;
case MODE_L5_320_COL:
cm.fpga_vmultmode = FPGA_V_MULTMODE_5X;
cm.fpga_hmultmode = FPGA_H_MULTMODE_OPTIMIZED;
cm.sample_mult = 5;
cm.hsync_cut = 24;
break;
case MODE_L5_256_COL:
cm.fpga_vmultmode = FPGA_V_MULTMODE_5X;
cm.fpga_hmultmode = FPGA_H_MULTMODE_OPTIMIZED;
cm.sample_mult = 6;
cm.hsync_cut = 20;
break;
default:
printf("WARNING: invalid target_lm\n");
continue;
break;
}
if (cm.hdmitx_vic == HDMI_Unknown)
cm.hdmitx_vic = cm.cc.default_vic;
return i;
}
}
return -1;
}

View File

@ -0,0 +1,183 @@
//
// Copyright (C) 2015-2019 Markus Hiienkari <mhiienka@niksula.hut.fi>
//
// This file is part of Open Source Scan Converter project.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
#ifndef VIDEO_MODES_H_
#define VIDEO_MODES_H_
#include <alt_types.h>
#include "sysconfig.h"
#include "it6613_sys.h"
#define H_TOTAL_MIN 300
#define H_TOTAL_MAX 2800
#define H_TOTAL_ADJ_MAX 19
#define H_SYNCLEN_MIN 10
#define H_SYNCLEN_MAX 255
#define H_BPORCH_MIN 1
#define H_BPORCH_MAX 255
#define H_ACTIVE_MIN 200
#define H_ACTIVE_MAX 1920
#define V_SYNCLEN_MIN 1
#define V_SYNCLEN_MAX 7
#define V_BPORCH_MIN 1
#define V_BPORCH_MAX 236 // 255 - 12 for L5FMT_1920x1080 - 7 for V_SYNCLEN_MAX
#define V_ACTIVE_MIN 160
#define V_ACTIVE_MAX 1200
typedef enum {
FORMAT_RGBS = 0,
FORMAT_RGBHV = 1,
FORMAT_RGsB = 2,
FORMAT_YPbPr = 3
} video_format;
typedef enum {
VIDEO_LDTV = (1<<0),
VIDEO_SDTV = (1<<1),
VIDEO_EDTV = (1<<2),
VIDEO_HDTV = (1<<3),
VIDEO_PC = (1<<4),
} video_type;
typedef enum {
GROUP_NONE = 0,
GROUP_240P = 1,
GROUP_384P = 2,
GROUP_480I = 3,
GROUP_480P = 4,
GROUP_1080I = 5,
} video_group;
typedef enum {
MODE_INTERLACED = (1<<0),
MODE_PLLDIVBY2 = (1<<1),
//at least one of the flags below must be set for each mode
MODE_PT = (1<<2),
MODE_L2 = (1<<3),
MODE_L2_512_COL = (1<<4),
MODE_L2_384_COL = (1<<5),
MODE_L2_320_COL = (1<<6),
MODE_L2_256_COL = (1<<7),
MODE_L2_240x360 = (1<<8),
MODE_L2_480x272 = (1<<9),
MODE_L3_GEN_16_9 = (1<<10),
MODE_L3_GEN_4_3 = (1<<11),
MODE_L3_512_COL = (1<<12),
MODE_L3_384_COL = (1<<13),
MODE_L3_320_COL = (1<<14),
MODE_L3_256_COL = (1<<15),
MODE_L3_240x360 = (1<<16),
MODE_L4_GEN_4_3 = (1<<17),
MODE_L4_512_COL = (1<<18),
MODE_L4_384_COL = (1<<19),
MODE_L4_320_COL = (1<<20),
MODE_L4_256_COL = (1<<21),
MODE_L5_GEN_4_3 = (1<<22),
MODE_L5_512_COL = (1<<23),
MODE_L5_384_COL = (1<<24),
MODE_L5_320_COL = (1<<25),
MODE_L5_256_COL = (1<<26),
} mode_flags;
typedef struct {
char name[10];
HDMI_Video_Type vic:5;
alt_u16 h_active:11;
alt_u16 v_active;
alt_u16 h_total;
alt_u8 h_total_adj:5;
alt_u16 v_total:11;
alt_u8 h_backporch;
alt_u8 v_backporch;
alt_u8 h_synclen;
alt_u8 v_synclen;
alt_u8 sampler_phase;
video_type type:5;
video_group group:3;
mode_flags flags;
} mode_data_t;
#define VIDEO_MODES_DEF { \
/* 240p modes */ \
{ "1600x240", HDMI_Unknown, 1600, 240, 2046, 0, 262, 202, 15, 150, 3, DEFAULT_SAMPLER_PHASE, VIDEO_SDTV, GROUP_240P, (MODE_L5_GEN_4_3 | MODE_PLLDIVBY2) }, \
{ "1280x240", HDMI_Unknown, 1280, 240, 1560, 0, 262, 170, 15, 72, 3, DEFAULT_SAMPLER_PHASE, VIDEO_SDTV, GROUP_240P, (MODE_L3_GEN_16_9 | MODE_L4_GEN_4_3 | MODE_PLLDIVBY2) }, \
{ "960x240", HDMI_Unknown, 960, 240, 1170, 0, 262, 128, 15, 54, 3, DEFAULT_SAMPLER_PHASE, VIDEO_SDTV, GROUP_240P, (MODE_L3_GEN_4_3 | MODE_PLLDIVBY2) }, \
{ "512x240", HDMI_Unknown, 512, 240, 682, 0, 262, 77, 14, 50, 3, DEFAULT_SAMPLER_PHASE, VIDEO_SDTV, GROUP_240P, (MODE_L2_512_COL | MODE_L3_512_COL | MODE_L4_512_COL | MODE_L5_512_COL) }, \
{ "384x240", HDMI_Unknown, 384, 240, 512, 0, 262, 59, 14, 37, 3, DEFAULT_SAMPLER_PHASE, VIDEO_SDTV, GROUP_240P, (MODE_L2_384_COL | MODE_L3_384_COL | MODE_L4_384_COL | MODE_L5_384_COL) }, \
{ "320x240", HDMI_Unknown, 320, 240, 426, 0, 262, 49, 14, 31, 3, DEFAULT_SAMPLER_PHASE, VIDEO_SDTV, GROUP_240P, (MODE_L2_320_COL | MODE_L3_320_COL | MODE_L4_320_COL | MODE_L5_320_COL) }, \
{ "256x240", HDMI_Unknown, 256, 240, 341, 0, 262, 39, 14, 25, 3, DEFAULT_SAMPLER_PHASE, VIDEO_SDTV, GROUP_240P, (MODE_L2_256_COL | MODE_L3_256_COL | MODE_L4_256_COL | MODE_L5_256_COL) }, \
{ "240p", HDMI_240p60, 720, 240, 858, 0, 262, 57, 15, 62, 3, DEFAULT_SAMPLER_PHASE, VIDEO_SDTV, GROUP_240P, (MODE_PT | MODE_L2 | MODE_PLLDIVBY2) }, \
/* 288p modes */ \
{ "1600x240L", HDMI_Unknown, 1600, 240, 2046, 0, 312, 202, 41, 150, 3, DEFAULT_SAMPLER_PHASE, VIDEO_SDTV, GROUP_240P, (MODE_L5_GEN_4_3 | MODE_PLLDIVBY2) }, \
{ "1280x288", HDMI_Unknown, 1280, 288, 1560, 0, 312, 170, 15, 72, 3, DEFAULT_SAMPLER_PHASE, VIDEO_SDTV, GROUP_240P, (MODE_L3_GEN_16_9 | MODE_L4_GEN_4_3 | MODE_PLLDIVBY2) }, \
{ "960x288", HDMI_Unknown, 960, 288, 1170, 0, 312, 128, 15, 54, 3, DEFAULT_SAMPLER_PHASE, VIDEO_SDTV, GROUP_240P, (MODE_L3_GEN_4_3 | MODE_PLLDIVBY2) }, \
{ "512x240LB", HDMI_Unknown, 512, 240, 682, 0, 312, 77, 41, 50, 3, DEFAULT_SAMPLER_PHASE, VIDEO_SDTV, GROUP_240P, (MODE_L2_512_COL | MODE_L3_512_COL | MODE_L4_512_COL | MODE_L5_512_COL) }, \
{ "384x240LB", HDMI_Unknown, 384, 240, 512, 0, 312, 59, 41, 37, 3, DEFAULT_SAMPLER_PHASE, VIDEO_SDTV, GROUP_240P, (MODE_L2_384_COL | MODE_L3_384_COL | MODE_L4_384_COL | MODE_L5_384_COL) }, \
{ "320x240LB", HDMI_Unknown, 320, 240, 426, 0, 312, 49, 41, 31, 3, DEFAULT_SAMPLER_PHASE, VIDEO_SDTV, GROUP_240P, (MODE_L2_320_COL | MODE_L3_320_COL | MODE_L4_320_COL | MODE_L5_320_COL) }, \
{ "256x240LB", HDMI_Unknown, 256, 240, 341, 0, 312, 39, 41, 25, 3, DEFAULT_SAMPLER_PHASE, VIDEO_SDTV, GROUP_240P, (MODE_L2_256_COL | MODE_L3_256_COL | MODE_L4_256_COL | MODE_L5_256_COL) }, \
{ "288p", HDMI_288p50, 720, 288, 864, 0, 312, 69, 19, 63, 3, DEFAULT_SAMPLER_PHASE, VIDEO_SDTV, GROUP_240P, (MODE_PT | MODE_L2 | MODE_PLLDIVBY2) }, \
/* 360p: GBI */ \
{ "480x360", HDMI_Unknown, 480, 360, 600, 0, 375, 63, 10, 38, 3, DEFAULT_SAMPLER_PHASE, VIDEO_EDTV, GROUP_384P, (MODE_PT | MODE_L2 | MODE_PLLDIVBY2) }, \
{ "240x360", HDMI_Unknown, 256, 360, 300, 0, 375, 24, 10, 18, 3, DEFAULT_SAMPLER_PHASE, VIDEO_EDTV, GROUP_384P, (MODE_L2_240x360 | MODE_L3_240x360) }, \
/* 384p: Sega Model 2 (real vtotal=423, avoid collision with PC88/98 and VGA400p) */ \
{ "384p", HDMI_Unknown, 496, 384, 640, 0, 408, 50, 29, 62, 3, DEFAULT_SAMPLER_PHASE, VIDEO_EDTV, GROUP_384P, (MODE_PT | MODE_L2 | MODE_PLLDIVBY2) }, \
/* 400p line3x */ \
{ "1600x400", HDMI_Unknown, 1600, 400, 2000, 0, 449, 120, 34, 240, 2, DEFAULT_SAMPLER_PHASE, VIDEO_PC, GROUP_384P, (MODE_L3_GEN_16_9) }, \
/* 720x400@70Hz, VGA Mode 3+/7+ */ \
{ "720x400", HDMI_Unknown, 720, 400, 900, 0, 449, 64, 34, 96, 2, DEFAULT_SAMPLER_PHASE, VIDEO_PC, GROUP_384P, (MODE_PT | MODE_L2) }, \
/* 640x400@70Hz, VGA Mode 13h */ \
{ "640x400", HDMI_Unknown, 640, 400, 800, 0, 449, 48, 34, 96, 2, DEFAULT_SAMPLER_PHASE, VIDEO_PC, GROUP_384P, (MODE_PT | MODE_L2) }, \
/* 384p: X68k @ 24kHz */ \
{ "640x384", HDMI_Unknown, 640, 384, 800, 0, 492, 48, 63, 96, 2, DEFAULT_SAMPLER_PHASE, VIDEO_PC, GROUP_384P, (MODE_PT | MODE_L2 | MODE_PLLDIVBY2) }, \
/* ~525-line modes */ \
{ "480i", HDMI_480i60, 720, 240, 858, 0, 525, 57, 15, 62, 3, DEFAULT_SAMPLER_PHASE, VIDEO_SDTV, GROUP_480I, (MODE_PT | MODE_L2 | MODE_L3_GEN_16_9 | MODE_L4_GEN_4_3 | MODE_PLLDIVBY2 | MODE_INTERLACED) }, \
{ "480p", HDMI_480p60, 720, 480, 858, 0, 525, 60, 30, 62, 6, DEFAULT_SAMPLER_PHASE, VIDEO_EDTV, GROUP_480P, (MODE_PT | MODE_L2) }, \
/* 480p PSP in-game */ \
{ "480x272", HDMI_480p60_16x9, 480, 272, 858, 0, 525, 177,134, 62, 6, DEFAULT_SAMPLER_PHASE, VIDEO_EDTV, GROUP_480P, (MODE_PT | MODE_L2_480x272) }, \
{ "640x480", HDMI_640x480p60, 640, 480, 800, 0, 525, 48, 33, 96, 2, DEFAULT_SAMPLER_PHASE, VIDEO_PC, GROUP_480P, (MODE_PT | MODE_L2) }, \
/* X68k @ 31kHz */ \
{ "640x512", HDMI_Unknown, 640, 512, 800, 0, 568, 48, 28, 96, 2, DEFAULT_SAMPLER_PHASE, VIDEO_PC, GROUP_480P, (MODE_PT | MODE_L2) }, \
/* ~625-line modes */ \
{ "576i", HDMI_576i50, 720, 288, 864, 0, 625, 69, 19, 63, 3, DEFAULT_SAMPLER_PHASE, VIDEO_SDTV, GROUP_480I, (MODE_PT | MODE_L2 | MODE_L3_GEN_16_9 | MODE_L4_GEN_4_3 | MODE_PLLDIVBY2 | MODE_INTERLACED) }, \
{ "576p", HDMI_576p50, 720, 576, 864, 0, 625, 68, 39, 64, 5, DEFAULT_SAMPLER_PHASE, VIDEO_EDTV, GROUP_480P, (MODE_PT | MODE_L2) }, \
{ "800x600", HDMI_Unknown, 800, 600, 1056, 0, 628, 88, 23, 128, 4, DEFAULT_SAMPLER_PHASE, VIDEO_PC, GROUP_NONE, MODE_PT }, \
/* 720p modes */ \
{ "720p_50", HDMI_720p50, 1280, 720, 1980, 0, 750, 220, 20, 40, 5, DEFAULT_SAMPLER_PHASE, (VIDEO_HDTV | VIDEO_PC), GROUP_NONE, MODE_PT }, \
{ "720p_60", HDMI_720p60, 1280, 720, 1650, 0, 750, 220, 20, 40, 5, DEFAULT_SAMPLER_PHASE, (VIDEO_HDTV | VIDEO_PC), GROUP_NONE, MODE_PT }, \
/* VESA XGA and SXGA modes */ \
{ "1024x768", HDMI_Unknown, 1024, 768, 1344, 0, 806, 160, 29, 136, 6, DEFAULT_SAMPLER_PHASE, VIDEO_PC, GROUP_NONE, MODE_PT }, \
{ "1280x1024", HDMI_Unknown, 1280, 1024, 1688, 0, 1066, 248, 38, 112, 3, DEFAULT_SAMPLER_PHASE, VIDEO_PC, GROUP_NONE, MODE_PT }, \
/* PS2 GSM 960i mode */ \
{ "640x960i", HDMI_Unknown, 640, 480, 800, 0, 1050, 48, 33, 96, 2, DEFAULT_SAMPLER_PHASE, VIDEO_EDTV, GROUP_1080I, (MODE_PT | MODE_L2 | MODE_INTERLACED) }, \
/* 1080i/p modes */ \
{ "1080i_50", HDMI_1080i50, 1920, 540, 2640, 0, 1125, 148, 15, 44, 5, DEFAULT_SAMPLER_PHASE, (VIDEO_HDTV | VIDEO_PC), GROUP_1080I, (MODE_PT | MODE_L2 | MODE_INTERLACED) }, \
{ "1080i_60", HDMI_1080i60, 1920, 540, 2200, 0, 1125, 148, 16, 44, 5, DEFAULT_SAMPLER_PHASE, (VIDEO_HDTV | VIDEO_PC), GROUP_1080I, (MODE_PT | MODE_L2 | MODE_INTERLACED) }, \
{ "1080p_50", HDMI_1080p50, 1920, 1080, 2640, 0, 1125, 148, 36, 44, 5, DEFAULT_SAMPLER_PHASE, (VIDEO_HDTV | VIDEO_PC), GROUP_NONE, MODE_PT }, \
{ "1080p_60", HDMI_1080p60, 1920, 1080, 2200, 0, 1125, 148, 36, 44, 5, DEFAULT_SAMPLER_PHASE, (VIDEO_HDTV | VIDEO_PC), GROUP_NONE, MODE_PT }, \
/* VESA UXGA with 49 H.backporch cycles exchanged for H.synclen */ \
{ "1600x1200", HDMI_Unknown, 1600, 1200, 2160, 0, 1250, 255, 46, 241, 3, DEFAULT_SAMPLER_PHASE, VIDEO_PC, GROUP_NONE, MODE_PT }, \
}
#define VIDEO_MODES_SIZE (sizeof((mode_data_t[])VIDEO_MODES_DEF))
#define VIDEO_MODES_CNT (sizeof((mode_data_t[])VIDEO_MODES_DEF)/sizeof(mode_data_t))
alt_8 get_mode_id(alt_u32 totlines, alt_u8 progressive, alt_u32 hz, alt_u8 h_syncinlen);
#endif /* VIDEO_MODES_H_ */

View File

@ -7,7 +7,7 @@
#include "spi_io.h"
#include "av_controller.h"
extern alt_u32 sys_ctrl;
extern alt_u16 sys_ctrl;
alt_u32 sd_timer_ts;

View File

@ -337,7 +337,7 @@
#define PIO_0_BIT_CLEARING_EDGE_REGISTER 0
#define PIO_0_BIT_MODIFYING_OUTPUT_REGISTER 0
#define PIO_0_CAPTURE 0
#define PIO_0_DATA_WIDTH 32
#define PIO_0_DATA_WIDTH 16
#define PIO_0_DO_TEST_BENCH_WIRING 0
#define PIO_0_DRIVEN_SIM_VALUE 0
#define PIO_0_EDGE_TYPE "NONE"

120
sys.qsys

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long