mirror of
https://github.com/marqs85/ossc.git
synced 2024-09-28 11:55:16 +00:00
Compare commits
16 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
de1b441167 | ||
|
c5f7483410 | ||
|
3a17642d5b | ||
|
d57a44131a | ||
|
0839e118ad | ||
|
86c3f744ed | ||
|
df643ec742 | ||
|
a825bb048c | ||
|
804642bd98 | ||
|
94c0526265 | ||
|
a8a3142071 | ||
|
02b2495221 | ||
|
76da437125 | ||
|
aa4beec957 | ||
|
db1cf5922f | ||
|
fd37e4275b |
5
.gitignore
vendored
5
.gitignore
vendored
@ -1,3 +1,8 @@
|
||||
*_bb.v
|
||||
*_inst.v
|
||||
*.ppf
|
||||
*.qws
|
||||
greybox_tmp
|
||||
.DS_Store
|
||||
software/sys_controller/.cproject
|
||||
software/sys_controller/.force_relink
|
||||
|
@ -5,9 +5,10 @@ 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 "20.1"
|
||||
#set_module_property VERSION "21.1"
|
||||
set_module_property INTERNAL false
|
||||
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
|
||||
|
@ -20,118 +20,147 @@
|
||||
#ifndef SC_CONFIG_REGS_H_
|
||||
#define SC_CONFIG_REGS_H_
|
||||
|
||||
#include <alt_types.h>
|
||||
#include <stdint.h>
|
||||
|
||||
// bit-fields coded as little-endian
|
||||
typedef union {
|
||||
struct {
|
||||
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;
|
||||
uint16_t vtotal:11;
|
||||
uint8_t interlace_flag:1;
|
||||
uint8_t sync_active:1;
|
||||
uint32_t fe_rsv:19;
|
||||
} __attribute__((packed, __may_alias__));
|
||||
alt_u32 data;
|
||||
} sc_status_reg;
|
||||
uint32_t data;
|
||||
} fe_status_reg;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
alt_u32 pcnt_frame:20;
|
||||
alt_u16 sc_rsv:12;
|
||||
uint32_t pcnt_frame:20;
|
||||
uint16_t fe_rsv:12;
|
||||
} __attribute__((packed, __may_alias__));
|
||||
alt_u32 data;
|
||||
} sc_status2_reg;
|
||||
uint32_t data;
|
||||
} fe_status2_reg;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
alt_u16 lt_lat_result:16;
|
||||
alt_u16 lt_stb_result:12;
|
||||
alt_u8 lt_rsv:3;
|
||||
alt_u8 lt_finished:1;
|
||||
uint16_t lt_lat_result:16;
|
||||
uint16_t lt_stb_result:12;
|
||||
uint8_t lt_rsv:3;
|
||||
uint8_t lt_finished:1;
|
||||
} __attribute__((packed, __may_alias__));
|
||||
alt_u32 data;
|
||||
uint32_t data;
|
||||
} lt_status_reg;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
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;
|
||||
uint16_t h_total:12;
|
||||
uint16_t h_active:12;
|
||||
uint16_t h_synclen:8;
|
||||
} __attribute__((packed, __may_alias__));
|
||||
alt_u32 data;
|
||||
} h_config_reg;
|
||||
uint32_t data;
|
||||
} hv_config_reg;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
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;
|
||||
uint16_t h_backporch:9;
|
||||
uint16_t v_total:11;
|
||||
uint16_t v_active:11;
|
||||
uint8_t interlaced:1;
|
||||
} __attribute__((packed, __may_alias__));
|
||||
alt_u32 data;
|
||||
} h_config2_reg;
|
||||
uint32_t data;
|
||||
} hv_config2_reg;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
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;
|
||||
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;
|
||||
} __attribute__((packed, __may_alias__));
|
||||
alt_u32 data;
|
||||
} v_config_reg;
|
||||
uint32_t data;
|
||||
} hv_config3_reg;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
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;
|
||||
uint16_t x_size:12;
|
||||
uint16_t y_size:11;
|
||||
int16_t y_offset:9;
|
||||
} __attribute__((packed, __may_alias__));
|
||||
alt_u32 data;
|
||||
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;
|
||||
} misc_config_reg;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
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;
|
||||
uint32_t sl_l_str_arr:24;
|
||||
uint8_t sl_l_overlay:6;
|
||||
uint8_t sl_method:1;
|
||||
uint8_t sl_altern:1;
|
||||
} __attribute__((packed, __may_alias__));
|
||||
alt_u32 data;
|
||||
uint32_t data;
|
||||
} sl_config_reg;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
alt_u32 sl_c_str_arr:24;
|
||||
alt_u8 sl_c_overlay:6;
|
||||
alt_u8 sl_rsv:1;
|
||||
alt_u8 sl_altiv:1;
|
||||
uint32_t sl_c_str_arr_l;
|
||||
} __attribute__((packed, __may_alias__));
|
||||
alt_u32 data;
|
||||
uint32_t 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;
|
||||
uint32_t sl_rsv:7;
|
||||
} __attribute__((packed, __may_alias__));
|
||||
uint32_t data;
|
||||
} sl_config3_reg;
|
||||
|
||||
typedef struct {
|
||||
sc_status_reg sc_status;
|
||||
sc_status2_reg sc_status2;
|
||||
fe_status_reg fe_status;
|
||||
fe_status2_reg fe_status2;
|
||||
lt_status_reg lt_status;
|
||||
h_config_reg h_config;
|
||||
h_config2_reg h_config2;
|
||||
v_config_reg v_config;
|
||||
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;
|
||||
misc_config_reg misc_config;
|
||||
sl_config_reg sl_config;
|
||||
sl_config2_reg sl_config2;
|
||||
} __attribute__((packed, __may_alias__)) sc_regs;
|
||||
sl_config3_reg sl_config3;
|
||||
} sc_regs;
|
||||
|
||||
#endif //SC_CONFIG_REGS_H_
|
||||
|
@ -143,12 +143,18 @@ 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 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 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 lt_status_i lt_status_i Input 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 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 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
|
||||
|
@ -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 7.1
|
||||
set_sw_property min_compatible_hw_version 1.0
|
||||
|
||||
# Initialize the driver in alt_sys_init()
|
||||
set_sw_property auto_initialize false
|
||||
|
@ -23,7 +23,7 @@ module sc_config_top(
|
||||
input rst_i,
|
||||
// avalon slave
|
||||
input [31:0] avalon_s_writedata,
|
||||
output [31:0] avalon_s_readdata,
|
||||
output reg [31:0] avalon_s_readdata,
|
||||
input [3:0] avalon_s_address,
|
||||
input [3:0] avalon_s_byteenable,
|
||||
input avalon_s_write,
|
||||
@ -31,144 +31,73 @@ module sc_config_top(
|
||||
input avalon_s_chipselect,
|
||||
output avalon_s_waitrequest_n,
|
||||
// SC interface
|
||||
input [31:0] sc_status_i,
|
||||
input [31:0] sc_status2_i,
|
||||
input [31:0] fe_status_i,
|
||||
input [31:0] fe_status2_i,
|
||||
input [31:0] lt_status_i,
|
||||
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
|
||||
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
|
||||
);
|
||||
|
||||
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;
|
||||
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;
|
||||
|
||||
reg [31:0] config_reg[HV_IN_CONFIG_REGNUM:SL_CONFIG3_REGNUM] /* synthesis ramstyle = "logic" */;
|
||||
|
||||
assign avalon_s_waitrequest_n = 1'b1;
|
||||
|
||||
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];
|
||||
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
|
||||
end
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
|
||||
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)
|
||||
SC_STATUS_REGNUM: avalon_s_readdata = sc_status_i;
|
||||
SC_STATUS2_REGNUM: avalon_s_readdata = sc_status2_i;
|
||||
FE_STATUS_REGNUM: avalon_s_readdata = fe_status_i;
|
||||
FE_STATUS2_REGNUM: avalon_s_readdata = fe_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
|
||||
@ -176,4 +105,17 @@ 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
|
||||
|
2
ossc.cof
2
ossc.cof
@ -19,7 +19,7 @@
|
||||
<auto_create_rpd>0</auto_create_rpd>
|
||||
<rpd_little_endian>1</rpd_little_endian>
|
||||
<options>
|
||||
<map_file>1</map_file>
|
||||
<map_file>0</map_file>
|
||||
</options>
|
||||
<advanced_options>
|
||||
<ignore_epcs_id_check>0</ignore_epcs_id_check>
|
||||
|
74
ossc.qsf
74
ossc.qsf
@ -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 "20.1.1 Lite Edition"
|
||||
set_global_assignment -name LAST_QUARTUS_VERSION "21.1.0 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
|
||||
@ -63,34 +63,34 @@ set_location_assignment PIN_23 -to ir_rx
|
||||
#============================================================
|
||||
# TVP7002
|
||||
#============================================================
|
||||
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]
|
||||
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_FID_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]
|
||||
|
||||
#============================================================
|
||||
# HDMITX
|
||||
@ -140,7 +140,8 @@ set_location_assignment PIN_30 -to SD_DAT[3]
|
||||
# Leds
|
||||
#============================================================
|
||||
set_location_assignment PIN_44 -to LED_G
|
||||
set_location_assignment PIN_46 -to LED_R
|
||||
#set_location_assignment PIN_46 -to LED_R
|
||||
set_location_assignment PIN_46 -to TVP_HSYNC_i
|
||||
|
||||
#============================================================
|
||||
# I2C
|
||||
@ -187,7 +188,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 "AGGRESSIVE PERFORMANCE"
|
||||
set_global_assignment -name OPTIMIZATION_MODE BALANCED
|
||||
set_global_assignment -name ALLOW_REGISTER_RETIMING OFF
|
||||
|
||||
set_global_assignment -name ENABLE_OCT_DONE OFF
|
||||
@ -211,14 +212,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 8.0
|
||||
set_global_assignment -name PLACEMENT_EFFORT_MULTIPLIER 1
|
||||
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_la.stp
|
||||
set_global_assignment -name USE_SIGNALTAP_FILE output_files/ossc_new.stp
|
||||
|
||||
set_global_assignment -name FITTER_EFFORT "AUTO FIT"
|
||||
set_global_assignment -name SEED 2
|
||||
set_global_assignment -name SEED 3
|
||||
|
||||
|
||||
|
||||
@ -234,6 +235,8 @@ 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
|
||||
@ -247,4 +250,7 @@ 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
|
57
ossc.sdc
57
ossc.sdc
@ -9,36 +9,24 @@ set_false_path -to {sys:sys_inst|sys_pio_1:pio_1|readdata*}
|
||||
|
||||
### Scanconverter clock constraints ###
|
||||
|
||||
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
|
||||
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
|
||||
|
||||
#derive_pll_clocks
|
||||
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
|
||||
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
|
||||
|
||||
# retrieve post-mapping clkmux output pin
|
||||
set clkmux_output [get_pins scanconverter_inst|clkctrl1|outclk]
|
||||
set clkmux_output [get_pins clkctrl1|outclk]
|
||||
|
||||
# specify postmux clocks which clock postprocess pipeline
|
||||
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
|
||||
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
|
||||
|
||||
# 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
|
||||
|
||||
@ -47,8 +35,8 @@ derive_clock_uncertainty
|
||||
# input delay constraints
|
||||
set TVP_dmin 0
|
||||
set TVP_dmax 1.5
|
||||
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 critinputs [get_ports {TVP_R_i* TVP_G_i* TVP_B_i* TVP_HS_i TVP_HSYNC_i TVP_VSYNC_i TVP_FID_i}]
|
||||
foreach_in_collection c [get_clocks "pclk_tvp*"] {
|
||||
set_input_delay -clock $c -min $TVP_dmin $critinputs -add_delay
|
||||
set_input_delay -clock $c -max $TVP_dmax $critinputs -add_delay
|
||||
}
|
||||
@ -69,25 +57,12 @@ set_false_path -to [remove_from_collection [all_outputs] $critoutputs_hdmi]
|
||||
|
||||
# Treat CPU clock asynchronous to pixel clocks
|
||||
set_clock_groups -asynchronous -group \
|
||||
{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_*}]
|
||||
{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}
|
||||
|
||||
|
||||
### JTAG Signal Constraints ###
|
||||
|
@ -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" Selected="no">
|
||||
<WorkspaceConfiguration Name="Debug">
|
||||
<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" Selected="yes">
|
||||
<WorkspaceConfiguration Name="Release">
|
||||
<Environment/>
|
||||
<Project Name="ossc_rtl" ConfigName="Release"/>
|
||||
<Project Name="ossc_sw_bsp" ConfigName="Release"/>
|
||||
|
@ -1,5 +1,5 @@
|
||||
set_global_assignment -name IP_TOOL_NAME "RAM: 2-PORT"
|
||||
set_global_assignment -name IP_TOOL_VERSION "20.1"
|
||||
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) "char_array.v"]
|
||||
set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "char_array_inst.v"]
|
||||
|
@ -14,11 +14,11 @@
|
||||
// ************************************************************
|
||||
// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
|
||||
//
|
||||
// 20.1.1 Build 720 11/11/2020 SJ Lite Edition
|
||||
// 21.1.0 Build 842 10/21/2021 SJ Lite Edition
|
||||
// ************************************************************
|
||||
|
||||
|
||||
//Copyright (C) 2020 Intel Corporation. All rights reserved.
|
||||
//Copyright (C) 2021 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
|
||||
|
@ -1,5 +1,5 @@
|
||||
set_global_assignment -name IP_TOOL_NAME "ROM: 1-PORT"
|
||||
set_global_assignment -name IP_TOOL_VERSION "20.1"
|
||||
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) "char_rom.v"]
|
||||
set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "char_rom_inst.v"]
|
||||
|
@ -14,11 +14,11 @@
|
||||
// ************************************************************
|
||||
// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
|
||||
//
|
||||
// 20.1.1 Build 720 11/11/2020 SJ Lite Edition
|
||||
// 21.1.0 Build 842 10/21/2021 SJ Lite Edition
|
||||
// ************************************************************
|
||||
|
||||
|
||||
//Copyright (C) 2020 Intel Corporation. All rights reserved.
|
||||
//Copyright (C) 2021 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
|
||||
|
@ -1,6 +1,4 @@
|
||||
set_global_assignment -name IP_TOOL_NAME "RAM: 2-PORT"
|
||||
set_global_assignment -name IP_TOOL_VERSION "20.1"
|
||||
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) "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"]
|
||||
|
@ -14,11 +14,11 @@
|
||||
// ************************************************************
|
||||
// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
|
||||
//
|
||||
// 20.1.1 Build 720 11/11/2020 SJ Lite Edition
|
||||
// 21.1.0 Build 842 10/21/2021 SJ Lite Edition
|
||||
// ************************************************************
|
||||
|
||||
|
||||
//Copyright (C) 2020 Intel Corporation. All rights reserved.
|
||||
//Copyright (C) 2021 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,22 +41,28 @@ 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
|
||||
@ -70,6 +76,8 @@ module linebuf (
|
||||
.address_b (rdaddress),
|
||||
.clock0 (wrclock),
|
||||
.clock1 (rdclock),
|
||||
.clocken0 (wrclocken),
|
||||
.clocken1 (rdclocken),
|
||||
.data_a (data),
|
||||
.wren_a (wren),
|
||||
.q_b (sub_wire0),
|
||||
@ -79,8 +87,6 @@ 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}}),
|
||||
@ -92,9 +98,9 @@ module linebuf (
|
||||
defparam
|
||||
altsyncram_component.address_aclr_b = "NONE",
|
||||
altsyncram_component.address_reg_b = "CLOCK1",
|
||||
altsyncram_component.clock_enable_input_a = "BYPASS",
|
||||
altsyncram_component.clock_enable_input_b = "BYPASS",
|
||||
altsyncram_component.clock_enable_output_b = "BYPASS",
|
||||
altsyncram_component.clock_enable_input_a = "NORMAL",
|
||||
altsyncram_component.clock_enable_input_b = "NORMAL",
|
||||
altsyncram_component.clock_enable_output_b = "NORMAL",
|
||||
altsyncram_component.intended_device_family = "Cyclone IV E",
|
||||
altsyncram_component.lpm_type = "altsyncram",
|
||||
altsyncram_component.numwords_a = 4096,
|
||||
@ -123,10 +129,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 "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: 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: CLRdata NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: CLRq NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: CLRrdaddress NUMERIC "0"
|
||||
@ -172,14 +178,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 "0"
|
||||
// Retrieval info: PRIVATE: enable NUMERIC "1"
|
||||
// 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 "BYPASS"
|
||||
// Retrieval info: CONSTANT: CLOCK_ENABLE_INPUT_B STRING "BYPASS"
|
||||
// Retrieval info: CONSTANT: CLOCK_ENABLE_OUTPUT_B STRING "BYPASS"
|
||||
// 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: INTENDED_DEVICE_FAMILY STRING "Cyclone IV E"
|
||||
// Retrieval info: CONSTANT: LPM_TYPE STRING "altsyncram"
|
||||
// Retrieval info: CONSTANT: NUMWORDS_A NUMERIC "4096"
|
||||
@ -197,13 +203,17 @@ 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
|
||||
@ -211,6 +221,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 TRUE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL linebuf_bb.v TRUE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL linebuf_inst.v FALSE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL linebuf_bb.v FALSE
|
||||
// Retrieval info: LIB_FILE: altera_mf
|
||||
|
279
rtl/linebuf_top.v
Normal file
279
rtl/linebuf_top.v
Normal file
@ -0,0 +1,279 @@
|
||||
//
|
||||
// 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
|
@ -1,5 +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_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_4_hybr_ref.v"]
|
||||
set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "lpm_mult_4_hybr_ref_bb.v"]
|
||||
|
@ -14,11 +14,11 @@
|
||||
// ************************************************************
|
||||
// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
|
||||
//
|
||||
// 20.1.1 Build 720 11/11/2020 SJ Lite Edition
|
||||
// 21.1.0 Build 842 10/21/2021 SJ Lite Edition
|
||||
// ************************************************************
|
||||
|
||||
|
||||
//Copyright (C) 2020 Intel Corporation. All rights reserved.
|
||||
//Copyright (C) 2021 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
|
||||
|
@ -1,5 +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_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_4_hybr_ref_pre.v"]
|
||||
set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "lpm_mult_4_hybr_ref_pre_bb.v"]
|
||||
|
@ -14,11 +14,11 @@
|
||||
// ************************************************************
|
||||
// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
|
||||
//
|
||||
// 20.1.1 Build 720 11/11/2020 SJ Lite Edition
|
||||
// 21.1.0 Build 842 10/21/2021 SJ Lite Edition
|
||||
// ************************************************************
|
||||
|
||||
|
||||
//Copyright (C) 2020 Intel Corporation. All rights reserved.
|
||||
//Copyright (C) 2021 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
|
||||
|
@ -1,5 +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_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_4_sl.v"]
|
||||
set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "lpm_mult_4_sl_bb.v"]
|
||||
|
@ -14,11 +14,11 @@
|
||||
// ************************************************************
|
||||
// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
|
||||
//
|
||||
// 20.1.1 Build 720 11/11/2020 SJ Lite Edition
|
||||
// 21.1.0 Build 842 10/21/2021 SJ Lite Edition
|
||||
// ************************************************************
|
||||
|
||||
|
||||
//Copyright (C) 2020 Intel Corporation. All rights reserved.
|
||||
//Copyright (C) 2021 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
|
||||
|
483
rtl/ossc.v
483
rtl/ossc.v
@ -22,17 +22,22 @@
|
||||
|
||||
module ossc (
|
||||
input clk27,
|
||||
input ir_rx,
|
||||
|
||||
inout scl,
|
||||
inout sda,
|
||||
|
||||
input ir_rx,
|
||||
input [1:0] btn,
|
||||
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,
|
||||
|
||||
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_HSYNC_i,
|
||||
input TVP_VSYNC_i,
|
||||
input TVP_FID_i,
|
||||
|
||||
output HDMI_TX_PCLK,
|
||||
output reg [7:0] HDMI_TX_RD,
|
||||
output reg [7:0] HDMI_TX_GD,
|
||||
@ -42,39 +47,51 @@ module ossc (
|
||||
output reg HDMI_TX_VS,
|
||||
input HDMI_TX_INT_N,
|
||||
input HDMI_TX_MODE,
|
||||
|
||||
output hw_reset_n,
|
||||
|
||||
output LED_G,
|
||||
output 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 [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 [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] ir_code;
|
||||
wire [7:0] ir_code_cnt;
|
||||
|
||||
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;
|
||||
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;
|
||||
|
||||
|
||||
reg [7:0] po_reset_ctr = 0;
|
||||
@ -82,24 +99,32 @@ reg po_reset_n = 1'b0;
|
||||
wire jtagm_reset_req;
|
||||
wire sys_reset_n = (po_reset_n & ~jtagm_reset_req);
|
||||
|
||||
reg [7:0] R_in_L, G_in_L, B_in_L;
|
||||
reg HSYNC_in_L, VSYNC_in_L, FID_in_L;
|
||||
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 [1:0] btn_L, btn_LL;
|
||||
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;
|
||||
reg vsync_flag_sync1_reg, vsync_flag_sync2_reg;
|
||||
|
||||
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, HDMI_TX_MODE_LL, btn_LL, ir_code};
|
||||
|
||||
wire lt_sensor = btn_LL[1];
|
||||
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 lt_trigger = DE_sc & G_sc[0];
|
||||
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;
|
||||
@ -107,53 +132,100 @@ 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, xpos_sc, xpos_vg;
|
||||
wire [10:0] ypos, ypos_sc, ypos_vg;
|
||||
wire [10:0] xpos_sc;
|
||||
wire [10:0] ypos_sc;
|
||||
|
||||
wire pll_areset, pll_scanclk, pll_scanclkena, pll_configupdate, pll_scandata, pll_scandone, pll_activeclock;
|
||||
`ifdef DEBUG
|
||||
assign LED_R = TVP_HSYNC_i;
|
||||
assign LED_G = TVP_VSYNC_i;
|
||||
`else
|
||||
wire resync_indicator = (warn_pll_lock_lost != 0) | (resync_led_ctr != 0);
|
||||
//assign LED_R = lt_active ? lt_trig_waiting : resync_indicator;
|
||||
assign LED_G = lt_active ? ~lt_sensor : (ir_code == 0) & ~resync_indicator;
|
||||
`endif
|
||||
|
||||
assign LCD_BL = lcd_bl_on ? (~lcd_bl_timeout | lt_active) : 1'b0;
|
||||
assign HDMI_TX_PCLK = pclk_out;
|
||||
|
||||
|
||||
// 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
|
||||
// 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;
|
||||
TVP_FID <= TVP_FID_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;
|
||||
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 [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),
|
||||
.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),
|
||||
.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 <= 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;
|
||||
{btn_L, btn_LL} <= '0;
|
||||
{ir_rx_L, ir_rx_LL} <= '0;
|
||||
{HDMI_TX_INT_N_L, HDMI_TX_INT_N_LL} <= '0;
|
||||
{HDMI_TX_MODE_L, HDMI_TX_MODE_LL} <= '0;
|
||||
end else begin
|
||||
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;
|
||||
{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};
|
||||
{HDMI_TX_MODE_L, HDMI_TX_MODE_LL} <= {HDMI_TX_MODE, HDMI_TX_MODE_L};
|
||||
end
|
||||
end
|
||||
|
||||
@ -166,49 +238,9 @@ begin
|
||||
po_reset_ctr <= po_reset_ctr + 1'b1;
|
||||
end
|
||||
|
||||
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;
|
||||
// Sync vsync flag to CPU clock
|
||||
always @(posedge clk27) begin
|
||||
{vsync_flag_sync1_reg, vsync_flag_sync2_reg} <= {~VSYNC_sc, vsync_flag_sync1_reg};
|
||||
end
|
||||
|
||||
// LCD backlight timeout counters
|
||||
@ -237,6 +269,93 @@ 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
|
||||
|
||||
|
||||
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),
|
||||
@ -253,19 +372,25 @@ 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 ({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),
|
||||
.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 ({12'h0, 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),
|
||||
.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),
|
||||
.osd_generator_0_osd_if_vclk (PCLK_out),
|
||||
.osd_generator_0_osd_if_xpos (xpos),
|
||||
.osd_generator_0_osd_if_ypos (ypos),
|
||||
.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_osd_enable (osd_enable_pre),
|
||||
.osd_generator_0_osd_if_osd_color (osd_color),
|
||||
.pll_reconfig_0_pll_reconfig_if_areset (pll_areset),
|
||||
@ -276,49 +401,65 @@ sys sys_inst(
|
||||
.pll_reconfig_0_pll_reconfig_if_scandone (pll_scandone)
|
||||
);
|
||||
|
||||
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)
|
||||
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()
|
||||
);
|
||||
|
||||
ir_rcv ir0 (
|
||||
@ -332,12 +473,12 @@ ir_rcv ir0 (
|
||||
|
||||
lat_tester lt0 (
|
||||
.clk27 (clk27),
|
||||
.pclk (PCLK_out),
|
||||
.pclk (PCLK_sc),
|
||||
.active (lt_active),
|
||||
.armed (lt_armed),
|
||||
.sensor (lt_sensor),
|
||||
.trigger (lt_trigger),
|
||||
.VSYNC_in (HDMI_TX_VS),
|
||||
.VSYNC_in (VSYNC_sc),
|
||||
.mode_in (lt_mode),
|
||||
.mode_synced (lt_mode_synced),
|
||||
.lat_result (lt_lat_result),
|
||||
@ -346,8 +487,8 @@ lat_tester lt0 (
|
||||
.finished (lt_finished)
|
||||
);
|
||||
|
||||
videogen vg0 (
|
||||
.clk27 (PCLK_out),
|
||||
/*Ävideogen vg0 (
|
||||
.clk27 (PCLK_sc),
|
||||
.reset_n (po_reset_n & ~enable_sc),
|
||||
.lt_active (lt_active),
|
||||
.lt_mode (lt_mode_synced),
|
||||
@ -359,6 +500,6 @@ videogen vg0 (
|
||||
.DE_out (DE_out_vg),
|
||||
.xpos (xpos_vg),
|
||||
.ypos (ypos_vg)
|
||||
);
|
||||
);*/
|
||||
|
||||
endmodule
|
||||
|
@ -12,7 +12,6 @@
|
||||
<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" />
|
||||
|
@ -1,7 +1,5 @@
|
||||
set_global_assignment -name IP_TOOL_NAME "ALTPLL"
|
||||
set_global_assignment -name IP_TOOL_VERSION "20.1"
|
||||
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) "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"]
|
||||
|
62
rtl/pll_2x.v
62
rtl/pll_2x.v
@ -14,11 +14,11 @@
|
||||
// ************************************************************
|
||||
// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
|
||||
//
|
||||
// 20.1.1 Build 720 11/11/2020 SJ Lite Edition
|
||||
// 21.1.0 Build 842 10/21/2021 SJ Lite Edition
|
||||
// ************************************************************
|
||||
|
||||
|
||||
//Copyright (C) 2020 Intel Corporation. All rights reserved.
|
||||
//Copyright (C) 2021 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,7 +48,6 @@ module pll_2x (
|
||||
scandata,
|
||||
activeclock,
|
||||
c0,
|
||||
c1,
|
||||
locked,
|
||||
scandataout,
|
||||
scandone);
|
||||
@ -63,7 +62,6 @@ module pll_2x (
|
||||
input scandata;
|
||||
output activeclock;
|
||||
output c0;
|
||||
output c1;
|
||||
output locked;
|
||||
output scandataout;
|
||||
output scandone;
|
||||
@ -81,34 +79,32 @@ module pll_2x (
|
||||
|
||||
wire sub_wire0;
|
||||
wire [4:0] sub_wire1;
|
||||
wire sub_wire3;
|
||||
wire sub_wire4;
|
||||
wire sub_wire5;
|
||||
wire sub_wire6;
|
||||
wire sub_wire9 = inclk1;
|
||||
wire sub_wire8 = 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 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};
|
||||
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};
|
||||
|
||||
altpll altpll_component (
|
||||
.areset (areset),
|
||||
.clkswitch (clkswitch),
|
||||
.configupdate (configupdate),
|
||||
.inclk (sub_wire8),
|
||||
.inclk (sub_wire7),
|
||||
.scanclk (scanclk),
|
||||
.scanclkena (scanclkena),
|
||||
.scandata (scandata),
|
||||
.activeclock (sub_wire0),
|
||||
.clk (sub_wire1),
|
||||
.locked (sub_wire4),
|
||||
.scandataout (sub_wire5),
|
||||
.scandone (sub_wire6),
|
||||
.locked (sub_wire3),
|
||||
.scandataout (sub_wire4),
|
||||
.scandone (sub_wire5),
|
||||
.clkbad (),
|
||||
.clkena ({6{1'b1}}),
|
||||
.clkloss (),
|
||||
@ -140,10 +136,6 @@ 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,
|
||||
@ -178,7 +170,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_USED",
|
||||
altpll_component.port_clk1 = "PORT_UNUSED",
|
||||
altpll_component.port_clk2 = "PORT_UNUSED",
|
||||
altpll_component.port_clk3 = "PORT_UNUSED",
|
||||
altpll_component.port_clk4 = "PORT_UNUSED",
|
||||
@ -227,11 +219,8 @@ 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"
|
||||
@ -252,26 +241,18 @@ 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"
|
||||
@ -294,14 +275,11 @@ 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
|
||||
@ -310,10 +288,6 @@ 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"
|
||||
@ -347,7 +321,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_USED"
|
||||
// Retrieval info: CONSTANT: PORT_clk1 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_clk2 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_clk3 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_clk4 STRING "PORT_UNUSED"
|
||||
@ -371,7 +345,6 @@ 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"
|
||||
@ -392,7 +365,6 @@ 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
|
||||
@ -401,8 +373,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 TRUE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL pll_2x_bb.v TRUE
|
||||
// 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.mif TRUE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL pll_2x.hex TRUE
|
||||
// Retrieval info: LIB_FILE: altera_mf
|
||||
|
1538
rtl/scanconverter.v
1538
rtl/scanconverter.v
File diff suppressed because it is too large
Load Diff
357
rtl/tvp7002_frontend.v
Normal file
357
rtl/tvp7002_frontend.v
Normal file
@ -0,0 +1,357 @@
|
||||
//
|
||||
// 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/>.
|
||||
//
|
||||
|
||||
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,
|
||||
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 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_PL_END = 4;
|
||||
|
||||
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" */;
|
||||
|
||||
// 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 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 [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/8)) | (pcnt_frame_ctr > (pcnt_frame - (pcnt_frame/8))));
|
||||
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];
|
||||
|
||||
|
||||
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 1-
|
||||
integer pp_idx;
|
||||
always @(posedge PCLK_i) begin
|
||||
for(pp_idx = PP_PL_START+1; pp_idx <= PP_PL_END-1; 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];
|
||||
end
|
||||
R_pp[PP_PL_END] <= R_pp[PP_PL_END-1];
|
||||
G_pp[PP_PL_END] <= G_pp[PP_PL_END-1];
|
||||
B_pp[PP_PL_END] <= B_pp[PP_PL_END-1];
|
||||
|
||||
for(pp_idx = PP_PL_START+1; pp_idx <= PP_PL_END; pp_idx = pp_idx+1) begin
|
||||
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
|
||||
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;
|
||||
|
||||
// store count 1ms after vsync
|
||||
if (~pcnt_line_stored & (pcnt_frame_ctr > 21'd27000)) begin
|
||||
pcnt_line <= pcnt_line_ctr;
|
||||
pcnt_line_stored <= 1'b1;
|
||||
end
|
||||
end else begin
|
||||
pcnt_line_ctr <= pcnt_line_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 (meas_vblank_region & (meas_h_cnt > pcnt_line)) begin
|
||||
// hsync may be missing during vblank, force line change detect if pcnt_line is exceeded +-1/8 field around vsync edge
|
||||
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
|
@ -1,5 +1,13 @@
|
||||
#Select the master service type and check for available service paths.
|
||||
set service_paths [get_service_paths master]
|
||||
while 1 {
|
||||
set service_paths [get_service_paths master]
|
||||
if {[llength $service_paths] > 0} {
|
||||
break
|
||||
}
|
||||
puts "Refreshing connections..."
|
||||
refresh_connections
|
||||
after 100
|
||||
}
|
||||
|
||||
#Set the master service path.
|
||||
set master_service_path [lindex $service_paths 0]
|
||||
@ -8,7 +16,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 0x1
|
||||
master_write_32 $claim_path 0x0 0x10000
|
||||
|
||||
puts "Writing block RAM"
|
||||
master_write_from_file $claim_path mem_init/sys_onchip_memory2_0.bin 0x10000
|
||||
|
@ -33,7 +33,7 @@
|
||||
<Extensions>
|
||||
<![CDATA[*.cpp;*.c;*.h;*.hpp;*.xrc;*.wxcp;*.fbp]]>
|
||||
</Extensions>
|
||||
<Topleveldir>/home/markus/Code/ossc/software</Topleveldir>
|
||||
<Topleveldir>./</Topleveldir>
|
||||
</Reconciliation>
|
||||
<VirtualDirectory Name="sys_controller">
|
||||
<VirtualDirectory Name="ths7353">
|
||||
@ -61,9 +61,7 @@
|
||||
<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>
|
||||
@ -89,6 +87,9 @@
|
||||
<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"/>
|
||||
|
@ -149,7 +149,6 @@ 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
|
||||
@ -171,6 +170,7 @@ 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 :=
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright (C) 2015-2022 Markus Hiienkari <mhiienka@niksula.hut.fi>
|
||||
// Copyright (C) 2015-2023 Markus Hiienkari <mhiienka@niksula.hut.fi>
|
||||
//
|
||||
// This file is part of Open Source Scan Converter project.
|
||||
//
|
||||
@ -33,7 +33,6 @@
|
||||
#include "sdcard.h"
|
||||
#include "menu.h"
|
||||
#include "avconfig.h"
|
||||
#include "sysconfig.h"
|
||||
#include "firmware.h"
|
||||
#include "userdata.h"
|
||||
#include "it6613.h"
|
||||
@ -43,19 +42,18 @@
|
||||
#include "sd_io.h"
|
||||
#include "sys/alt_timestamp.h"
|
||||
|
||||
#define STABLE_THOLD 1
|
||||
#define MIN_LINES_PROGRESSIVE 200
|
||||
#define MIN_LINES_INTERLACED 400
|
||||
#define SYNC_LOCK_THOLD 3
|
||||
#define SYNC_LOSS_THOLD -5
|
||||
#define STATUS_TIMEOUT 100000
|
||||
#define STATUS_TIMEOUT_US 25000
|
||||
|
||||
alt_u16 sys_ctrl;
|
||||
#define PCNT_TOLERANCE 50
|
||||
|
||||
alt_u32 sys_ctrl;
|
||||
|
||||
// Current mode
|
||||
avmode_t cm;
|
||||
|
||||
extern mode_data_t video_modes[];
|
||||
extern mode_data_t video_modes_plm[];
|
||||
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];
|
||||
@ -64,11 +62,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;
|
||||
@ -82,9 +80,13 @@ avinput_t target_input;
|
||||
|
||||
alt_u8 pcm1862_active;
|
||||
|
||||
alt_u32 pclk_out;
|
||||
uint8_t sl_def_iv_x, sl_def_iv_y;
|
||||
|
||||
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:
|
||||
@ -98,9 +100,12 @@ alt_u32 read_it2(alt_u32 regaddr);
|
||||
// 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, 0x08040220, 0x00004022, 0x00000000}}, // 1x, 1x (default)
|
||||
{{0x0dc06000, 0x00783c11, 0x070180e0, 0x0000180e, 0x00000000}}, // 2x, 5x
|
||||
{{0x0d806000, 0x00301804, 0x02014060, 0x00001406, 0x00000000}} }; // 3x, 4x
|
||||
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)
|
||||
|
||||
volatile sc_regs *sc = (volatile sc_regs*)SC_CONFIG_0_BASE;
|
||||
volatile osd_regs *osd = (volatile osd_regs*)OSD_GENERATOR_0_BASE;
|
||||
@ -148,7 +153,7 @@ inline void SetupAudio(tx_mode_t mode)
|
||||
EnableAudioInfoFrame(FALSE, NULL);
|
||||
|
||||
if (mode != TX_DVI) {
|
||||
EnableAudioOutput4OSSC(pclk_out, tc.audio_dw_sampl, tc.audio_swap_lr);
|
||||
EnableAudioOutput4OSSC(cm.pclk_o_hz, tc.audio_dw_sampl, tc.audio_swap_lr);
|
||||
HDMITX_SetAudioInfoFrame((BYTE)tc.audio_dw_sampl);
|
||||
#ifdef DEBUG
|
||||
Switch_HDMITX_Bank(1);
|
||||
@ -175,7 +180,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(cm.hdmitx_vic, (mode == TX_HDMI_RGB) ? F_MODE_RGB444 : F_MODE_YUV444, 0, 0, tc.hdmi_itc, cm.hdmitx_pixr_ifr);
|
||||
HDMITX_SetAVIInfoFrame(vmode_out.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;
|
||||
}
|
||||
|
||||
@ -225,8 +230,7 @@ void pll_reconfigure(alt_u8 id)
|
||||
void set_lpf(alt_u8 lpf)
|
||||
{
|
||||
alt_u32 pclk;
|
||||
pclk = (TVP_EXTCLK_HZ/cm.clkcnt)*video_modes[cm.id].h_total;
|
||||
printf("PCLK_in: %luHz\n", pclk);
|
||||
pclk = estimate_dotclk(&vmode_in, (TVP_EXTCLK_HZ/cm.clkcnt));
|
||||
|
||||
//Auto
|
||||
if (lpf == 0) {
|
||||
@ -245,7 +249,6 @@ 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;
|
||||
@ -281,151 +284,84 @@ 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 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;
|
||||
alt_u32 totlines, clkcnt, pcnt_frame;
|
||||
alt_u8 progressive, sync_active, valid_linecnt;
|
||||
status_t status = NO_CHANGE;
|
||||
alt_timestamp_type start_ts = alt_timestamp();
|
||||
|
||||
// Wait until vsync active (avoid noise coupled to I2C bus on earlier prototypes)
|
||||
for (ctr=0; ctr<STATUS_TIMEOUT; ctr++) {
|
||||
if (sc->sc_status.vsync_flag) {
|
||||
//printf("ctrval %u\n", ctr);
|
||||
while (alt_timestamp() < start_ts + STATUS_TIMEOUT_US*(TIMER_0_FREQ/1000000)) {
|
||||
if (IORD_ALTERA_AVALON_PIO_DATA(PIO_1_BASE) & VSYNC_FLAG_MASK)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
sync_active = tvp_check_sync(syncinput);
|
||||
vsyncmode = cm.sync_active ? sc->sc_status.fpga_vsyncgen : 0;
|
||||
//sync_active = tvp_check_sync(syncinput);
|
||||
sync_active = sc->fe_status.sync_active;
|
||||
|
||||
// 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
|
||||
}
|
||||
// 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;
|
||||
clkcnt = pcnt_frame/(totlines>>!progressive);
|
||||
|
||||
valid_linecnt = check_linecnt(progressive, totlines);
|
||||
|
||||
// TVP7002 may randomly report "no sync" (especially with arcade boards),
|
||||
// thus disable output only after N consecutive "no sync"-events
|
||||
// Check sync activity
|
||||
if (!cm.sync_active && sync_active && valid_linecnt) {
|
||||
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++;
|
||||
}
|
||||
cm.sync_active = 1;
|
||||
status = ACTIVITY_CHANGE;
|
||||
} else if (cm.sync_active && (!sync_active || !valid_linecnt)) {
|
||||
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;
|
||||
cm.sync_active = 0;
|
||||
status = ACTIVITY_CHANGE;
|
||||
}
|
||||
|
||||
if (valid_linecnt) {
|
||||
// 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 ((totlines != cm.totlines) ||
|
||||
(progressive != cm.progressive) ||
|
||||
(pcnt_frame < (cm.pcnt_frame - PCNT_TOLERANCE)) ||
|
||||
(pcnt_frame > (cm.pcnt_frame + PCNT_TOLERANCE))) {
|
||||
printf("totlines: %lu (cur) / %lu (prev), pcnt_frame: %lu (cur) / %lu (prev)\n", totlines, cm.totlines, pcnt_frame, cm.pcnt_frame);
|
||||
|
||||
status = (status < MODE_CHANGE) ? MODE_CHANGE : status;
|
||||
}
|
||||
|
||||
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))
|
||||
if (memcmp(&tc, &cm.cc, offsetof(avconfig_t, sl_mode)) || (update_cur_vm == 1))
|
||||
status = (status < MODE_CHANGE) ? MODE_CHANGE : status;
|
||||
|
||||
if ((tc.s480p_mode != cm.cc.s480p_mode) && (video_modes[cm.id].v_total == 525))
|
||||
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))
|
||||
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.progressive = progressive;
|
||||
}
|
||||
|
||||
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))
|
||||
if (memcmp(&tc.sl_mode, &cm.cc.sl_mode, offsetof(avconfig_t, sync_vth) - offsetof(avconfig_t, sl_mode)))
|
||||
status = (status < SC_CONFIG_CHANGE) ? SC_CONFIG_CHANGE : status;
|
||||
|
||||
if (tc.sync_vth != cm.cc.sync_vth)
|
||||
@ -468,6 +404,12 @@ 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;
|
||||
@ -476,286 +418,246 @@ status_t get_status(tvp_sync_input_t syncinput)
|
||||
return status;
|
||||
}
|
||||
|
||||
void update_sc_config()
|
||||
void update_sc_config(mode_data_t *vm_in, mode_data_t *vm_out, vm_proc_config_t *vm_conf, avconfig_t *avconfig)
|
||||
{
|
||||
h_config_reg h_config = {.data=0x00000000};
|
||||
h_config2_reg h_config2 = {.data=0x00000000};
|
||||
v_config_reg v_config = {.data=0x00000000};
|
||||
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};
|
||||
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};
|
||||
|
||||
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 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 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;
|
||||
// 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;
|
||||
|
||||
int i;
|
||||
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;
|
||||
|
||||
// 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);
|
||||
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;
|
||||
} else {
|
||||
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;
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
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;
|
||||
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;
|
||||
} else {
|
||||
sl_l_str_arr |= cm.cc.sl_str<<(4*i);
|
||||
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;
|
||||
}
|
||||
}
|
||||
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;
|
||||
sl_config.sl_method = avconfig->sl_method;
|
||||
sl_config.sl_altern = avconfig->sl_altern;
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
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->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;
|
||||
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()
|
||||
{
|
||||
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;
|
||||
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;
|
||||
|
||||
// Mark as stable (needed after sync up to avoid unnecessary mode switch)
|
||||
stable_frames = STABLE_THOLD;
|
||||
memset(&vmode_in, 0, sizeof(mode_data_t));
|
||||
cm.tx_pixelrep = cm.hdmitx_pixr_ifr = 0;
|
||||
|
||||
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;
|
||||
}
|
||||
vmode_in.timings.v_hz_x100 = (100*27000000UL)/cm.pcnt_frame;
|
||||
h_hz = (100*27000000UL)/((100*cm.pcnt_frame*(1+!cm.progressive))/cm.totlines);
|
||||
|
||||
printf("\nLines: %u %c\n", (unsigned)cm.totlines, cm.progressive ? 'p' : 'i');
|
||||
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));
|
||||
printf("Clocks per line: %u\n", (unsigned)cm.clkcnt);
|
||||
|
||||
h_syncinlen = tvp_readreg(TVP_HSINWIDTH);
|
||||
v_syncinlen = tvp_readreg(TVP_VSINWIDTH);
|
||||
printf("Hswidth: %u Vswidth: %u Macrovision: %u\n", (unsigned)h_syncinlen, (unsigned)(v_syncinlen & 0x1F), (unsigned)cm.macrovis);
|
||||
macrovis = !!(tvp_readreg(TVP_LINECNT2) & (1<<6));
|
||||
printf("Hswidth: %u Vswidth: %u Macrovision: %u\n", (unsigned)h_syncinlen, (unsigned)(v_syncinlen & 0x1F), (unsigned)macrovis);
|
||||
|
||||
vmode_in.timings.h_synclen = h_syncinlen;
|
||||
vmode_in.timings.v_total = cm.totlines;
|
||||
vmode_in.timings.interlaced = !cm.progressive;
|
||||
|
||||
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)(v_hz_x100/100), (unsigned)(v_hz_x100%100));
|
||||
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));
|
||||
ui_disp_status(1);
|
||||
|
||||
//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);
|
||||
retval = get_pure_lm_mode(&cm.cc, &vmode_in, &vmode_out, &vm_conf);
|
||||
|
||||
if (cm.id == -1) {
|
||||
printf ("Error: no suitable mode found, defaulting to 240p\n");
|
||||
cm.id = 4;
|
||||
if (retval == -1) {
|
||||
printf ("ERROR: no suitable mode preset found\n");
|
||||
vm_conf.si_pclk_mult = 0;
|
||||
return;
|
||||
}
|
||||
cm.id = retval;
|
||||
vm_sel = cm.id;
|
||||
|
||||
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);
|
||||
// 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);
|
||||
|
||||
// Trilevel sync is used with HDTV modes using composite sync
|
||||
if (video_modes[cm.id].type & VIDEO_HDTV)
|
||||
if (video_modes_plm[cm.id].type & VIDEO_HDTV)
|
||||
target_type = (target_tvp_sync <= TVP_SOG3) ? VIDEO_HDTV : VIDEO_PC;
|
||||
else
|
||||
target_type = video_modes[cm.id].type;
|
||||
target_type = video_modes_plm[cm.id].type;
|
||||
|
||||
h_synclen_px = ((alt_u32)h_syncinlen * (alt_u32)cm.h_mult_total) / cm.clkcnt;
|
||||
h_synclen_px = ((alt_u32)h_syncinlen * pll_h_total) / cm.clkcnt;
|
||||
|
||||
printf("Mode %s selected - hsync width: %upx\n", video_modes[cm.id].name, (unsigned)h_synclen_px);
|
||||
printf("Mode %s selected - hsync width: %upx\n", video_modes_plm[cm.id].name, (unsigned)h_synclen_px);
|
||||
|
||||
tvp_source_setup(target_type,
|
||||
cm.h_mult_total,
|
||||
pll_h_total,
|
||||
cm.clkcnt,
|
||||
cm.cc.tvp_hpll2x && (video_modes[cm.id].flags & MODE_PLLDIVBY2),
|
||||
0,
|
||||
(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);
|
||||
|
||||
pll_reconfig->pll_config_status.reset = (cm.fpga_vmultmode == FPGA_V_MULTMODE_1X);
|
||||
set_sampler_phase(video_modes_plm[cm.id].sampler_phase);
|
||||
|
||||
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;
|
||||
}
|
||||
pll_reconfigure(cm.pll_config);
|
||||
pll_reconfig->pll_config_status.reset = (vm_conf.si_pclk_mult <= 1);
|
||||
|
||||
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);
|
||||
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 {
|
||||
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;
|
||||
sys_ctrl |= PLL_BYPASS;
|
||||
}
|
||||
osd->osd_config.x_size = osd_x_size;
|
||||
osd->osd_config.y_size = osd_y_size;
|
||||
IOWR_ALTERA_AVALON_PIO_DATA(PIO_0_BASE, sys_ctrl);
|
||||
|
||||
update_sc_config();
|
||||
update_osd_size(&vmode_out);
|
||||
|
||||
update_sc_config(&vmode_in, &vmode_out, &vm_conf, &cm.cc);
|
||||
|
||||
TX_SetPixelRepetition(cm.tx_pixelrep, ((cm.cc.tx_mode!=TX_DVI) && (cm.tx_pixelrep == cm.hdmitx_pixr_ifr)) ? 1 : 0);
|
||||
|
||||
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)
|
||||
if (cm.pclk_o_hz > 85000000)
|
||||
hdmitx_pclk_level = 1;
|
||||
else if (pclk_out < 75000000)
|
||||
else if (cm.pclk_o_hz < 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(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);
|
||||
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);
|
||||
#ifdef ENABLE_AUDIO
|
||||
#ifdef MANUAL_CTS
|
||||
SetupAudio(cm.cc.tx_mode);
|
||||
@ -805,8 +707,9 @@ 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->h_config.data = 0x00000000;
|
||||
sc->v_config.data = 0x00000000;
|
||||
sc->hv_in_config.data = 0x00000000;
|
||||
sc->hv_in_config2.data = 0x00000000;
|
||||
sc->hv_in_config3.data = 0x00000000;
|
||||
usleep(10000);
|
||||
|
||||
// unreset hw
|
||||
@ -870,21 +773,18 @@ 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 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;
|
||||
// Setup test pattern
|
||||
get_vmode(VMODE_480p, &vmode_in, &vmode_out, &vm_conf);
|
||||
update_sc_config(&vmode_in, &vmode_out, &vm_conf, &cm.cc);
|
||||
|
||||
// init always in HDMI mode (fixes yellow screen bug)
|
||||
cm.hdmitx_vic = HDMI_480p60;
|
||||
TX_enable(TX_HDMI_RGB);
|
||||
|
||||
// Setup remote keymap
|
||||
@ -894,6 +794,39 @@ 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;
|
||||
@ -955,18 +888,6 @@ 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;
|
||||
@ -991,7 +912,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-2022 marqs", LCD_ROW_LEN+1);
|
||||
strncpy(row2, "2014-2023 marqs", LCD_ROW_LEN+1);
|
||||
#else
|
||||
strncpy(row2, "** DEBUG BUILD *", LCD_ROW_LEN+1);
|
||||
#endif
|
||||
@ -1151,7 +1072,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_disable_output();
|
||||
tvp_powerdown();
|
||||
#ifdef ENABLE_AUDIO
|
||||
DisableAudioOutput();
|
||||
if (pcm1862_active)
|
||||
@ -1159,6 +1080,10 @@ 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);
|
||||
@ -1174,7 +1099,7 @@ int main()
|
||||
|
||||
// Check here to enable regardless of input
|
||||
if (tc.tx_mode != cm.cc.tx_mode) {
|
||||
HDMITX_SetAVIInfoFrame(cm.hdmitx_vic, F_MODE_RGB444, 0, 0, 0, 0);
|
||||
HDMITX_SetAVIInfoFrame(vmode_out.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
|
||||
@ -1182,7 +1107,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(cm.hdmitx_vic, (tc.tx_mode == TX_HDMI_RGB) ? F_MODE_RGB444 : F_MODE_YUV444, 0, 0, tc.hdmi_itc, cm.hdmitx_pixr_ifr);
|
||||
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);
|
||||
cm.cc.hdmi_itc = tc.hdmi_itc;
|
||||
}
|
||||
if (tc.av3_alt_rgb != cm.cc.av3_alt_rgb) {
|
||||
@ -1208,11 +1133,15 @@ int main()
|
||||
printf("Sync up\n");
|
||||
sys_ctrl |= VIDGEN_OFF;
|
||||
IOWR_ALTERA_AVALON_PIO_DATA(PIO_0_BASE, sys_ctrl);
|
||||
enable_outputs();
|
||||
tvp_powerup();
|
||||
program_mode();
|
||||
#ifdef ENABLE_AUDIO
|
||||
SetupAudio(cm.cc.tx_mode);
|
||||
#endif
|
||||
} else {
|
||||
printf("Sync lost\n");
|
||||
cm.clkcnt = 0; //TODO: proper invalidate
|
||||
tvp_disable_output();
|
||||
tvp_powerdown();
|
||||
//ths_source_sel(THS_STANDBY, 0);
|
||||
strncpy(row1, avinput_str[cm.avinput], LCD_ROW_LEN+1);
|
||||
strncpy(row2, " NO SYNC", LCD_ROW_LEN+1);
|
||||
@ -1231,7 +1160,7 @@ int main()
|
||||
case SC_CONFIG_CHANGE:
|
||||
if (cm.sync_active) {
|
||||
printf("Scanconverter config change\n");
|
||||
update_sc_config();
|
||||
update_sc_config(&vmode_in, &vmode_out, &vm_conf, &cm.cc);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright (C) 2015-2019 Markus Hiienkari <mhiienka@niksula.hut.fi>
|
||||
// Copyright (C) 2015-2023 Markus Hiienkari <mhiienka@niksula.hut.fi>
|
||||
//
|
||||
// This file is part of Open Source Scan Converter project.
|
||||
//
|
||||
@ -30,6 +30,8 @@
|
||||
#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)
|
||||
@ -39,37 +41,18 @@
|
||||
#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 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 VSYNC_FLAG_MASK 0x00100000
|
||||
|
||||
#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 {
|
||||
@ -93,24 +76,16 @@ typedef struct {
|
||||
//TODO: transform binary values into flags
|
||||
typedef struct {
|
||||
alt_u32 totlines;
|
||||
alt_u32 pcnt_frame;
|
||||
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;
|
||||
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;
|
||||
alt_u32 pclk_o_hz;
|
||||
avinput_t avinput;
|
||||
alt_u8 pll_config;
|
||||
// Current configuration
|
||||
avconfig_t cc;
|
||||
} avmode_t;
|
||||
@ -118,9 +93,12 @@ 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
|
||||
|
@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright (C) 2015-2019 Markus Hiienkari <mhiienka@niksula.hut.fi>
|
||||
// Copyright (C) 2015-2023 Markus Hiienkari <mhiienka@niksula.hut.fi>
|
||||
//
|
||||
// This file is part of Open Source Scan Converter project.
|
||||
//
|
||||
@ -26,7 +26,6 @@
|
||||
|
||||
#define DEFAULT_ON 1
|
||||
|
||||
extern mode_data_t video_modes[], video_modes_default[];
|
||||
extern alt_u8 update_cur_vm;
|
||||
|
||||
// Target configuration
|
||||
@ -34,24 +33,21 @@ 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,
|
||||
.tvp_hpll2x = DEFAULT_ON,
|
||||
.l3_mode = 1,
|
||||
.clamp_offset = SIGNED_NUMVAL_ZERO,
|
||||
.sl_altern = 1,
|
||||
.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,
|
||||
.sl_altern = 1,
|
||||
#ifdef ENABLE_AUDIO
|
||||
.audio_dw_sampl = DEFAULT_ON,
|
||||
.tx_mode = TX_HDMI_RGB,
|
||||
.audio_gain = AUDIO_GAIN_0DB,
|
||||
#endif
|
||||
.sync_lpf = DEFAULT_SYNC_LPF,
|
||||
.alc_h_filter = DEFAULT_ALC_H_FILTER,
|
||||
.alc_v_filter = DEFAULT_ALC_V_FILTER,
|
||||
.col = {
|
||||
.r_f_gain = DEFAULT_FINE_GAIN,
|
||||
.g_f_gain = DEFAULT_FINE_GAIN,
|
||||
@ -61,10 +57,11 @@ const avconfig_t tc_default = {
|
||||
.b_f_off = DEFAULT_FINE_OFFSET,
|
||||
.c_gain = DEFAULT_COARSE_GAIN,
|
||||
},
|
||||
#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()
|
||||
@ -74,7 +71,7 @@ int set_default_avconfig()
|
||||
tc.tx_mode = (IORD_ALTERA_AVALON_PIO_DATA(PIO_1_BASE) & HDMITX_MODE_MASK) ? TX_DVI : TX_HDMI_RGB;
|
||||
#endif
|
||||
|
||||
memcpy(video_modes, video_modes_default, VIDEO_MODES_SIZE);
|
||||
set_default_vm_table();
|
||||
update_cur_vm = 1;
|
||||
|
||||
return 0;
|
||||
|
@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright (C) 2015-2019 Markus Hiienkari <mhiienka@niksula.hut.fi>
|
||||
// Copyright (C) 2015-2023 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 "tvp7002.h"
|
||||
#include "sysconfig.h"
|
||||
|
||||
#define SIGNED_NUMVAL_ZERO 128
|
||||
|
||||
@ -73,60 +73,75 @@ typedef enum {
|
||||
} avinput_t;
|
||||
|
||||
typedef struct {
|
||||
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 linemult_target;
|
||||
alt_u8 l2_mode;
|
||||
alt_u8 l3_mode;
|
||||
alt_u8 l4_mode;
|
||||
alt_u8 l5_mode;
|
||||
alt_u8 l5_fmt;
|
||||
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 ar_256col;
|
||||
alt_u8 h_mask;
|
||||
alt_u8 v_mask;
|
||||
alt_u8 mask_br;
|
||||
alt_u8 mask_color;
|
||||
alt_u8 tx_mode;
|
||||
alt_u8 hdmi_itc;
|
||||
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 tvp_hpll2x;
|
||||
alt_u8 upsample2x;
|
||||
alt_u8 ypbpr_cs;
|
||||
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_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 mask_br;
|
||||
alt_u8 mask_color;
|
||||
alt_u8 reverse_lpf;
|
||||
|
||||
/* AFE settings */
|
||||
alt_u8 sync_vth;
|
||||
alt_u8 linelen_tol;
|
||||
alt_u8 vsync_thold;
|
||||
alt_u8 sync_lpf;
|
||||
alt_u8 stc_lpf;
|
||||
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 default_vic;
|
||||
alt_u8 clamp_offset;
|
||||
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 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;
|
||||
avinput_t link_av;
|
||||
} __attribute__((packed)) avconfig_t;
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright (C) 2015-2019 Markus Hiienkari <mhiienka@niksula.hut.fi>
|
||||
// Copyright (C) 2015-2023 Markus Hiienkari <mhiienka@niksula.hut.fi>
|
||||
//
|
||||
// This file is part of Open Source Scan Converter project.
|
||||
//
|
||||
@ -38,25 +38,24 @@ 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[];
|
||||
extern mode_data_t video_modes_plm[];
|
||||
extern avmode_t cm;
|
||||
extern avconfig_t tc;
|
||||
extern avinput_t target_input;
|
||||
extern alt_u8 menu_active;
|
||||
extern alt_u16 sys_ctrl;
|
||||
extern alt_u32 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 update_cur_vm, vm_edit;
|
||||
extern volatile sc_regs *sc;
|
||||
extern alt_u8 vm_edit;
|
||||
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()
|
||||
{
|
||||
@ -122,13 +121,9 @@ 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_384p, &tc.pm_480i, &tc.pm_480p, &tc.pm_480p, &tc.pm_1080i };
|
||||
alt_u8 valid_pm[] = { 0x1, 0x1f, 0x3, 0xf, 0x3, 0x3, 0x3 };
|
||||
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 };
|
||||
|
||||
avinput_t next_input = (cm.avinput == AV3_YPBPR) ? AV1_RGBs : (cm.avinput+1);
|
||||
|
||||
@ -169,34 +164,7 @@ int parse_control()
|
||||
|
||||
break;
|
||||
case RC_INFO:
|
||||
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;
|
||||
}
|
||||
print_vm_stats();
|
||||
break;
|
||||
case RC_LCDBL:
|
||||
sys_ctrl ^= LCD_BL;
|
||||
@ -217,8 +185,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[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);
|
||||
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);
|
||||
osd->osd_config.status_refresh = 1;
|
||||
osd->osd_row_color.mask = 0;
|
||||
osd->osd_sec_enable[0].mask = 3;
|
||||
@ -259,14 +227,14 @@ int parse_control()
|
||||
break;
|
||||
}
|
||||
|
||||
if (video_modes[cm.id].group > GROUP_1080I) {
|
||||
if (video_modes_plm[cm.id].group > GROUP_1080P) {
|
||||
printf("WARNING: Corrupted mode (id %d)\n", cm.id);
|
||||
break;
|
||||
}
|
||||
|
||||
if (i <= RC_BTN5) {
|
||||
if ((1<<i) & valid_pm[video_modes[cm.id].group]) {
|
||||
*pmcfg_ptr[video_modes[cm.id].group] = i;
|
||||
if ((1<<i) & valid_pm[video_modes_plm[cm.id].group]) {
|
||||
*pmcfg_ptr[video_modes_plm[cm.id].group] = i;
|
||||
} else {
|
||||
sniprintf(menu_row2, LCD_ROW_LEN+1, "%ux unsupported", i+1);
|
||||
ui_disp_menu(1);
|
||||
@ -285,25 +253,28 @@ int parse_control()
|
||||
break;
|
||||
case RC_PHASE_MINUS:
|
||||
case RC_PHASE_PLUS:
|
||||
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 (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;
|
||||
|
||||
update_cur_vm = 1;
|
||||
if (cm.id == vm_edit)
|
||||
tc_sampler_phase = video_modes[vm_edit].sampler_phase;
|
||||
if (cm.id == vm_edit)
|
||||
tc_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);
|
||||
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();
|
||||
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();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case RC_PROF_HOTKEY:
|
||||
|
@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright (C) 2015-2018 Markus Hiienkari <mhiienka@niksula.hut.fi>
|
||||
// Copyright (C) 2015-2023 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_u16 sys_ctrl;
|
||||
extern alt_u32 sys_ctrl;
|
||||
|
||||
static int check_fw_header(alt_u8 *databuf, fw_hdr *hdr)
|
||||
{
|
||||
@ -146,7 +146,7 @@ int fw_update()
|
||||
}
|
||||
|
||||
//disable video output
|
||||
tvp_disable_output();
|
||||
tvp_powerdown();
|
||||
sys_ctrl |= VIDGEN_OFF;
|
||||
IOWR_ALTERA_AVALON_PIO_DATA(PIO_0_BASE, sys_ctrl);
|
||||
usleep(10000);
|
||||
|
@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright (C) 2015-2022 Markus Hiienkari <mhiienka@niksula.hut.fi>
|
||||
// Copyright (C) 2015-2023 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 0
|
||||
#define FW_VER_MINOR 90
|
||||
#define FW_VER_MAJOR 1
|
||||
#define FW_VER_MINOR 02
|
||||
|
||||
#define PROFILE_VER_MAJOR 0
|
||||
#define PROFILE_VER_MINOR 88
|
||||
#define PROFILE_VER_MAJOR 1
|
||||
#define PROFILE_VER_MINOR 02
|
||||
|
||||
#define INITCFG_VER_MAJOR 0
|
||||
#define INITCFG_VER_MINOR 85
|
||||
#define INITCFG_VER_MAJOR 1
|
||||
#define INITCFG_VER_MINOR 00
|
||||
|
||||
#ifdef ENABLE_AUDIO
|
||||
#define FW_SUFFIX1 "a"
|
||||
|
@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright (C) 2015-2019 Markus Hiienkari <mhiienka@niksula.hut.fi>
|
||||
// Copyright (C) 2015-2023 Markus Hiienkari <mhiienka@niksula.hut.fi>
|
||||
//
|
||||
// This file is part of Open Source Scan Converter project.
|
||||
//
|
||||
@ -32,15 +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[];
|
||||
extern mode_data_t video_modes_plm[];
|
||||
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;
|
||||
extern alt_u8 osd_enable, osd_status_timeout, phase_hotkey_enable;
|
||||
extern uint8_t sl_def_iv_x, sl_def_iv_y;
|
||||
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;
|
||||
alt_u8 menu_active;
|
||||
@ -58,7 +60,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", "Line2x 240x360", "Line3x 240x360", "Line3x Generic" };
|
||||
static const char *pm_384p_desc[] = { LNG("Passthru","パススルー"), "Line2x", "Line3x Generic", "Line2x 240x360", "Line3x 240x360" };
|
||||
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" };
|
||||
@ -82,6 +84,8 @@ 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); }
|
||||
@ -89,14 +93,15 @@ 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[v].name, LCD_ROW_LEN+1); }
|
||||
static void vm_display_name (alt_u8 v) { strncpy(menu_row2, video_modes_plm[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 const arg_info_t vm_arg_info = {&vm_sel, VIDEO_MODES_CNT-1, vm_display_name};
|
||||
static arg_info_t vm_arg_info = {&vm_sel, 0, 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 = {<_sel, (sizeof(lt_desc)/sizeof(char*))-1, lt_disp};
|
||||
|
||||
@ -106,7 +111,7 @@ 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_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("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 } } },
|
||||
@ -114,6 +119,8 @@ MENU(menu_advtiming, P99_PROTECT({ \
|
||||
}))
|
||||
|
||||
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 } } },
|
||||
@ -146,7 +153,6 @@ 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 } } },
|
||||
}))
|
||||
@ -180,36 +186,34 @@ MENU(menu_output, P99_PROTECT({ \
|
||||
MENU(menu_scanlines, P99_PROTECT({ \
|
||||
{ LNG("Scanlines","スキャンライン"), OPT_AVCONFIG_SELECTION, { .sel = { &tc.sl_mode, OPT_WRAP, SETTING_ITEM(sl_mode_desc) } } },
|
||||
{ LNG("Sl. strength","スキャンラインツヨサ"), OPT_AVCONFIG_NUMVALUE, { .num = { &tc.sl_str, OPT_NOWRAP, 0, SCANLINESTR_MAX, sl_str_disp } } },
|
||||
{ "Sl. hybrid str.", OPT_AVCONFIG_NUMVALUE, { .num = { &tc.sl_hybr_str, OPT_NOWRAP, 0, SL_HYBRIDSTR_MAX, sl_hybr_str_disp } } },
|
||||
//{ "Sl. hybrid str.", OPT_AVCONFIG_NUMVALUE, { .num = { &tc.sl_hybr_str, OPT_NOWRAP, 0, SL_HYBRIDSTR_MAX, sl_hybr_str_disp } } },
|
||||
{ "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 } } },
|
||||
//{ 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("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, <_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, <_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 } } },
|
||||
@ -218,9 +222,6 @@ 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) } } },
|
||||
@ -231,6 +232,10 @@ 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 } } },
|
||||
@ -260,6 +265,21 @@ 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) {
|
||||
@ -450,48 +470,68 @@ void display_menu(alt_u8 forcedisp)
|
||||
ui_disp_menu(0);
|
||||
}
|
||||
|
||||
static void vm_select() {
|
||||
vm_edit = vm_sel;
|
||||
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;
|
||||
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_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))
|
||||
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_sampler_phase = video_modes_plm[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))
|
||||
update_cur_vm = 1;
|
||||
if (video_modes_plm[cm.id].sampler_phase != tc_sampler_phase)
|
||||
set_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;
|
||||
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].sampler_phase = tc_sampler_phase;
|
||||
|
||||
if (v == &tc_sampler_phase)
|
||||
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);
|
||||
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);
|
||||
else
|
||||
sniprintf(menu_row2, LCD_ROW_LEN+1, "%u", *v);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright (C) 2015-2016 Markus Hiienkari <mhiienka@niksula.hut.fi>
|
||||
// Copyright (C) 2015-2023 Markus Hiienkari <mhiienka@niksula.hut.fi>
|
||||
//
|
||||
// This file is part of Open Source Scan Converter project.
|
||||
//
|
||||
@ -21,7 +21,9 @@
|
||||
#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
|
||||
@ -121,10 +123,12 @@ 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
|
||||
|
@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright (C) 2015-2018 Markus Hiienkari <mhiienka@niksula.hut.fi>
|
||||
// Copyright (C) 2015-2023 Markus Hiienkari <mhiienka@niksula.hut.fi>
|
||||
//
|
||||
// This file is part of Open Source Scan Converter project.
|
||||
//
|
||||
@ -32,10 +32,15 @@
|
||||
#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[];
|
||||
extern mode_data_t video_modes_plm[];
|
||||
extern avinput_t target_input;
|
||||
extern alt_u8 update_cur_vm;
|
||||
extern alt_u8 input_profiles[AV_LAST];
|
||||
@ -43,7 +48,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;
|
||||
extern alt_u8 osd_enable, osd_status_timeout, phase_hotkey_enable;
|
||||
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];
|
||||
@ -83,6 +88,7 @@ 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]);
|
||||
@ -95,7 +101,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 = VIDEO_MODES_SIZE;
|
||||
vm_to_write = sizeof(video_modes_plm_default);
|
||||
((ude_profile*)databuf)->avc_data_len = sizeof(avconfig_t);
|
||||
((ude_profile*)databuf)->vm_data_len = vm_to_write;
|
||||
|
||||
@ -110,8 +116,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) >> PAGESIZE
|
||||
memcpy(databuf+pageoffset, (char*)video_modes, PAGESIZE-pageoffset);
|
||||
// erase sector and write a full page first, assume sizeof(video_modes_plm) >> PAGESIZE
|
||||
memcpy(databuf+pageoffset, (char*)video_modes_plm, PAGESIZE-pageoffset);
|
||||
srcoffset = PAGESIZE-pageoffset;
|
||||
vm_to_write -= PAGESIZE-pageoffset;
|
||||
for (i=0; i<PAGESIZE; i++)
|
||||
@ -123,7 +129,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+srcoffset, (vm_to_write > PAGESIZE) ? PAGESIZE : vm_to_write);
|
||||
memcpy(databuf, (char*)video_modes_plm+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);
|
||||
@ -135,7 +141,7 @@ int write_userdata(alt_u8 entry)
|
||||
pageno++;
|
||||
}
|
||||
|
||||
printf("Profile %u data written (%u bytes)\n", entry, sizeof(avconfig_t)+VIDEO_MODES_SIZE);
|
||||
printf("Profile %u data written (%u bytes)\n", entry, sizeof(avconfig_t)+sizeof(video_modes_plm_default));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -197,6 +203,7 @@ 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));
|
||||
}
|
||||
@ -206,7 +213,7 @@ int read_userdata(alt_u8 entry, int dry_run)
|
||||
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 == VIDEO_MODES_SIZE)) {
|
||||
if ((((ude_profile*)databuf)->avc_data_len == sizeof(avconfig_t)) && (((ude_profile*)databuf)->vm_data_len == sizeof(video_modes_plm_default))) {
|
||||
strncpy(target_profile_name, ((ude_profile*)databuf)->name, PROFILE_NAME_LEN+1);
|
||||
if (dry_run)
|
||||
return 0;
|
||||
@ -223,7 +230,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+dstoffset, databuf+pageoffset, PAGESIZE-pageoffset);
|
||||
memcpy((char*)video_modes_plm+dstoffset, databuf+pageoffset, PAGESIZE-pageoffset);
|
||||
dstoffset += PAGESIZE-pageoffset;
|
||||
vm_to_read -= PAGESIZE-pageoffset;
|
||||
pageoffset = 0;
|
||||
@ -235,14 +242,14 @@ int read_userdata(alt_u8 entry, int dry_run)
|
||||
if (retval != 0)
|
||||
return retval;
|
||||
} else {
|
||||
memcpy((char*)video_modes+dstoffset, databuf+pageoffset, vm_to_read);
|
||||
memcpy((char*)video_modes_plm+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)+VIDEO_MODES_SIZE);
|
||||
printf("Profile %u data read (%u bytes)\n", entry, sizeof(avconfig_t)+sizeof(video_modes_plm_default));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@ -315,7 +322,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(ude_initcfg), databuf);
|
||||
(header.type == UDE_PROFILE) ? (sizeof(ude_profile)+sizeof(video_modes_plm_default)) : sizeof(ude_initcfg), databuf);
|
||||
if (retval != 0) {
|
||||
printf("Copy from SD to flash failed (error %d)\n", retval);
|
||||
goto sd_disable;
|
||||
|
@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright (C) 2015-2018 Markus Hiienkari <mhiienka@niksula.hut.fi>
|
||||
// Copyright (C) 2015-2023 Markus Hiienkari <mhiienka@niksula.hut.fi>
|
||||
//
|
||||
// This file is part of Open Source Scan Converter project.
|
||||
//
|
||||
@ -62,6 +62,7 @@ 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;
|
||||
|
||||
@ -71,7 +72,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);
|
||||
|
489
software/sys_controller/ossc/video_modes.c
Normal file
489
software/sys_controller/ossc/video_modes.c
Normal file
@ -0,0 +1,489 @@
|
||||
//
|
||||
// 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->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;
|
||||
vm_out->timings.h_synclen /= 3;
|
||||
vm_out->timings.h_backporch /= 3;
|
||||
vm_out->timings.h_active /= 3;
|
||||
vm_conf->x_offset = vm_out->timings.h_active/2;
|
||||
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;
|
||||
//cm.hsync_cut = 13;
|
||||
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;
|
||||
//cm.hsync_cut = 40;
|
||||
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;
|
||||
//cm.hsync_cut = 30;
|
||||
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;
|
||||
//cm.hsync_cut = 24;
|
||||
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;
|
||||
//cm.hsync_cut = 20;
|
||||
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*(vm_conf->x_rpt+1);
|
||||
if (vm_conf->y_size == 0)
|
||||
vm_conf->y_size = vm_out->timings.v_active;
|
||||
|
||||
vm_conf->x_offset = ((vm_out->timings.h_active-vm_conf->x_size)/2);
|
||||
vm_conf->x_start_lb = (vm_conf->x_offset >= 0) ? 0 : (-vm_conf->x_offset / (vm_conf->x_rpt+1));
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
||||
#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));
|
||||
|
||||
return 0;
|
||||
}
|
173
software/sys_controller/ossc/video_modes.h
Normal file
173
software/sys_controller/ossc/video_modes.h
Normal file
@ -0,0 +1,173 @@
|
||||
//
|
||||
// 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 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;
|
||||
aspect_ratio_t ar;
|
||||
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_ */
|
84
software/sys_controller/ossc/video_modes_list.c
Normal file
84
software/sys_controller/ossc/video_modes_list.c
Normal file
@ -0,0 +1,84 @@
|
||||
//
|
||||
// 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, { 4, 3}, 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, { 4, 3}, 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, { 4, 3}, 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, { 4, 3}, 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, { 4, 3}, 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, { 4, 3}, 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, { 4, 3}, 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, { 4, 3}, 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, { 4, 3}, 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, { 4, 3}, 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, { 4, 3}, 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, { 4, 3}, 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, { 4, 3}, 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, { 4, 3}, 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, { 4, 3}, 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, { 4, 3}, 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, { 4, 3}, VIDEO_EDTV, GROUP_384P, (MODE_PT | MODE_L2), },
|
||||
{ "240x360", HDMI_Unknown, { 256, 360, 6000, 300, 0, 375, 24, 10, 18, 3, 0}, DEF_PHASE, { 4, 3}, 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, { 4, 3}, 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, { 4, 3}, 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, { 4, 3}, 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, { 4, 3}, 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, { 4, 3}, 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, { 4, 3}, 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, { 4, 3}, 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, { 4, 3}, 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, {16, 9}, 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, { 4, 3}, 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, { 4, 3}, 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, { 4, 3}, 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, { 4, 3}, 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, {16, 9}, (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, {16, 9}, (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, { 4, 3}, VIDEO_PC, GROUP_NONE, MODE_PT, },
|
||||
{ "1280x960", HDMI_Unknown, {1280, 960, 6000, 1800, 0, 1000, 312, 36, 112, 3, 0}, DEF_PHASE, { 4, 3}, VIDEO_PC, GROUP_NONE, MODE_PT, },
|
||||
{ "1280x1024", HDMI_Unknown, {1280, 1024, 6000, 1688, 0, 1066, 248, 38, 112, 3, 0}, DEF_PHASE, { 5, 4}, 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, { 4, 3}, 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, {16, 9}, (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, {16, 9}, (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, {16, 9}, (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, {16, 9}, (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, { 4, 3}, VIDEO_PC, GROUP_NONE, MODE_PT, },
|
||||
};
|
@ -48,6 +48,41 @@ 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;
|
||||
|
||||
|
@ -32,6 +32,8 @@ 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();
|
||||
|
@ -23,6 +23,9 @@
|
||||
#define PCM1862_BASE (0x94>>1)
|
||||
|
||||
#define PCM1862_PAGESEL 0x00
|
||||
|
||||
/* Page 0 registers */
|
||||
|
||||
#define PCM1862_PGA1L 0x01
|
||||
#define PCM1862_PGA1R 0x02
|
||||
#define PCM1862_PGA2L 0x03
|
||||
@ -56,4 +59,17 @@
|
||||
#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_ */
|
||||
|
@ -31,7 +31,7 @@
|
||||
#define WRDELAY 20
|
||||
#define CLEARDELAY 800
|
||||
|
||||
extern alt_u16 sys_ctrl;
|
||||
extern alt_u32 sys_ctrl;
|
||||
|
||||
static void lcd_cmd(alt_u8 cmd, alt_u16 postdelay) {
|
||||
SPI_write(I2CA_BASE, &cmd, 1);
|
||||
|
@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright (C) 2015-2018 Markus Hiienkari <mhiienka@niksula.hut.fi>
|
||||
// Copyright (C) 2015-2023 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;
|
||||
@ -145,24 +145,30 @@ 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()
|
||||
{
|
||||
usleep(10000);
|
||||
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()
|
||||
{
|
||||
tvp_writereg(TVP_MISCCTRL1, 0x11);
|
||||
usleep(10000);
|
||||
tvp_writereg(TVP_MISCCTRL2, 0x02);
|
||||
usleep(10000);
|
||||
tvp_writereg(TVP_POWERCTRL, 0x00);
|
||||
}
|
||||
|
||||
inline void tvp_set_hpllcoast(alt_u8 pre, alt_u8 post)
|
||||
@ -192,9 +198,6 @@ 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
|
||||
@ -208,6 +211,9 @@ 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]);
|
||||
|
||||
@ -242,6 +248,10 @@ 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) {
|
||||
@ -344,17 +354,12 @@ void tvp_set_clp_lpf(alt_u8 val)
|
||||
printf("CLP LPF value set to 0x%x\n", val);
|
||||
}
|
||||
|
||||
alt_u8 tvp_set_hpll_phase(alt_u8 val, alt_u8 sample_mult)
|
||||
void tvp_set_hpll_phase(alt_u8 val)
|
||||
{
|
||||
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("Phase selection: %u/%u (FPGA), %u/32 (TVP)\n", sample_sel+1, sample_mult, val+1);
|
||||
|
||||
return sample_sel;
|
||||
printf("TVP Phase set to %u/32 (%u deg)\n", val, (val*11250)/1000);
|
||||
}
|
||||
|
||||
void tvp_set_sog_thold(alt_u8 val)
|
||||
@ -381,14 +386,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, 0x0C);
|
||||
tvp_writereg(TVP_MISCCTRL4, 0x0D);
|
||||
break;
|
||||
case VIDEO_LDTV:
|
||||
//case VIDEO_LDTV:
|
||||
case VIDEO_SDTV:
|
||||
case VIDEO_EDTV:
|
||||
case VIDEO_HDTV:
|
||||
default:
|
||||
tvp_writereg(TVP_MISCCTRL4, 0x08);
|
||||
tvp_writereg(TVP_MISCCTRL4, 0x09);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -412,7 +417,7 @@ void tvp_source_sel(tvp_input_t input, tvp_sync_input_t syncinput, video_format
|
||||
else // RGBS
|
||||
tvp_writereg(TVP_SYNCCTRL1, 0x53);
|
||||
|
||||
usleep(1000);
|
||||
usleep(100000);
|
||||
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");
|
||||
|
@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright (C) 2015-2018 Markus Hiienkari <mhiienka@niksula.hut.fi>
|
||||
// Copyright (C) 2015-2023 Markus Hiienkari <mhiienka@niksula.hut.fi>
|
||||
//
|
||||
// This file is part of Open Source Scan Converter project.
|
||||
//
|
||||
@ -26,7 +26,6 @@
|
||||
|
||||
#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
|
||||
@ -74,16 +73,6 @@ 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);
|
||||
|
||||
@ -95,6 +84,10 @@ 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);
|
||||
@ -115,7 +108,7 @@ void tvp_set_sync_lpf(alt_u8 val);
|
||||
|
||||
void tvp_set_clp_lpf(alt_u8 val);
|
||||
|
||||
alt_u8 tvp_set_hpll_phase(alt_u8 val, alt_u8 sample_mult);
|
||||
void tvp_set_hpll_phase(alt_u8 val);
|
||||
|
||||
void tvp_set_sog_thold(alt_u8 val);
|
||||
|
||||
|
@ -1,295 +0,0 @@
|
||||
//
|
||||
// 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;
|
||||
}
|
@ -1,183 +0,0 @@
|
||||
//
|
||||
// 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_ */
|
@ -7,7 +7,7 @@
|
||||
#include "spi_io.h"
|
||||
#include "av_controller.h"
|
||||
|
||||
extern alt_u16 sys_ctrl;
|
||||
extern alt_u32 sys_ctrl;
|
||||
|
||||
alt_u32 sd_timer_ts;
|
||||
|
||||
|
Binary file not shown.
@ -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 16
|
||||
#define PIO_0_DATA_WIDTH 32
|
||||
#define PIO_0_DO_TEST_BENCH_WIRING 0
|
||||
#define PIO_0_DRIVEN_SIM_VALUE 0
|
||||
#define PIO_0_EDGE_TYPE "NONE"
|
||||
|
366
sys.sopcinfo
366
sys.sopcinfo
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user