advanced OSD implementation

This commit is contained in:
marqs 2020-10-05 23:05:43 +03:00
parent b26b213ead
commit 9c5e7b5b83
25 changed files with 9287 additions and 8726 deletions

View File

@ -34,7 +34,7 @@ package require -exact qsys 14.1
# #
set_module_property DESCRIPTION "This component is a serial flash controller which allows user to access Altera EPCQ devices" set_module_property DESCRIPTION "This component is a serial flash controller which allows user to access Altera EPCQ devices"
set_module_property NAME altera_epcq_controller_core set_module_property NAME altera_epcq_controller_core
set_module_property VERSION 16.1 set_module_property VERSION 19.1
set_module_property INTERNAL true set_module_property INTERNAL true
set_module_property OPAQUE_ADDRESS_MAP true set_module_property OPAQUE_ADDRESS_MAP true
set_module_property AUTHOR "Altera Corporation" set_module_property AUTHOR "Altera Corporation"

View File

@ -20,7 +20,7 @@ package require -exact altera_terp 1.0
# #
set_module_property DESCRIPTION "This component is a serial flash controller which allows user to access Altera EPCQ devices" set_module_property DESCRIPTION "This component is a serial flash controller which allows user to access Altera EPCQ devices"
set_module_property NAME altera_epcq_controller_mod set_module_property NAME altera_epcq_controller_mod
set_module_property VERSION 17.1 set_module_property VERSION 19.1
set_module_property INTERNAL false set_module_property INTERNAL false
set_module_property OPAQUE_ADDRESS_MAP true set_module_property OPAQUE_ADDRESS_MAP true
set_module_property GROUP "Basic Functions/Configuration and Programming" set_module_property GROUP "Basic Functions/Configuration and Programming"

View File

@ -5,7 +5,7 @@ package require -exact sopc 9.1
# | # |
set_module_property NAME altera_jtag_avalon_master_mod 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 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 "17.1" set_module_property VERSION "19.1"
set_module_property GROUP "Basic Functions/Bridges and Adaptors/Memory Mapped" 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 DISPLAY_NAME "JTAG to Avalon Master Bridge (customized)"

View File

@ -1,5 +1,5 @@
// //
// Copyright (C) 2019 Markus Hiienkari <mhiienka@niksula.hut.fi> // Copyright (C) 2019-2020 Markus Hiienkari <mhiienka@niksula.hut.fi>
// //
// This file is part of Open Source Scan Converter project. // This file is part of Open Source Scan Converter project.
// //
@ -20,32 +20,42 @@
#ifndef OSD_GENERATOR_REGS_H_ #ifndef OSD_GENERATOR_REGS_H_
#define OSD_GENERATOR_REGS_H_ #define OSD_GENERATOR_REGS_H_
#include <alt_types.h> #define OSD_CHAR_ROWS 30
#define OSD_CHAR_COLS 16
#define OSD_CHAR_SECTIONS 2
#include <stdint.h>
typedef union { typedef union {
struct { struct {
alt_u8 enable:1; uint8_t enable:1;
alt_u8 status_refresh:1; uint8_t status_refresh:1;
alt_u8 menu_active:1; uint8_t menu_active:1;
alt_u8 status_timeout:2; uint8_t status_timeout:2;
alt_u8 x_offset:3; uint8_t x_offset:3;
alt_u8 y_offset:3; uint8_t y_offset:3;
alt_u8 x_size:2; uint8_t x_size:2;
alt_u8 y_size:2; uint8_t y_size:2;
alt_u32 osd_rsv:17; uint8_t border_color:2;
uint32_t osd_rsv:15;
} __attribute__((packed, __may_alias__)); } __attribute__((packed, __may_alias__));
alt_u32 data; uint32_t data;
} osd_config_reg; } osd_config_reg;
// char regs // char regs
typedef struct { typedef struct {
char row1[16]; char data[OSD_CHAR_ROWS][OSD_CHAR_SECTIONS][OSD_CHAR_COLS];
char row2[16]; } osd_char_array;
} osd_char_regs;
typedef struct { typedef struct {
uint32_t mask;
} osd_enable_color_reg;
typedef struct {
osd_char_array osd_array;
osd_config_reg osd_config; osd_config_reg osd_config;
osd_char_regs osd_chars; osd_enable_color_reg osd_sec_enable[OSD_CHAR_SECTIONS];
osd_enable_color_reg osd_row_color;
} __attribute__((packed, __may_alias__)) osd_regs; } __attribute__((packed, __may_alias__)) osd_regs;
#endif //OSD_GENERATOR_REGS_H_ #endif //OSD_GENERATOR_REGS_H_

View File

@ -23,11 +23,11 @@ set_module_property REPORT_HIERARCHY false
# #
# parameters # parameters
# #
add_parameter USE_MEMORY_BLOCKS INTEGER 1 #add_parameter USE_MEMORY_BLOCKS INTEGER 1
set_parameter_property USE_MEMORY_BLOCKS DISPLAY_NAME "Use memory blocks for character array" #set_parameter_property USE_MEMORY_BLOCKS DISPLAY_NAME "Use memory blocks for character array"
set_parameter_property USE_MEMORY_BLOCKS DISPLAY_HINT boolean #set_parameter_property USE_MEMORY_BLOCKS DISPLAY_HINT boolean
set_parameter_property USE_MEMORY_BLOCKS UNITS None #set_parameter_property USE_MEMORY_BLOCKS UNITS None
set_parameter_property USE_MEMORY_BLOCKS HDL_PARAMETER true #set_parameter_property USE_MEMORY_BLOCKS HDL_PARAMETER true
# #
# file sets # file sets
@ -109,7 +109,7 @@ set_interface_property avalon_s PORT_NAME_MAP ""
set_interface_property avalon_s CMSIS_SVD_VARIABLES "" set_interface_property avalon_s CMSIS_SVD_VARIABLES ""
set_interface_property avalon_s SVD_ADDRESS_GROUP "" set_interface_property avalon_s SVD_ADDRESS_GROUP ""
add_interface_port avalon_s avalon_s_address address Input 4 add_interface_port avalon_s avalon_s_address address Input 8
add_interface_port avalon_s avalon_s_writedata writedata Input 32 add_interface_port avalon_s avalon_s_writedata writedata Input 32
add_interface_port avalon_s avalon_s_readdata readdata Output 32 add_interface_port avalon_s avalon_s_readdata readdata Output 32
add_interface_port avalon_s avalon_s_byteenable byteenable Input 4 add_interface_port avalon_s avalon_s_byteenable byteenable Input 4
@ -156,4 +156,4 @@ add_interface_port osd_if vclk vclk Input 1
add_interface_port osd_if xpos xpos Input 11 add_interface_port osd_if xpos xpos Input 11
add_interface_port osd_if ypos ypos Input 11 add_interface_port osd_if ypos ypos Input 11
add_interface_port osd_if osd_enable osd_enable Output 1 add_interface_port osd_if osd_enable osd_enable Output 1
add_interface_port osd_if osd_color osd_color Output 1 add_interface_port osd_if osd_color osd_color Output 2

View File

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

View File

@ -1,5 +1,5 @@
// //
// Copyright (C) 2019 Markus Hiienkari <mhiienka@niksula.hut.fi> // Copyright (C) 2019-2020 Markus Hiienkari <mhiienka@niksula.hut.fi>
// //
// This file is part of Open Source Scan Converter project. // This file is part of Open Source Scan Converter project.
// //
@ -17,16 +17,14 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>. // along with this program. If not, see <http://www.gnu.org/licenses/>.
// //
module osd_generator_top #( module osd_generator_top (
parameter USE_MEMORY_BLOCKS = 0
) (
// common // common
input clk_i, input clk_i,
input rst_i, input rst_i,
// avalon slave // avalon slave
input [31:0] avalon_s_writedata, input [31:0] avalon_s_writedata,
output [31:0] avalon_s_readdata, output [31:0] avalon_s_readdata,
input [3:0] avalon_s_address, input [7:0] avalon_s_address,
input [3:0] avalon_s_byteenable, input [3:0] avalon_s_byteenable,
input avalon_s_write, input avalon_s_write,
input avalon_s_read, input avalon_s_read,
@ -37,21 +35,33 @@ module osd_generator_top #(
input [10:0] xpos, input [10:0] xpos,
input [10:0] ypos, input [10:0] ypos,
output reg osd_enable, output reg osd_enable,
output reg osd_color output reg [1:0] osd_color
); );
localparam CHAR_ROWS = 2; localparam CHAR_ROWS = 30;
localparam CHAR_COLS = 16; localparam CHAR_COLS = 16;
localparam CHAR_SECTIONS = 2;
localparam CHAR_SEC_SEPARATOR = 2;
localparam OSD_CONFIG_REGNUM = 4'h0; localparam BG_BLACK = 2'h0;
localparam BG_BLUE = 2'h1;
localparam BG_YELLOW = 2'h2;
localparam BG_WHITE = 2'h3;
localparam OSD_CONFIG_REGNUM = 8'hf0;
localparam OSD_ROW_LSEC_ENABLE_REGNUM = 8'hf1;
localparam OSD_ROW_RSEC_ENABLE_REGNUM = 8'hf2;
localparam OSD_ROW_COLOR_REGNUM = 8'hf3;
reg [31:0] osd_config; reg [31:0] osd_config;
reg [31:0] config_reg[OSD_ROW_LSEC_ENABLE_REGNUM:OSD_ROW_COLOR_REGNUM] /* synthesis ramstyle = "logic" */;
reg [10:0] xpos_osd_area_scaled, xpos_text_scaled; reg [10:0] xpos_osd_area_scaled, xpos_text_scaled;
reg [10:0] ypos_osd_area_scaled, ypos_text_scaled; reg [10:0] ypos_osd_area_scaled, ypos_text_scaled;
reg [7:0] x_ptr[2:5], y_ptr[2:5] /* synthesis ramstyle = "logic" */; reg [7:0] x_ptr[2:5], y_ptr[2:5] /* synthesis ramstyle = "logic" */;
reg osd_text_act_pp[2:5], osd_act_pp[3:5]; reg osd_text_act_pp[2:6], osd_act_pp[3:6];
reg [14:0] to_ctr, to_ctr_ms; reg [14:0] to_ctr, to_ctr_ms;
reg char_px;
wire render_enable = osd_config[0]; wire render_enable = osd_config[0];
wire status_refresh = osd_config[1]; wire status_refresh = osd_config[1];
@ -61,34 +71,28 @@ wire [2:0] x_offset = osd_config[7:5];
wire [2:0] y_offset = osd_config[10:8]; wire [2:0] y_offset = osd_config[10:8];
wire [1:0] x_size = osd_config[12:11]; wire [1:0] x_size = osd_config[12:11];
wire [1:0] y_size = osd_config[14:13]; wire [1:0] y_size = osd_config[14:13];
wire [1:0] border_color = osd_config[16:15];
wire [10:0] xpos_scaled_w = (xpos >> x_size)-({3'h0, x_offset} << 3); wire [10:0] xpos_scaled_w = (xpos >> x_size)-({3'h0, x_offset} << 3);
wire [10:0] ypos_scaled_w = (ypos >> y_size)-({3'h0, y_offset} << 3); wire [10:0] ypos_scaled_w = (ypos >> y_size)-({3'h0, y_offset} << 3);
wire [7:0] rom_rdaddr; wire [7:0] rom_rdaddr;
wire [0:7] char_data[7:0]; wire [0:7] char_data[7:0];
wire [4:0] char_idx = CHAR_COLS*(ypos_text_scaled >> 3) + (xpos_text_scaled >> 3); wire [4:0] char_row = (ypos_text_scaled >> 3);
wire [5:0] char_col = (xpos_text_scaled >> 3) - (((xpos_text_scaled >> 3) >= CHAR_COLS) ? CHAR_SEC_SEPARATOR : 0);
wire [9:0] char_idx = 32*char_row + char_col;
assign avalon_s_waitrequest_n = 1'b1; assign avalon_s_waitrequest_n = 1'b1;
generate char_array char_array_inst (
if (USE_MEMORY_BLOCKS == 1) begin .byteena_a(avalon_s_byteenable),
char_array char_array_inst ( .data(avalon_s_writedata),
.byteena_a(avalon_s_byteenable), .rdaddress(char_idx),
.data(avalon_s_writedata), .rdclock(vclk),
.rdaddress(char_idx), .wraddress(avalon_s_address),
.rdclock(vclk), .wrclock(clk_i),
.wraddress(avalon_s_address-1'b1), .wren(avalon_s_chipselect && avalon_s_write && (avalon_s_address < CHAR_ROWS*CHAR_COLS*CHAR_SECTIONS)),
.wrclock(clk_i), .q(rom_rdaddr)
.wren(avalon_s_chipselect && avalon_s_write && (avalon_s_address > 4'h0)), );
.q(rom_rdaddr)
);
end else begin
reg [7:0] char_ptr[CHAR_ROWS*CHAR_COLS-1:0], char_ptr_pp3[7:0] /* synthesis ramstyle = "logic" */;
reg [4:0] char_idx_pp[2:3];
assign rom_rdaddr = char_ptr_pp3[char_idx_pp[3][2:0]];
end
endgenerate
char_rom char_rom_inst ( char_rom char_rom_inst (
.clock(vclk), .clock(vclk),
@ -97,13 +101,13 @@ char_rom char_rom_inst (
); );
// Pipeline structure // Pipeline structure
// | 0 | 1 | 2 | 3 | 4 | 5 | // | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
// |----------|----------|---------|---------|---------|--------| // |----------|----------|---------|---------|---------|---------|--------|
// > POS_TEXT | POS_AREA | | | | | // > POS_TEXT | POS_AREA | | | | | |
// > | PTR | PTR | PTR | PTR | | // > | PTR | PTR | PTR | PTR | | |
// > | ENABLE | ENABLE | ENABLE | ENABLE | ENABLE | // > | ENABLE | ENABLE | ENABLE | ENABLE | ENABLE | ENABLE |
// > | INDEX | INDEX | | | | // > | INDEX | INDEX | | | | |
// > | | | CHARROM | CHARROM | COLOR | // > | | | CHARROM | CHARROM | CHAR_PX | COLOR |
integer idx, pp_idx; integer idx, pp_idx;
always @(posedge vclk) begin always @(posedge vclk) begin
xpos_text_scaled <= xpos_scaled_w; xpos_text_scaled <= xpos_scaled_w;
@ -119,32 +123,38 @@ always @(posedge vclk) begin
y_ptr[pp_idx] <= y_ptr[pp_idx-1]; y_ptr[pp_idx] <= y_ptr[pp_idx-1];
end end
osd_text_act_pp[2] <= render_enable & (menu_active || (to_ctr_ms > 0)) & ((xpos_text_scaled < 8*CHAR_COLS) && (ypos_text_scaled < 8*CHAR_ROWS)); osd_text_act_pp[2] <= render_enable &
for(pp_idx = 3; pp_idx <= 5; pp_idx = pp_idx+1) begin (menu_active || (to_ctr_ms > 0)) &
(((xpos_text_scaled < 8*CHAR_COLS) & config_reg[OSD_ROW_LSEC_ENABLE_REGNUM][ypos_text_scaled/8]) |
((xpos_text_scaled >= 8*(CHAR_COLS+CHAR_SEC_SEPARATOR)) & (xpos_text_scaled < 8*(2*CHAR_COLS+CHAR_SEC_SEPARATOR)) & config_reg[OSD_ROW_RSEC_ENABLE_REGNUM][ypos_text_scaled/8])) &
(ypos_text_scaled < 8*CHAR_ROWS);
for(pp_idx = 3; pp_idx <= 6; pp_idx = pp_idx+1) begin
osd_text_act_pp[pp_idx] <= osd_text_act_pp[pp_idx-1]; osd_text_act_pp[pp_idx] <= osd_text_act_pp[pp_idx-1];
end end
osd_act_pp[3] <= render_enable & (menu_active || (to_ctr_ms > 0)) & ((xpos_osd_area_scaled < 8*(CHAR_COLS+1)) && (ypos_osd_area_scaled < 8*(CHAR_ROWS+1))); osd_act_pp[3] <= render_enable &
for(pp_idx = 4; pp_idx <= 5; pp_idx = pp_idx+1) begin (menu_active || (to_ctr_ms > 0)) &
(((xpos_osd_area_scaled/8 < (CHAR_COLS+1)) & config_reg[OSD_ROW_LSEC_ENABLE_REGNUM][(ypos_osd_area_scaled/8) ? ((ypos_osd_area_scaled/8)-1) : 0]) |
((xpos_osd_area_scaled/8 >= (CHAR_COLS+1)) & (xpos_osd_area_scaled/8 < (2*CHAR_COLS+CHAR_SEC_SEPARATOR+1)) & (config_reg[OSD_ROW_RSEC_ENABLE_REGNUM][(ypos_osd_area_scaled/8)-1] | config_reg[OSD_ROW_RSEC_ENABLE_REGNUM][ypos_osd_area_scaled/8]))) &
(ypos_osd_area_scaled < 8*(CHAR_ROWS+1));
for(pp_idx = 4; pp_idx <= 6; pp_idx = pp_idx+1) begin
osd_act_pp[pp_idx] <= osd_act_pp[pp_idx-1]; osd_act_pp[pp_idx] <= osd_act_pp[pp_idx-1];
end end
osd_enable <= osd_act_pp[5]; char_px <= char_data[y_ptr[5]][x_ptr[5]];
osd_color = osd_text_act_pp[5] ? char_data[y_ptr[5]][x_ptr[5]] : 1'b0;
end
generate osd_enable <= osd_act_pp[6];
if (USE_MEMORY_BLOCKS == 0) begin
always @(posedge vclk) begin
char_idx_pp[2] <= char_idx;
char_idx_pp[3] <= char_idx_pp[2];
for(idx = 0; idx <= 7; idx = idx+1) begin if (osd_text_act_pp[6]) begin
char_ptr_pp3[idx] <= char_ptr[{char_idx_pp[2][4:3], 3'(idx)}]; if (char_px) begin
end osd_color <= config_reg[OSD_ROW_COLOR_REGNUM][char_row] ? BG_YELLOW : BG_WHITE;
end else begin
osd_color <= BG_BLUE;
end end
end else begin // border
osd_color <= border_color;
end end
endgenerate end
// OSD status timeout counters // OSD status timeout counters
always @(posedge clk_i) always @(posedge clk_i)
@ -188,39 +198,37 @@ always @(posedge clk_i or posedge rst_i) begin
end end
end end
genvar i; genvar i;
generate generate
if (USE_MEMORY_BLOCKS == 0) begin for (i=OSD_ROW_LSEC_ENABLE_REGNUM; i <= OSD_ROW_COLOR_REGNUM; i++) begin : gen_reg
for (i = 0; i < (CHAR_ROWS*CHAR_COLS); i = i + 4) begin : genreg always @(posedge clk_i or posedge rst_i) begin
always @(posedge clk_i or posedge rst_i) begin if (rst_i) begin
if (rst_i) begin config_reg[i] <= 0;
char_ptr[i] <= 0; end else begin
char_ptr[i+1] <= 0; if (avalon_s_chipselect && avalon_s_write && (avalon_s_address==i)) begin
char_ptr[i+2] <= 0; if (avalon_s_byteenable[3])
char_ptr[i+3] <= 0; config_reg[i][31:24] <= avalon_s_writedata[31:24];
end else begin if (avalon_s_byteenable[2])
if (avalon_s_chipselect && avalon_s_write && (avalon_s_address==1+(i/4))) begin config_reg[i][23:16] <= avalon_s_writedata[23:16];
if (avalon_s_byteenable[3]) if (avalon_s_byteenable[1])
char_ptr[i+3] <= avalon_s_writedata[31:24]; config_reg[i][15:8] <= avalon_s_writedata[15:8];
if (avalon_s_byteenable[2]) if (avalon_s_byteenable[0])
char_ptr[i+2] <= avalon_s_writedata[23:16]; config_reg[i][7:0] <= avalon_s_writedata[7:0];
if (avalon_s_byteenable[1])
char_ptr[i+1] <= avalon_s_writedata[15:8];
if (avalon_s_byteenable[0])
char_ptr[i] <= avalon_s_writedata[7:0];
end
end end
end end
end end
end end
endgenerate endgenerate
always @(*) begin always @(*) begin
if (avalon_s_chipselect && avalon_s_read) begin if (avalon_s_chipselect && avalon_s_read) begin
case (avalon_s_address) case (avalon_s_address)
OSD_CONFIG_REGNUM: avalon_s_readdata = osd_config; OSD_CONFIG_REGNUM: avalon_s_readdata = osd_config;
default: avalon_s_readdata = 32'h00000000; OSD_ROW_LSEC_ENABLE_REGNUM: avalon_s_readdata = config_reg[OSD_ROW_LSEC_ENABLE_REGNUM];
OSD_ROW_RSEC_ENABLE_REGNUM: avalon_s_readdata = config_reg[OSD_ROW_RSEC_ENABLE_REGNUM];
OSD_ROW_COLOR_REGNUM: avalon_s_readdata = config_reg[OSD_ROW_COLOR_REGNUM];
default: avalon_s_readdata = 32'h00000000;
endcase endcase
end else begin end else begin
avalon_s_readdata = 32'h00000000; avalon_s_readdata = 32'h00000000;

View File

@ -218,7 +218,7 @@ 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_la.stp
set_global_assignment -name FITTER_EFFORT "AUTO FIT" set_global_assignment -name FITTER_EFFORT "AUTO FIT"
set_global_assignment -name SEED 2 set_global_assignment -name SEED 6

View File

@ -104,7 +104,8 @@ reg remove_event_prev;
reg [14:0] to_ctr, to_ctr_ms; reg [14:0] to_ctr, to_ctr_ms;
wire lcd_bl_timeout; wire lcd_bl_timeout;
wire osd_color, osd_enable_pre; wire [1:0] osd_color;
wire osd_enable_pre;
wire osd_enable = osd_enable_pre & ~lt_active; wire osd_enable = osd_enable_pre & ~lt_active;
wire [10:0] xpos, xpos_sc, xpos_vg; wire [10:0] xpos, xpos_sc, xpos_vg;
wire [10:0] ypos, ypos_sc, ypos_vg; wire [10:0] ypos, ypos_sc, ypos_vg;
@ -189,9 +190,22 @@ assign ypos = enable_sc ? ypos_sc : ypos_vg;
assign HDMI_TX_PCLK = PCLK_out; assign HDMI_TX_PCLK = PCLK_out;
always @(posedge PCLK_out) begin always @(posedge PCLK_out) begin
HDMI_TX_RD <= osd_enable ? {8{osd_color}} : (enable_sc ? R_out_sc : R_out_vg); if (osd_enable) begin
HDMI_TX_GD <= osd_enable ? {8{osd_color}} : (enable_sc ? G_out_sc : G_out_vg); if (osd_color == 2'h0) begin
HDMI_TX_BD <= osd_enable ? 8'hff : (enable_sc ? B_out_sc : B_out_vg); {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_HS <= enable_sc ? HSYNC_out_sc : HSYNC_out_vg;
HDMI_TX_VS <= enable_sc ? VSYNC_out_sc : VSYNC_out_vg; HDMI_TX_VS <= enable_sc ? VSYNC_out_sc : VSYNC_out_vg;
HDMI_TX_DE <= enable_sc ? DE_out_sc : DE_out_vg; HDMI_TX_DE <= enable_sc ? DE_out_sc : DE_out_vg;

File diff suppressed because it is too large Load Diff

View File

@ -23,75 +23,23 @@
#include "flash.h" #include "flash.h"
#include "utils.h" #include "utils.h"
extern alt_epcq_controller_dev epcq_controller_0; // save some code space
#define SINGLE_FLASH_INSTANCE
alt_epcq_controller_dev *epcq_controller_dev; alt_flash_dev *epcq_dev;
int check_flash() int init_flash()
{ {
epcq_controller_dev = &epcq_controller_0; #ifdef SINGLE_FLASH_INSTANCE
extern alt_llist alt_flash_dev_list;
epcq_dev = (alt_flash_dev*)alt_flash_dev_list.next;
#else
epcq_dev = alt_flash_open_dev(EPCQ_CONTROLLER_0_AVL_MEM_NAME);
#endif
if ((epcq_controller_dev == NULL) || !(epcq_controller_dev->is_epcs && (epcq_controller_dev->page_size == PAGESIZE))) if (epcq_dev == NULL)
return -FLASH_DETECT_ERROR; return -1;
printf("Flash size in bytes: %lu\nSector size: %lu (%lu pages)\nPage size: %lu\n",
epcq_controller_dev->size_in_bytes, epcq_controller_dev->sector_size, epcq_controller_dev->sector_size/epcq_controller_dev->page_size, epcq_controller_dev->page_size);
return 0;
}
int read_flash(alt_u32 offset, alt_u32 length, alt_u8 *dstbuf)
{
int retval, i;
retval = alt_epcq_controller_read(&epcq_controller_dev->dev, offset, dstbuf, length);
if (retval != 0)
return -FLASH_READ_ERROR;
return 0;
}
int write_flash_page(alt_u8 *pagedata, alt_u32 length, alt_u32 pagenum)
{
int retval, i;
if ((pagenum % PAGES_PER_SECTOR) == 0) {
printf("Erasing sector %u\n", (unsigned)(pagenum/PAGES_PER_SECTOR));
retval = alt_epcq_controller_erase_block(&epcq_controller_dev->dev, pagenum*PAGESIZE);
if (retval != 0) {
printf("Flash erase error, sector %u\nRetval %d\n", (unsigned)(pagenum/PAGES_PER_SECTOR), retval);
return -FLASH_ERASE_ERROR;
}
}
retval = alt_epcq_controller_write_block(&epcq_controller_dev->dev, (pagenum/PAGES_PER_SECTOR)*PAGES_PER_SECTOR*PAGESIZE, pagenum*PAGESIZE, pagedata, length);
if (retval != 0) {
printf("Flash write error, page %u\nRetval %d\n", (unsigned)pagenum, retval);
return -FLASH_WRITE_ERROR;
}
return 0;
}
int write_flash(alt_u8 *buf, alt_u32 length, alt_u32 pagenum)
{
int retval;
alt_u32 bytes_to_w;
while (length > 0) {
bytes_to_w = (length > PAGESIZE) ? PAGESIZE : length;
retval = write_flash_page(buf, bytes_to_w, pagenum);
if (retval != 0)
return retval;
buf += bytes_to_w;
length -= bytes_to_w;
++pagenum;
}
return 0; return 0;
} }
@ -104,7 +52,8 @@ int verify_flash(alt_u32 offset, alt_u32 length, alt_u32 golden_crc, alt_u8 *tmp
for (i=0; i<length; i=i+PAGESIZE) { for (i=0; i<length; i=i+PAGESIZE) {
bytes_to_read = ((length-i < PAGESIZE) ? (length-i) : PAGESIZE); bytes_to_read = ((length-i < PAGESIZE) ? (length-i) : PAGESIZE);
retval = read_flash(i, bytes_to_read, tmpbuf); //retval = read_flash(i, bytes_to_read, tmpbuf);
retval = alt_epcq_controller_read(epcq_dev, offset+i, tmpbuf, bytes_to_read);
if (retval != 0) if (retval != 0)
return retval; return retval;

View File

@ -32,20 +32,10 @@
#define USERDATA_OFFSET 0x100000 #define USERDATA_OFFSET 0x100000
#define MAX_USERDATA_ENTRY 15 // 16 sectors for userdata #define MAX_USERDATA_ENTRY 15 // 16 sectors for userdata
#define FLASH_DETECT_ERROR 200
#define FLASH_READ_ERROR 201
#define FLASH_ERASE_ERROR 202
#define FLASH_WRITE_ERROR 203
#define FLASH_VERIFY_ERROR 204 #define FLASH_VERIFY_ERROR 204
int check_flash();
int read_flash(alt_u32 offset, alt_u32 length, alt_u8 *dstbuf);
int write_flash_page(alt_u8 *pagedata, alt_u32 length, alt_u32 pagenum);
int write_flash(alt_u8 *buf, alt_u32 length, alt_u32 pagenum);
int init_flash();
int verify_flash(alt_u32 offset, alt_u32 length, alt_u32 golden_crc, alt_u8 *tmpbuf); int verify_flash(alt_u32 offset, alt_u32 length, alt_u32 golden_crc, alt_u8 *tmpbuf);
#endif /* FLASH_H_ */ #endif /* FLASH_H_ */

View File

@ -22,7 +22,7 @@
#include "flash.h" #include "flash.h"
#include "lcd.h" #include "lcd.h"
extern char menu_row1[LCD_ROW_LEN+1], menu_row2[LCD_ROW_LEN+1]; extern alt_flash_dev *epcq_dev;
SD_DEV sdcard_dev; SD_DEV sdcard_dev;
@ -32,26 +32,33 @@ int check_sdcard(alt_u8 *databuf)
res = SD_Init(&sdcard_dev); res = SD_Init(&sdcard_dev);
printf("SD det status: %u\n", res); printf("SD det status: %u\n", res);
if (res != SD_OK) if (res == SD_OK)
return res; res = SD_Read(&sdcard_dev, databuf, 0, 0, 512);
return SD_Read(&sdcard_dev, databuf, 0, 0, 512); return -res;
} }
int copy_sd_to_flash(alt_u32 sd_blknum, alt_u32 flash_pagenum, alt_u32 length, alt_u8 *tmpbuf) int copy_sd_to_flash(alt_u32 sd_blknum, alt_u32 flash_pagenum, alt_u32 length, alt_u8 *tmpbuf)
{ {
SDRESULTS res;
int retval; int retval;
alt_u32 bytes_to_rw; alt_u32 bytes_to_rw;
while (length > 0) { while (length > 0) {
bytes_to_rw = (length < SD_BLK_SIZE) ? length : SD_BLK_SIZE; bytes_to_rw = (length < SD_BLK_SIZE) ? length : SD_BLK_SIZE;
retval = SD_Read(&sdcard_dev, tmpbuf, sd_blknum, 0, bytes_to_rw); res = SD_Read(&sdcard_dev, tmpbuf, sd_blknum, 0, bytes_to_rw);
if (retval != 0) { if (res != SD_OK) {
printf("Failed to read SD card\n"); printf("Failed to read SD card\n");
return -retval; return -res;
} }
retval = write_flash(tmpbuf, bytes_to_rw, flash_pagenum); if ((flash_pagenum % PAGES_PER_SECTOR) == 0) {
retval = alt_epcq_controller_erase_block(epcq_dev, flash_pagenum*PAGESIZE);
if (retval != 0)
return retval;
}
retval = alt_epcq_controller_write_block(epcq_dev, ((flash_pagenum/PAGES_PER_SECTOR)*SECTORSIZE), flash_pagenum*PAGESIZE, tmpbuf, bytes_to_rw);
if (retval != 0) if (retval != 0)
return retval; return retval;

View File

@ -106,17 +106,38 @@ volatile sc_regs *sc = (volatile sc_regs*)SC_CONFIG_0_BASE;
volatile osd_regs *osd = (volatile osd_regs*)OSD_GENERATOR_0_BASE; volatile osd_regs *osd = (volatile osd_regs*)OSD_GENERATOR_0_BASE;
volatile pll_reconfig_regs *pll_reconfig = (volatile pll_reconfig_regs*)PLL_RECONFIG_0_BASE; volatile pll_reconfig_regs *pll_reconfig = (volatile pll_reconfig_regs*)PLL_RECONFIG_0_BASE;
inline void lcd_write_menu() void ui_disp_menu(alt_u8 osd_mode)
{ {
strncpy((char*)osd->osd_chars.row1, menu_row1, LCD_ROW_LEN); alt_u8 menu_page;
strncpy((char*)osd->osd_chars.row2, menu_row2, LCD_ROW_LEN);
if ((osd_mode == 1) || (osd_enable == 2)) {
strncpy((char*)osd->osd_array.data[0][0], menu_row1, OSD_CHAR_COLS);
strncpy((char*)osd->osd_array.data[1][0], menu_row2, OSD_CHAR_COLS);
osd->osd_row_color.mask = 0;
osd->osd_sec_enable[0].mask = 3;
osd->osd_sec_enable[1].mask = 0;
} else if (osd_mode == 2) {
menu_page = get_current_menunavi()->mp;
strncpy((char*)osd->osd_array.data[menu_page][1], menu_row2, OSD_CHAR_COLS);
osd->osd_sec_enable[1].mask |= (1<<menu_page);
}
lcd_write((char*)&menu_row1, (char*)&menu_row2); lcd_write((char*)&menu_row1, (char*)&menu_row2);
} }
inline void lcd_write_status() { void ui_disp_status(alt_u8 refresh_osd_timer) {
strncpy((char*)osd->osd_chars.row1, row1, LCD_ROW_LEN); if (!menu_active) {
strncpy((char*)osd->osd_chars.row2, row2, LCD_ROW_LEN); if (refresh_osd_timer)
lcd_write((char*)&row1, (char*)&row2); osd->osd_config.status_refresh = 1;
strncpy((char*)osd->osd_array.data[0][0], row1, OSD_CHAR_COLS);
strncpy((char*)osd->osd_array.data[1][0], row2, OSD_CHAR_COLS);
osd->osd_row_color.mask = 0;
osd->osd_sec_enable[0].mask = 3;
osd->osd_sec_enable[1].mask = 0;
lcd_write((char*)&row1, (char*)&row2);
}
} }
#ifdef ENABLE_AUDIO #ifdef ENABLE_AUDIO
@ -651,10 +672,7 @@ void program_mode()
sniprintf(row1, LCD_ROW_LEN+1, "%s %u-%c", avinput_str[cm.avinput], (unsigned)cm.totlines, cm.progressive ? 'p' : 'i'); 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)(v_hz_x100/100), (unsigned)(v_hz_x100%100));
if (!menu_active) { ui_disp_status(1);
osd->osd_config.status_refresh = 1;
lcd_write_status();
}
//printf ("Get mode id with %u %u %f\n", totlines, progressive, hz); //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); cm.id = get_mode_id(cm.totlines, cm.progressive, v_hz_x100/100, h_syncinlen);
@ -842,8 +860,8 @@ int init_hw()
} }
#endif #endif
if (check_flash() != 0) { if (init_flash() != 0) {
printf("Error: incorrect flash type detected\n"); printf("Error: could not find flash\n");
return -1; return -1;
} }
@ -863,17 +881,18 @@ int init_hw()
osd->osd_config.y_size = 0; osd->osd_config.y_size = 0;
osd->osd_config.x_offset = 3; osd->osd_config.x_offset = 3;
osd->osd_config.y_offset = 3; osd->osd_config.y_offset = 3;
osd->osd_config.enable = osd_enable; osd->osd_config.enable = !!osd_enable;
osd->osd_config.status_timeout = osd_status_timeout; osd->osd_config.status_timeout = osd_status_timeout;
osd->osd_config.border_color = 1;
// Setup remote keymap
if (!(IORD_ALTERA_AVALON_PIO_DATA(PIO_1_BASE) & PB1_BIT))
setup_rc();
// init always in HDMI mode (fixes yellow screen bug) // init always in HDMI mode (fixes yellow screen bug)
cm.hdmitx_vic = HDMI_480p60; cm.hdmitx_vic = HDMI_480p60;
TX_enable(TX_HDMI_RGB); TX_enable(TX_HDMI_RGB);
// Setup remote keymap
if (!(IORD_ALTERA_AVALON_PIO_DATA(PIO_1_BASE) & PB1_BIT))
setup_rc();
return 0; return 0;
} }
@ -886,7 +905,7 @@ int latency_test() {
sys_ctrl |= LT_ACTIVE|(position<<LT_MODE_OFFS); sys_ctrl |= LT_ACTIVE|(position<<LT_MODE_OFFS);
IOWR_ALTERA_AVALON_PIO_DATA(PIO_0_BASE, sys_ctrl); IOWR_ALTERA_AVALON_PIO_DATA(PIO_0_BASE, sys_ctrl);
sniprintf(menu_row2, LCD_ROW_LEN+1, "OK to init"); sniprintf(menu_row2, LCD_ROW_LEN+1, "OK to init");
lcd_write_menu(); ui_disp_menu(0);
while (1) { while (1) {
btn_vec = IORD_ALTERA_AVALON_PIO_DATA(PIO_1_BASE) & RC_MASK; btn_vec = IORD_ALTERA_AVALON_PIO_DATA(PIO_1_BASE) & RC_MASK;
@ -896,7 +915,7 @@ int latency_test() {
sys_ctrl &= ~(3<<LT_MODE_OFFS); sys_ctrl &= ~(3<<LT_MODE_OFFS);
IOWR_ALTERA_AVALON_PIO_DATA(PIO_0_BASE, sys_ctrl); IOWR_ALTERA_AVALON_PIO_DATA(PIO_0_BASE, sys_ctrl);
menu_row2[0] = 0; menu_row2[0] = 0;
lcd_write_menu(); ui_disp_menu(0);
usleep(400000); usleep(400000);
sys_ctrl |= LT_ARMED|(position<<LT_MODE_OFFS); sys_ctrl |= LT_ARMED|(position<<LT_MODE_OFFS);
IOWR_ALTERA_AVALON_PIO_DATA(PIO_0_BASE, sys_ctrl); IOWR_ALTERA_AVALON_PIO_DATA(PIO_0_BASE, sys_ctrl);
@ -919,7 +938,7 @@ int latency_test() {
sniprintf(menu_row2, LCD_ROW_LEN+1, "%u.%.2ums", latency_ms_x100/100, latency_ms_x100%100); sniprintf(menu_row2, LCD_ROW_LEN+1, "%u.%.2ums", latency_ms_x100/100, latency_ms_x100%100);
else else
sniprintf(menu_row2, LCD_ROW_LEN+1, "%u.%.2ums/%u.%.2ums", latency_ms_x100/100, latency_ms_x100%100, stb_ms_x100/100, stb_ms_x100%100); sniprintf(menu_row2, LCD_ROW_LEN+1, "%u.%.2ums/%u.%.2ums", latency_ms_x100/100, latency_ms_x100%100, stb_ms_x100/100, stb_ms_x100%100);
lcd_write_menu(); ui_disp_menu(0);
} else if (btn_vec == rc_keymap[RC_BACK]) { } else if (btn_vec == rc_keymap[RC_BACK]) {
break; break;
} }
@ -978,14 +997,12 @@ int main()
#else #else
strncpy(row2, "** DEBUG BUILD *", LCD_ROW_LEN+1); strncpy(row2, "** DEBUG BUILD *", LCD_ROW_LEN+1);
#endif #endif
osd->osd_config.status_refresh = 1; ui_disp_status(1);
lcd_write_status();
usleep(500000); usleep(500000);
} else { } else {
sniprintf(row1, LCD_ROW_LEN+1, "Init error %d", init_stat); sniprintf(row1, LCD_ROW_LEN+1, "Init error %d", init_stat);
strncpy(row2, "", LCD_ROW_LEN+1); strncpy(row2, "", LCD_ROW_LEN+1);
osd->osd_config.status_refresh = 1; ui_disp_status(1);
lcd_write_status();
while (1) {} while (1) {}
} }
@ -1146,10 +1163,7 @@ int main()
cm.clkcnt = 0; //TODO: proper invalidate cm.clkcnt = 0; //TODO: proper invalidate
strncpy(row1, avinput_str[cm.avinput], LCD_ROW_LEN+1); strncpy(row1, avinput_str[cm.avinput], LCD_ROW_LEN+1);
strncpy(row2, " NO SYNC", LCD_ROW_LEN+1); strncpy(row2, " NO SYNC", LCD_ROW_LEN+1);
if (!menu_active) { ui_disp_status(1);
osd->osd_config.status_refresh = 1;
lcd_write_status();
}
if (man_input_change) { if (man_input_change) {
// record last input if it was selected manually // record last input if it was selected manually
if (def_input == AV_LAST) if (def_input == AV_LAST)
@ -1180,8 +1194,13 @@ int main()
if ((osd_enable != osd_enable_pre) || (osd_status_timeout != osd_status_timeout_pre)) { if ((osd_enable != osd_enable_pre) || (osd_status_timeout != osd_status_timeout_pre)) {
osd_enable = osd_enable_pre; osd_enable = osd_enable_pre;
osd_status_timeout = osd_status_timeout_pre; osd_status_timeout = osd_status_timeout_pre;
osd->osd_config.enable = osd_enable; osd->osd_config.enable = !!osd_enable;
osd->osd_config.status_timeout = osd_status_timeout; osd->osd_config.status_timeout = osd_status_timeout;
if (menu_active) {
remote_code = 0;
render_osd_page();
display_menu(1);
}
} }
if (cm.avinput != AV_TESTPAT) { if (cm.avinput != AV_TESTPAT) {
@ -1201,10 +1220,7 @@ int main()
//ths_source_sel(THS_STANDBY, 0); //ths_source_sel(THS_STANDBY, 0);
strncpy(row1, avinput_str[cm.avinput], LCD_ROW_LEN+1); strncpy(row1, avinput_str[cm.avinput], LCD_ROW_LEN+1);
strncpy(row2, " NO SYNC", LCD_ROW_LEN+1); strncpy(row2, " NO SYNC", LCD_ROW_LEN+1);
if (!menu_active) { ui_disp_status(1);
osd->osd_config.status_refresh = 1;
lcd_write_status();
}
alt_timestamp_start();// reset auto input timer alt_timestamp_start();// reset auto input timer
auto_input_ctr = 0; auto_input_ctr = 0;
auto_input_current_ctr = 0; auto_input_current_ctr = 0;

View File

@ -115,8 +115,8 @@ typedef struct {
avconfig_t cc; avconfig_t cc;
} avmode_t; } avmode_t;
inline void lcd_write_menu(); void ui_disp_menu(alt_u8 osd_mode);
inline void lcd_write_status(); void ui_disp_status(alt_u8 refresh_osd_timer);
int load_profile(); int load_profile();
int save_profile(); int save_profile();

View File

@ -25,6 +25,7 @@
#include "av_controller.h" #include "av_controller.h"
#include "video_modes.h" #include "video_modes.h"
#include "userdata.h" #include "userdata.h"
#include "firmware.h"
#include "lcd.h" #include "lcd.h"
#include "altera_avalon_pio_regs.h" #include "altera_avalon_pio_regs.h"
@ -50,6 +51,8 @@ extern alt_u8 update_cur_vm, vm_edit;
extern volatile sc_regs *sc; extern volatile sc_regs *sc;
extern volatile osd_regs *osd; extern volatile osd_regs *osd;
extern menu_t menu_scanlines, menu_advtiming;
alt_u32 remote_code; alt_u32 remote_code;
alt_u8 remote_rpt, remote_rpt_prev; alt_u8 remote_rpt, remote_rpt_prev;
alt_u32 btn_code, btn_code_prev; alt_u32 btn_code, btn_code_prev;
@ -62,7 +65,8 @@ void setup_rc()
for (i=0; i<REMOTE_MAX_KEYS; i++) { for (i=0; i<REMOTE_MAX_KEYS; i++) {
strncpy(menu_row1, "Press", LCD_ROW_LEN+1); strncpy(menu_row1, "Press", LCD_ROW_LEN+1);
strncpy(menu_row2, rc_keydesc[i], LCD_ROW_LEN+1); strncpy(menu_row2, rc_keydesc[i], LCD_ROW_LEN+1);
lcd_write_menu(); osd->osd_config.menu_active = 1;
ui_disp_menu(1);
confirm = 0; confirm = 0;
while (1) { while (1) {
@ -73,14 +77,14 @@ void setup_rc()
if (confirm == 0) { if (confirm == 0) {
rc_keymap[i] = remote_code; rc_keymap[i] = remote_code;
strncpy(menu_row1, "Confirm", LCD_ROW_LEN+1); strncpy(menu_row1, "Confirm", LCD_ROW_LEN+1);
lcd_write_menu(); ui_disp_menu(1);
confirm = 1; confirm = 1;
} else { } else {
if (remote_code == rc_keymap[i]) { if (remote_code == rc_keymap[i]) {
confirm = 2; confirm = 2;
} else { } else {
strncpy(menu_row1, "Mismatch, retry", LCD_ROW_LEN+1); strncpy(menu_row1, "Mismatch, retry", LCD_ROW_LEN+1);
lcd_write_menu(); ui_disp_menu(1);
confirm = 0; confirm = 0;
} }
} }
@ -106,6 +110,8 @@ void setup_rc()
} }
} }
write_userdata(INIT_CONFIG_SLOT); write_userdata(INIT_CONFIG_SLOT);
osd->osd_config.menu_active = 0;
} }
int parse_control() int parse_control()
@ -153,43 +159,96 @@ int parse_control()
osd->osd_config.menu_active = menu_active; osd->osd_config.menu_active = menu_active;
profile_sel_menu = profile_sel; profile_sel_menu = profile_sel;
if (menu_active) if (menu_active) {
render_osd_page();
display_menu(1); display_menu(1);
else } else {
lcd_write_status(); ui_disp_status(0);
}
break; break;
case RC_INFO: case RC_INFO:
sc_status = sc->sc_status; sc_status = sc->sc_status;
sc_status2 = sc->sc_status2; sc_status2 = sc->sc_status2;
sniprintf(menu_row1, LCD_ROW_LEN+1, "Prof.%u %9s", profile_sel, video_modes[cm.id].name); fpga_v_hz_x100 = (100*TVP_EXTCLK_HZ)/sc_status2.pcnt_frame;
if (cm.sync_active) {
//fpga_v_hz_x100 = (100*TVP_EXTCLK_HZ)/IORD_ALTERA_AVALON_PIO_DATA(PIO_8_BASE); if (!menu_active) {
/*sniprintf(menu_row2, LCD_ROW_LEN+1, "%4lu%c%c %3lu.%.2luHz", (((fpga_status & 0x7ff)+1)<<fpga_ilace)+fpga_ilace, memset((void*)osd->osd_array.data, 0, sizeof(osd_char_array));
fpga_ilace ? 'i' : 'p', sniprintf((char*)osd->osd_array.data[0][0], OSD_CHAR_COLS, "Profile:");
((fpga_status >> 16) & 0x3) ? '*' : ' ', sniprintf((char*)osd->osd_array.data[0][1], OSD_CHAR_COLS, "%u", profile_sel);
fpga_v_hz_x100/100, if (cm.sync_active) {
fpga_v_hz_x100%100);*/ sniprintf((char*)osd->osd_array.data[1][0], OSD_CHAR_COLS, "Mode preset:");
sniprintf(menu_row2, LCD_ROW_LEN+1, "%4lu-%c%c %lu", (unsigned long)((sc_status.vmax+1)<<sc_status.interlace_flag)+sc_status.interlace_flag, sniprintf((char*)osd->osd_array.data[1][1], OSD_CHAR_COLS, "%s", video_modes[cm.id].name);
sc_status.interlace_flag ? 'i' : 'p', sniprintf((char*)osd->osd_array.data[2][0], OSD_CHAR_COLS, "Imode (FPGA):");
sc_status.fpga_vsyncgen ? '*' : ' ', 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,
(unsigned long)sc_status2.pcnt_frame); 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;
} }
osd->osd_config.menu_active = 1;
lcd_write_menu();
break; break;
case RC_LCDBL: case RC_LCDBL:
sys_ctrl ^= LCD_BL; sys_ctrl ^= LCD_BL;
break; break;
case RC_SL_MODE: tc.sl_mode = (tc.sl_mode < SL_MODE_MAX) ? (tc.sl_mode + 1) : 0; break; case RC_SL_MODE:
case RC_SL_TYPE: tc.sl_type = (tc.sl_type < SL_TYPE_MAX) ? (tc.sl_type + 1) : 0; break; tc.sl_mode = (tc.sl_mode < SL_MODE_MAX) ? (tc.sl_mode + 1) : 0;
case RC_SL_MINUS: tc.sl_str = tc.sl_str ? (tc.sl_str - 1) : 0; break; if (!menu_active) {
case RC_SL_PLUS: tc.sl_str = (tc.sl_str < SCANLINESTR_MAX) ? (tc.sl_str + 1) : SCANLINESTR_MAX; break; strncpy((char*)osd->osd_array.data[0][0], menu_scanlines.items[0].name, OSD_CHAR_COLS);
strncpy((char*)osd->osd_array.data[1][0], menu_scanlines.items[0].sel.setting_str[tc.sl_mode], 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_scanlines) {
render_osd_page();
}
break;
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);
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_scanlines) {
render_osd_page();
}
break;
case RC_SL_MINUS:
case RC_SL_PLUS:
if (i == RC_SL_MINUS)
tc.sl_str = tc.sl_str ? (tc.sl_str - 1) : 0;
else
tc.sl_str = (tc.sl_str < SCANLINESTR_MAX) ? (tc.sl_str + 1) : SCANLINESTR_MAX;
if (!menu_active) {
strncpy((char*)osd->osd_array.data[0][0], menu_scanlines.items[1].name, OSD_CHAR_COLS);
menu_scanlines.items[1].num.df(tc.sl_str);
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_scanlines) {
render_osd_page();
}
break;
case RC_LM_MODE: case RC_LM_MODE:
strncpy(menu_row1, "Linemult mode:", LCD_ROW_LEN+1); strncpy(menu_row1, "Linemult mode:", LCD_ROW_LEN+1);
strncpy(menu_row2, "press 1-5", LCD_ROW_LEN+1); strncpy(menu_row2, "press 1-5", LCD_ROW_LEN+1);
osd->osd_config.menu_active = 1; osd->osd_config.menu_active = 1;
lcd_write_menu(); ui_disp_menu(1);
while (1) { while (1) {
btn_vec = IORD_ALTERA_AVALON_PIO_DATA(PIO_1_BASE) & RC_MASK; btn_vec = IORD_ALTERA_AVALON_PIO_DATA(PIO_1_BASE) & RC_MASK;
@ -208,7 +267,7 @@ int parse_control()
*pmcfg_ptr[video_modes[cm.id].group] = i; *pmcfg_ptr[video_modes[cm.id].group] = i;
} else { } else {
sniprintf(menu_row2, LCD_ROW_LEN+1, "%ux unsupported", i+1); sniprintf(menu_row2, LCD_ROW_LEN+1, "%ux unsupported", i+1);
lcd_write_menu(); ui_disp_menu(1);
usleep(500000); usleep(500000);
} }
break; break;
@ -218,27 +277,39 @@ int parse_control()
usleep(WAITLOOP_SLEEP_US); usleep(WAITLOOP_SLEEP_US);
} }
osd->osd_config.menu_active = 0;
lcd_write_status();
menu_active = 0; menu_active = 0;
osd->osd_config.menu_active = 0;
ui_disp_status(0);
break; break;
case RC_PHASE_MINUS:
case RC_PHASE_PLUS: case RC_PHASE_PLUS:
video_modes[cm.id].sampler_phase = (video_modes[cm.id].sampler_phase < SAMPLER_PHASE_MAX) ? (video_modes[cm.id].sampler_phase + 1) : 0; if (i == RC_PHASE_MINUS)
update_cur_vm = 1; video_modes[cm.id].sampler_phase = video_modes[cm.id].sampler_phase ? (video_modes[cm.id].sampler_phase - 1) : SAMPLER_PHASE_MAX;
if (cm.id == vm_edit) else
tc_sampler_phase = video_modes[vm_edit].sampler_phase; video_modes[cm.id].sampler_phase = (video_modes[cm.id].sampler_phase < SAMPLER_PHASE_MAX) ? (video_modes[cm.id].sampler_phase + 1) : 0;
break;
case 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;
update_cur_vm = 1; update_cur_vm = 1;
if (cm.id == vm_edit) if (cm.id == vm_edit)
tc_sampler_phase = video_modes[vm_edit].sampler_phase; tc_sampler_phase = video_modes[vm_edit].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();
}
break; break;
case RC_PROF_HOTKEY: case RC_PROF_HOTKEY:
Prof_Hotkey_Prompt: Prof_Hotkey_Prompt:
strncpy(menu_row1, "Profile load:", LCD_ROW_LEN+1); strncpy(menu_row1, "Profile load:", LCD_ROW_LEN+1);
sniprintf(menu_row2, LCD_ROW_LEN+1, "press %u-%u", prof_x10*10, ((prof_x10*10+9) > MAX_PROFILE) ? MAX_PROFILE : (prof_x10*10+9)); sniprintf(menu_row2, LCD_ROW_LEN+1, "press %u-%u", prof_x10*10, ((prof_x10*10+9) > MAX_PROFILE) ? MAX_PROFILE : (prof_x10*10+9));
osd->osd_config.menu_active = 1; osd->osd_config.menu_active = 1;
lcd_write_menu(); ui_disp_menu(1);
while (1) { while (1) {
btn_vec = IORD_ALTERA_AVALON_PIO_DATA(PIO_1_BASE) & RC_MASK; btn_vec = IORD_ALTERA_AVALON_PIO_DATA(PIO_1_BASE) & RC_MASK;
@ -253,7 +324,7 @@ Prof_Hotkey_Prompt:
profile_sel_menu = prof_x10*10 + ((i+1)%10); profile_sel_menu = prof_x10*10 + ((i+1)%10);
retval = load_profile(); retval = load_profile();
sniprintf(menu_row2, LCD_ROW_LEN+1, "%s", (retval==0) ? "Done" : "Failed"); sniprintf(menu_row2, LCD_ROW_LEN+1, "%s", (retval==0) ? "Done" : "Failed");
lcd_write_menu(); ui_disp_menu(1);
usleep(500000); usleep(500000);
break; break;
} else if (i == RC_PROF_HOTKEY) { } else if (i == RC_PROF_HOTKEY) {
@ -269,9 +340,9 @@ Prof_Hotkey_Prompt:
usleep(WAITLOOP_SLEEP_US); usleep(WAITLOOP_SLEEP_US);
} }
osd->osd_config.menu_active = 0;
lcd_write_status();
menu_active = 0; menu_active = 0;
osd->osd_config.menu_active = 0;
ui_disp_status(0);
break; break;
case RC_RIGHT: case RC_RIGHT:
if (!menu_active) if (!menu_active)

View File

@ -27,6 +27,7 @@
#include "av_controller.h" #include "av_controller.h"
#include "lcd.h" #include "lcd.h"
#include "utils.h" #include "utils.h"
#include "menu.h"
#include "altera_avalon_pio_regs.h" #include "altera_avalon_pio_regs.h"
extern char menu_row1[LCD_ROW_LEN+1], menu_row2[LCD_ROW_LEN+1]; extern char menu_row1[LCD_ROW_LEN+1], menu_row2[LCD_ROW_LEN+1];
@ -71,15 +72,14 @@ static int check_fw_header(alt_u8 *databuf, fw_hdr *hdr)
static int check_fw_image(alt_u32 offset, alt_u32 size, alt_u32 golden_crc, alt_u8 *tmpbuf) static int check_fw_image(alt_u32 offset, alt_u32 size, alt_u32 golden_crc, alt_u8 *tmpbuf)
{ {
alt_u32 crcval=0, i, bytes_to_read; alt_u32 crcval=0, i, bytes_to_read;
int retval; SDRESULTS res;
for (i=0; i<size; i=i+SD_BLK_SIZE) { for (i=0; i<size; i=i+SD_BLK_SIZE) {
bytes_to_read = ((size-i < SD_BLK_SIZE) ? (size-i) : SD_BLK_SIZE); bytes_to_read = ((size-i < SD_BLK_SIZE) ? (size-i) : SD_BLK_SIZE);
retval = SD_Read(&sdcard_dev, tmpbuf, (offset+i)/SD_BLK_SIZE, 0, bytes_to_read); res = SD_Read(&sdcard_dev, tmpbuf, (offset+i)/SD_BLK_SIZE, 0, bytes_to_read);
//retval = read_sd_block(offset+i, bytes_to_read, tmpbuf);
if (retval != SD_OK) if (res != SD_OK)
return retval; return -res;
crcval = crc32(tmpbuf, bytes_to_read, (i==0)); crcval = crc32(tmpbuf, bytes_to_read, (i==0));
} }
@ -106,14 +106,16 @@ int fw_update()
asm volatile("mov %0, sp" : "=r"(sp)); asm volatile("mov %0, sp" : "=r"(sp));
sniprintf(menu_row1, LCD_ROW_LEN+1, "Stack size:"); sniprintf(menu_row1, LCD_ROW_LEN+1, "Stack size:");
sniprintf(menu_row2, LCD_ROW_LEN+1, "%lu bytes", (ONCHIP_MEMORY2_0_BASE+ONCHIP_MEMORY2_0_SIZE_VALUE)-sp); sniprintf(menu_row2, LCD_ROW_LEN+1, "%lu bytes", (ONCHIP_MEMORY2_0_BASE+ONCHIP_MEMORY2_0_SIZE_VALUE)-sp);
lcd_write_menu(); ui_disp_menu(1);
usleep(1000000); usleep(1000000);
#endif #endif
retval = check_sdcard(databuf); retval = check_sdcard(databuf);
SPI_CS_High(); SPI_CS_High();
if (retval != 0) if (retval != 0) {
retval = -retval;
goto failure; goto failure;
}
retval = check_fw_header(databuf, &fw_header); retval = check_fw_header(databuf, &fw_header);
if (retval != 0) if (retval != 0)
@ -121,14 +123,14 @@ int fw_update()
sniprintf(menu_row1, LCD_ROW_LEN+1, "Validating data"); sniprintf(menu_row1, LCD_ROW_LEN+1, "Validating data");
sniprintf(menu_row2, LCD_ROW_LEN+1, "%u bytes", (unsigned)fw_header.data_len); sniprintf(menu_row2, LCD_ROW_LEN+1, "%u bytes", (unsigned)fw_header.data_len);
lcd_write_menu(); ui_disp_menu(1);
retval = check_fw_image(512, fw_header.data_len, fw_header.data_crc, databuf); retval = check_fw_image(512, fw_header.data_len, fw_header.data_crc, databuf);
if (retval != 0) if (retval != 0)
goto failure; goto failure;
sniprintf(menu_row1, LCD_ROW_LEN+1, "%u.%.2u%s%s", fw_header.version_major, fw_header.version_minor, (fw_header.version_suffix[0] == 0) ? "" : "-", fw_header.version_suffix); sniprintf(menu_row1, LCD_ROW_LEN+1, "%u.%.2u%s%s", fw_header.version_major, fw_header.version_minor, (fw_header.version_suffix[0] == 0) ? "" : "-", fw_header.version_suffix);
strncpy(menu_row2, "Update? 1=Y, 2=N", LCD_ROW_LEN+1); strncpy(menu_row2, "Update? 1=Y, 2=N", LCD_ROW_LEN+1);
lcd_write_menu(); ui_disp_menu(1);
while (1) { while (1) {
btn_vec = IORD_ALTERA_AVALON_PIO_DATA(PIO_1_BASE) & RC_MASK; btn_vec = IORD_ALTERA_AVALON_PIO_DATA(PIO_1_BASE) & RC_MASK;
@ -152,7 +154,7 @@ int fw_update()
strncpy(menu_row1, "Updating FW", LCD_ROW_LEN+1); strncpy(menu_row1, "Updating FW", LCD_ROW_LEN+1);
update_init: update_init:
strncpy(menu_row2, "please wait...", LCD_ROW_LEN+1); strncpy(menu_row2, "please wait...", LCD_ROW_LEN+1);
lcd_write_menu(); ui_disp_menu(1);
retval = copy_sd_to_flash(512/SD_BLK_SIZE, 0, fw_header.data_len, databuf); retval = copy_sd_to_flash(512/SD_BLK_SIZE, 0, fw_header.data_len, databuf);
if (retval != 0) if (retval != 0)
@ -160,7 +162,7 @@ update_init:
strncpy(menu_row1, "Verifying flash", LCD_ROW_LEN+1); strncpy(menu_row1, "Verifying flash", LCD_ROW_LEN+1);
strncpy(menu_row2, "please wait...", LCD_ROW_LEN+1); strncpy(menu_row2, "please wait...", LCD_ROW_LEN+1);
lcd_write_menu(); ui_disp_menu(1);
retval = verify_flash(0, fw_header.data_len, fw_header.data_crc, databuf); retval = verify_flash(0, fw_header.data_len, fw_header.data_crc, databuf);
if (retval != 0) if (retval != 0)
goto failure; goto failure;
@ -169,7 +171,7 @@ update_init:
strncpy(menu_row1, "Firmware updated", LCD_ROW_LEN+1); strncpy(menu_row1, "Firmware updated", LCD_ROW_LEN+1);
strncpy(menu_row2, "please restart", LCD_ROW_LEN+1); strncpy(menu_row2, "please restart", LCD_ROW_LEN+1);
lcd_write_menu(); ui_disp_menu(1);
while (1) {} while (1) {}
return 0; return 0;
@ -196,24 +198,15 @@ failure:
case FW_UPD_CANCELLED: case FW_UPD_CANCELLED:
errmsg = "Update cancelled"; errmsg = "Update cancelled";
break; break;
case -FLASH_READ_ERROR:
errmsg = "Flash read err";
break;
case -FLASH_ERASE_ERROR:
errmsg = "Flash erase err";
break;
case -FLASH_WRITE_ERROR:
errmsg = "Flash write err";
break;
case -FLASH_VERIFY_ERROR: case -FLASH_VERIFY_ERROR:
errmsg = "Flash verif fail"; errmsg = "Flash verif fail";
break; break;
default: default:
errmsg = "Error"; errmsg = "SD/Flash error";
break; break;
} }
strncpy(menu_row2, errmsg, LCD_ROW_LEN+1); strncpy(menu_row2, errmsg, LCD_ROW_LEN+1);
lcd_write_menu(); ui_disp_menu(1);
usleep(1000000); usleep(1000000);
// Critical error, retry update // Critical error, retry update
@ -223,5 +216,6 @@ failure:
goto update_init; goto update_init;
} }
render_osd_page();
return -1; return -1;
} }

View File

@ -24,7 +24,7 @@
#include "sysconfig.h" #include "sysconfig.h"
#define FW_VER_MAJOR 0 #define FW_VER_MAJOR 0
#define FW_VER_MINOR 86 #define FW_VER_MINOR 87
#define PROFILE_VER_MAJOR 0 #define PROFILE_VER_MAJOR 0
#define PROFILE_VER_MINOR 86 #define PROFILE_VER_MINOR 86

View File

@ -44,7 +44,7 @@ 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 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 auto_input, auto_av1_ypbpr, auto_av2_ypbpr, auto_av3_ypbpr;
extern alt_u8 update_cur_vm; extern alt_u8 update_cur_vm;
extern alt_u8 osd_enable_pre, osd_status_timeout_pre; extern alt_u8 osd_enable, osd_enable_pre, osd_status_timeout_pre;
extern char target_profile_name[PROFILE_NAME_LEN+1]; extern char target_profile_name[PROFILE_NAME_LEN+1];
extern volatile osd_regs *osd; extern volatile osd_regs *osd;
@ -76,6 +76,7 @@ static const char *sl_id_desc[] = { LNG("Top","ウエ"), LNG("Bottom","シタ")
static const char *audio_dw_sampl_desc[] = { LNG("Off (fs = 96kHz)","オフ (fs = 96kHz)"), "2x (fs = 48kHz)" }; static const char *audio_dw_sampl_desc[] = { LNG("Off (fs = 96kHz)","オフ (fs = 96kHz)"), "2x (fs = 48kHz)" };
static const char *lt_desc[] = { "Top-left", "Center", "Bottom-right" }; static const char *lt_desc[] = { "Top-left", "Center", "Bottom-right" };
static const char *lcd_bl_timeout_desc[] = { "Off", "3s", "10s", "30s" }; static const char *lcd_bl_timeout_desc[] = { "Off", "3s", "10s", "30s" };
static const char *osd_enable_desc[] = { "Off", "Full", "Simple" };
static const char *osd_status_desc[] = { "2s", "5s", "10s", "Off" }; static const char *osd_status_desc[] = { "2s", "5s", "10s", "Off" };
static const char *rgsb_ypbpr_desc[] = { "RGsB", "YPbPr" }; static const char *rgsb_ypbpr_desc[] = { "RGsB", "YPbPr" };
static const char *auto_input_desc[] = { "Off", "Current input", "All inputs" }; static const char *auto_input_desc[] = { "Off", "Current input", "All inputs" };
@ -90,8 +91,8 @@ static void sl_cust_str_disp(alt_u8 v) { sniprintf(menu_row2, LCD_ROW_LEN+1, "%u
static void sl_hybr_str_disp(alt_u8 v) { sniprintf(menu_row2, LCD_ROW_LEN+1, "%u%%", (v*625)/100); } 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 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); } static void pixels_disp(alt_u8 v) { sniprintf(menu_row2, LCD_ROW_LEN+1, LNG("%u pixels","%u ドット"), v); }
static void value_disp(alt_u8 v) { sniprintf(menu_row2, LCD_ROW_LEN+1, " %u", v); } 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 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 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 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[v].name, LCD_ROW_LEN+1); }
@ -108,7 +109,7 @@ static const arg_info_t lt_arg_info = {&lt_sel, (sizeof(lt_desc)/sizeof(char*))-
MENU(menu_advtiming, P99_PROTECT({ \ MENU(menu_advtiming, P99_PROTECT({ \
{ LNG("H. samplerate","H. サンプルレート"), OPT_AVCONFIG_NUMVAL_U16,{ .num_u16 = { &tc_h_samplerate, H_TOTAL_MIN, H_TOTAL_MAX, vm_tweak } } }, { LNG("H. samplerate","H. サンプルレート"), OPT_AVCONFIG_NUMVAL_U16,{ .num_u16 = { &tc_h_samplerate, H_TOTAL_MIN, H_TOTAL_MAX, vm_tweak } } },
{ "H. s.rate adj", OPT_AVCONFIG_NUMVAL_U16,{ .num_u16 = { &tc_h_samplerate_adj, 0, H_TOTAL_ADJ_MAX, vm_tweak } } }, { "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. 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. 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_MAX, vm_tweak } } },
@ -234,7 +235,7 @@ MENU(menu_settings, P99_PROTECT({ \
{ "Auto AV2 Y/Gs", OPT_AVCONFIG_SELECTION, { .sel = { &auto_av2_ypbpr, OPT_WRAP, SETTING_ITEM(rgsb_ypbpr_desc) } } }, { "Auto AV2 Y/Gs", OPT_AVCONFIG_SELECTION, { .sel = { &auto_av2_ypbpr, OPT_WRAP, SETTING_ITEM(rgsb_ypbpr_desc) } } },
{ "Auto AV3 Y/Gs", OPT_AVCONFIG_SELECTION, { .sel = { &auto_av3_ypbpr, OPT_WRAP, SETTING_ITEM(rgsb_ypbpr_desc) } } }, { "Auto AV3 Y/Gs", OPT_AVCONFIG_SELECTION, { .sel = { &auto_av3_ypbpr, OPT_WRAP, SETTING_ITEM(rgsb_ypbpr_desc) } } },
{ "LCD BL timeout", OPT_AVCONFIG_SELECTION, { .sel = { &lcd_bl_timeout, OPT_WRAP, SETTING_ITEM(lcd_bl_timeout_desc) } } }, { "LCD BL timeout", OPT_AVCONFIG_SELECTION, { .sel = { &lcd_bl_timeout, OPT_WRAP, SETTING_ITEM(lcd_bl_timeout_desc) } } },
{ "OSD enable", OPT_AVCONFIG_SELECTION, { .sel = { &osd_enable_pre, OPT_WRAP, SETTING_ITEM(off_on_desc) } } }, { "OSD", OPT_AVCONFIG_SELECTION, { .sel = { &osd_enable_pre, OPT_WRAP, SETTING_ITEM(osd_enable_desc) } } },
{ "OSD status disp.", OPT_AVCONFIG_SELECTION, { .sel = { &osd_status_timeout_pre, OPT_WRAP, SETTING_ITEM(osd_status_desc) } } }, { "OSD status disp.", OPT_AVCONFIG_SELECTION, { .sel = { &osd_status_timeout_pre, OPT_WRAP, SETTING_ITEM(osd_status_desc) } } },
#ifndef DEBUG #ifndef DEBUG
{ "<Import sett. >", OPT_FUNC_CALL, { .fun = { import_userdata, NULL } } }, { "<Import sett. >", OPT_FUNC_CALL, { .fun = { import_userdata, NULL } } },
@ -260,10 +261,73 @@ menunavi navi[] = {{&menu_main, 0}, {NULL, 0}, {NULL, 0}};
alt_u8 navlvl = 0; alt_u8 navlvl = 0;
menunavi* get_current_menunavi() {
return &navi[navlvl];
}
void write_option_value(menuitem_t *item, int func_called, int retval)
{
switch (item->type) {
case OPT_AVCONFIG_SELECTION:
strncpy(menu_row2, item->sel.setting_str[*(item->sel.data)], LCD_ROW_LEN+1);
break;
case OPT_AVCONFIG_NUMVALUE:
item->num.df(*(item->num.data));
break;
case OPT_AVCONFIG_NUMVAL_U16:
item->num_u16.df(item->num_u16.data);
break;
case OPT_SUBMENU:
if (item->sub.arg_info)
item->sub.arg_info->df(*item->sub.arg_info->data);
else
menu_row2[0] = 0;
break;
case OPT_FUNC_CALL:
if (func_called) {
if (retval == 0)
strncpy(menu_row2, "Done", LCD_ROW_LEN+1);
else if (retval < 0)
sniprintf(menu_row2, LCD_ROW_LEN+1, "Failed (%d)", retval);
} else if (item->fun.arg_info) {
item->fun.arg_info->df(*item->fun.arg_info->data);
} else {
menu_row2[0] = 0;
}
break;
default:
break;
}
}
void render_osd_page() {
int i;
menuitem_t *item;
uint32_t row_mask[2] = {0, 0};
if (!menu_active || (osd_enable != 1))
return;
for (i=0; i < navi[navlvl].m->num_items; i++) {
item = &navi[navlvl].m->items[i];
strncpy((char*)osd->osd_array.data[i][0], item->name, OSD_CHAR_COLS);
row_mask[0] |= (1<<i);
if ((item->type != OPT_SUBMENU) && (item->type != OPT_FUNC_CALL)) {
write_option_value(item, 0, 0);
strncpy((char*)osd->osd_array.data[i][1], menu_row2, OSD_CHAR_COLS);
row_mask[1] |= (1<<i);
}
}
osd->osd_sec_enable[0].mask = row_mask[0];
osd->osd_sec_enable[1].mask = row_mask[1];
}
void display_menu(alt_u8 forcedisp) void display_menu(alt_u8 forcedisp)
{ {
menucode_id code = NO_ACTION; menucode_id code = NO_ACTION;
menuitem_type type; menuitem_t *item;
alt_u8 *val, val_wrap, val_min, val_max; alt_u8 *val, val_wrap, val_min, val_max;
alt_u16 *val_u16, val_u16_min, val_u16_max; alt_u16 *val_u16, val_u16_min, val_u16_max;
int i, func_called = 0, retval = 0; int i, func_called = 0, retval = 0;
@ -278,40 +342,46 @@ void display_menu(alt_u8 forcedisp)
if (!forcedisp && !remote_code) if (!forcedisp && !remote_code)
return; return;
type = navi[navlvl].m->items[navi[navlvl].mp].type; item = &navi[navlvl].m->items[navi[navlvl].mp];
// Parse menu control // Parse menu control
switch (code) { switch (code) {
case PREV_PAGE: case PREV_PAGE:
navi[navlvl].mp = (navi[navlvl].mp == 0) ? navi[navlvl].m->num_items-1 : (navi[navlvl].mp-1);
break;
case NEXT_PAGE: case NEXT_PAGE:
navi[navlvl].mp = (navi[navlvl].mp+1) % navi[navlvl].m->num_items; if ((item->type == OPT_FUNC_CALL) || (item->type == OPT_SUBMENU))
osd->osd_sec_enable[1].mask &= ~(1<<navi[navlvl].mp);
if (code == PREV_PAGE)
navi[navlvl].mp = (navi[navlvl].mp == 0) ? navi[navlvl].m->num_items-1 : (navi[navlvl].mp-1);
else
navi[navlvl].mp = (navi[navlvl].mp+1) % navi[navlvl].m->num_items;
break; break;
case PREV_MENU: case PREV_MENU:
if (navlvl > 0) { if (navlvl > 0) {
navlvl--; navlvl--;
render_osd_page();
} else { } else {
menu_active = 0; menu_active = 0;
osd->osd_config.menu_active = 0; osd->osd_config.menu_active = 0;
lcd_write_status(); ui_disp_status(0);
return; return;
} }
break; break;
case OPT_SELECT: case OPT_SELECT:
switch (navi[navlvl].m->items[navi[navlvl].mp].type) { switch (item->type) {
case OPT_SUBMENU: case OPT_SUBMENU:
if (navi[navlvl].m->items[navi[navlvl].mp].sub.arg_f) if (item->sub.arg_f)
navi[navlvl].m->items[navi[navlvl].mp].sub.arg_f(); item->sub.arg_f();
if (navi[navlvl+1].m != navi[navlvl].m->items[navi[navlvl].mp].sub.menu) if (navi[navlvl+1].m != item->sub.menu)
navi[navlvl+1].mp = 0; navi[navlvl+1].mp = 0;
navi[navlvl+1].m = navi[navlvl].m->items[navi[navlvl].mp].sub.menu; navi[navlvl+1].m = item->sub.menu;
navlvl++; navlvl++;
render_osd_page();
break; break;
case OPT_FUNC_CALL: case OPT_FUNC_CALL:
retval = navi[navlvl].m->items[navi[navlvl].mp].fun.f(); retval = item->fun.f();
func_called = 1; func_called = 1;
break; break;
default: default:
@ -320,13 +390,13 @@ void display_menu(alt_u8 forcedisp)
break; break;
case VAL_MINUS: case VAL_MINUS:
case VAL_PLUS: case VAL_PLUS:
switch (navi[navlvl].m->items[navi[navlvl].mp].type) { switch (item->type) {
case OPT_AVCONFIG_SELECTION: case OPT_AVCONFIG_SELECTION:
case OPT_AVCONFIG_NUMVALUE: case OPT_AVCONFIG_NUMVALUE:
val = navi[navlvl].m->items[navi[navlvl].mp].sel.data; val = item->sel.data;
val_wrap = navi[navlvl].m->items[navi[navlvl].mp].sel.wrap_cfg; val_wrap = item->sel.wrap_cfg;
val_min = navi[navlvl].m->items[navi[navlvl].mp].sel.min; val_min = item->sel.min;
val_max = navi[navlvl].m->items[navi[navlvl].mp].sel.max; val_max = item->sel.max;
if (code == VAL_MINUS) if (code == VAL_MINUS)
*val = (*val > val_min) ? (*val-1) : (val_wrap ? val_max : val_min); *val = (*val > val_min) ? (*val-1) : (val_wrap ? val_max : val_min);
@ -334,9 +404,9 @@ void display_menu(alt_u8 forcedisp)
*val = (*val < val_max) ? (*val+1) : (val_wrap ? val_min : val_max); *val = (*val < val_max) ? (*val+1) : (val_wrap ? val_min : val_max);
break; break;
case OPT_AVCONFIG_NUMVAL_U16: case OPT_AVCONFIG_NUMVAL_U16:
val_u16 = navi[navlvl].m->items[navi[navlvl].mp].num_u16.data; val_u16 = item->num_u16.data;
val_u16_min = navi[navlvl].m->items[navi[navlvl].mp].num_u16.min; val_u16_min = item->num_u16.min;
val_u16_max = navi[navlvl].m->items[navi[navlvl].mp].num_u16.max; val_u16_max = item->num_u16.max;
val_wrap = (val_u16_min == 0); val_wrap = (val_u16_min == 0);
if (code == VAL_MINUS) if (code == VAL_MINUS)
*val_u16 = (*val_u16 > val_u16_min) ? (*val_u16-1) : (val_wrap ? val_u16_max : val_u16_min); *val_u16 = (*val_u16 > val_u16_min) ? (*val_u16-1) : (val_wrap ? val_u16_max : val_u16_min);
@ -344,10 +414,10 @@ void display_menu(alt_u8 forcedisp)
*val_u16 = (*val_u16 < val_u16_max) ? (*val_u16+1) : (val_wrap ? val_u16_min : val_u16_max); *val_u16 = (*val_u16 < val_u16_max) ? (*val_u16+1) : (val_wrap ? val_u16_min : val_u16_max);
break; break;
case OPT_SUBMENU: case OPT_SUBMENU:
val = navi[navlvl].m->items[navi[navlvl].mp].sub.arg_info->data; val = item->sub.arg_info->data;
val_max = navi[navlvl].m->items[navi[navlvl].mp].sub.arg_info->max; val_max = item->sub.arg_info->max;
if (navi[navlvl].m->items[navi[navlvl].mp].sub.arg_info) { if (item->sub.arg_info) {
if (code == VAL_MINUS) if (code == VAL_MINUS)
*val = (*val > 0) ? (*val-1) : 0; *val = (*val > 0) ? (*val-1) : 0;
else else
@ -355,10 +425,10 @@ void display_menu(alt_u8 forcedisp)
} }
break; break;
case OPT_FUNC_CALL: case OPT_FUNC_CALL:
val = navi[navlvl].m->items[navi[navlvl].mp].fun.arg_info->data; val = item->fun.arg_info->data;
val_max = navi[navlvl].m->items[navi[navlvl].mp].fun.arg_info->max; val_max = item->fun.arg_info->max;
if (navi[navlvl].m->items[navi[navlvl].mp].fun.arg_info) { if (item->fun.arg_info) {
if (code == VAL_MINUS) if (code == VAL_MINUS)
*val = (*val > 0) ? (*val-1) : 0; *val = (*val > 0) ? (*val-1) : 0;
else else
@ -374,37 +444,15 @@ void display_menu(alt_u8 forcedisp)
} }
// Generate menu text // Generate menu text
type = navi[navlvl].m->items[navi[navlvl].mp].type; item = &navi[navlvl].m->items[navi[navlvl].mp];
strncpy(menu_row1, navi[navlvl].m->items[navi[navlvl].mp].name, LCD_ROW_LEN+1); strncpy(menu_row1, item->name, LCD_ROW_LEN+1);
switch (navi[navlvl].m->items[navi[navlvl].mp].type) { write_option_value(item, func_called, retval);
case OPT_AVCONFIG_SELECTION: strncpy((char*)osd->osd_array.data[navi[navlvl].mp][1], menu_row2, OSD_CHAR_COLS);
strncpy(menu_row2, navi[navlvl].m->items[navi[navlvl].mp].sel.setting_str[*(navi[navlvl].m->items[navi[navlvl].mp].sel.data)], LCD_ROW_LEN+1); osd->osd_row_color.mask = (1<<navi[navlvl].mp);
break; if (func_called || ((item->type == OPT_FUNC_CALL) && item->fun.arg_info != NULL) || ((item->type == OPT_SUBMENU) && item->sub.arg_info != NULL))
case OPT_AVCONFIG_NUMVALUE: osd->osd_sec_enable[1].mask |= (1<<navi[navlvl].mp);
navi[navlvl].m->items[navi[navlvl].mp].num.df(*(navi[navlvl].m->items[navi[navlvl].mp].num.data));
break;
case OPT_AVCONFIG_NUMVAL_U16:
navi[navlvl].m->items[navi[navlvl].mp].num_u16.df(navi[navlvl].m->items[navi[navlvl].mp].num_u16.data);
break;
case OPT_SUBMENU:
if (navi[navlvl].m->items[navi[navlvl].mp].sub.arg_info)
navi[navlvl].m->items[navi[navlvl].mp].sub.arg_info->df(*navi[navlvl].m->items[navi[navlvl].mp].sub.arg_info->data);
else
menu_row2[0] = 0;
break;
case OPT_FUNC_CALL:
if (func_called)
sniprintf(menu_row2, LCD_ROW_LEN+1, "%s", (retval==0) ? "Done" : "Failed");
else if (navi[navlvl].m->items[navi[navlvl].mp].fun.arg_info)
navi[navlvl].m->items[navi[navlvl].mp].fun.arg_info->df(*navi[navlvl].m->items[navi[navlvl].mp].fun.arg_info->data);
else
menu_row2[0] = 0;
break;
default:
break;
}
lcd_write_menu(); ui_disp_menu(0);
} }
static void vm_select() { static void vm_select() {
@ -445,8 +493,10 @@ static void vm_tweak(alt_u16 *v) {
if (v == &tc_sampler_phase) if (v == &tc_sampler_phase)
sniprintf(menu_row2, LCD_ROW_LEN+1, LNG("%d deg","%d ド"), ((*v)*1125)/100); sniprintf(menu_row2, LCD_ROW_LEN+1, LNG("%d deg","%d ド"), ((*v)*1125)/100);
else if ((v == &tc_h_samplerate) || (v == &tc_h_samplerate_adj)) else if (v == &tc_h_samplerate)
sniprintf(menu_row2, LCD_ROW_LEN+1, "%u.%.2u", video_modes[vm_edit].h_total, video_modes[vm_edit].h_total_adj*5); sniprintf(menu_row2, LCD_ROW_LEN+1, "%u", video_modes[vm_edit].h_total);
else if (v == &tc_h_samplerate_adj)
sniprintf(menu_row2, LCD_ROW_LEN+1, ".%.2u", video_modes[vm_edit].h_total_adj*5);
else else
sniprintf(menu_row2, LCD_ROW_LEN+1, "%u", *v); sniprintf(menu_row2, LCD_ROW_LEN+1, "%u", *v);
} }

View File

@ -114,6 +114,8 @@ typedef struct {
alt_u8 mp; alt_u8 mp;
} menunavi; } menunavi;
menunavi* get_current_menunavi();
void render_osd_page();
void display_menu(alt_u8 forcedisp); void display_menu(alt_u8 forcedisp);
static void vm_select(); static void vm_select();
static void vm_tweak(alt_u16 *v); static void vm_tweak(alt_u16 *v);

View File

@ -41,7 +41,8 @@ extern alt_u8 lcd_bl_timeout;
extern alt_u8 auto_input, auto_av1_ypbpr, auto_av2_ypbpr, auto_av3_ypbpr; extern alt_u8 auto_input, auto_av1_ypbpr, auto_av2_ypbpr, auto_av3_ypbpr;
extern alt_u8 osd_enable_pre, osd_status_timeout_pre; extern alt_u8 osd_enable_pre, osd_status_timeout_pre;
extern SD_DEV sdcard_dev; extern SD_DEV sdcard_dev;
extern char menu_row1[LCD_ROW_LEN+1], menu_row2[LCD_ROW_LEN+1]; extern alt_flash_dev *epcq_dev;
extern char menu_row2[LCD_ROW_LEN+1];
char target_profile_name[PROFILE_NAME_LEN+1]; char target_profile_name[PROFILE_NAME_LEN+1];
@ -79,9 +80,9 @@ int write_userdata(alt_u8 entry)
((ude_initcfg*)databuf)->osd_enable = osd_enable_pre; ((ude_initcfg*)databuf)->osd_enable = osd_enable_pre;
((ude_initcfg*)databuf)->osd_status_timeout = osd_status_timeout_pre; ((ude_initcfg*)databuf)->osd_status_timeout = osd_status_timeout_pre;
memcpy(((ude_initcfg*)databuf)->keys, rc_keymap, sizeof(rc_keymap)); memcpy(((ude_initcfg*)databuf)->keys, rc_keymap, sizeof(rc_keymap));
retval = write_flash_page(databuf, sizeof(ude_initcfg), (USERDATA_OFFSET+entry*SECTORSIZE)/PAGESIZE); retval = alt_epcq_controller_write(epcq_dev, (USERDATA_OFFSET+entry*SECTORSIZE), databuf, sizeof(ude_initcfg));
if (retval != 0) if (retval != 0)
return -1; return retval;
printf("Initconfig data written (%u bytes)\n", sizeof(ude_initcfg) - offsetof(ude_initcfg, last_profile)); printf("Initconfig data written (%u bytes)\n", sizeof(ude_initcfg) - offsetof(ude_initcfg, last_profile));
break; break;
@ -103,15 +104,20 @@ int write_userdata(alt_u8 entry)
memcpy(databuf+pageoffset, &tc, sizeof(avconfig_t)); memcpy(databuf+pageoffset, &tc, sizeof(avconfig_t));
pageoffset += sizeof(avconfig_t); pageoffset += sizeof(avconfig_t);
// write a full page first // erase sector and write a full page first, assume sizeof(video_modes) >> PAGESIZE
memcpy(databuf+pageoffset, (char*)video_modes, PAGESIZE-pageoffset); memcpy(databuf+pageoffset, (char*)video_modes, PAGESIZE-pageoffset);
srcoffset = PAGESIZE-pageoffset; srcoffset = PAGESIZE-pageoffset;
vm_to_write -= PAGESIZE-pageoffset; vm_to_write -= PAGESIZE-pageoffset;
write_flash_page(databuf, PAGESIZE, ((USERDATA_OFFSET+entry*SECTORSIZE)/PAGESIZE)); retval = alt_epcq_controller_write(epcq_dev, (USERDATA_OFFSET+entry*SECTORSIZE), databuf, PAGESIZE);
if (retval != 0)
return retval;
// then write the rest // then write the rest
if (vm_to_write > 0) if (vm_to_write > 0) {
write_flash((alt_u8*)video_modes+srcoffset, vm_to_write, ((USERDATA_OFFSET+entry*SECTORSIZE)/PAGESIZE) + 1); retval = alt_epcq_controller_write_block(epcq_dev, (USERDATA_OFFSET+entry*SECTORSIZE), (USERDATA_OFFSET+entry*SECTORSIZE+PAGESIZE), (alt_u8*)video_modes+srcoffset, vm_to_write);
if (retval != 0)
return retval;
}
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)+VIDEO_MODES_SIZE);
break; break;
@ -137,11 +143,9 @@ int read_userdata(alt_u8 entry, int dry_run)
return -1; return -1;
} }
retval = read_flash(USERDATA_OFFSET+(entry*SECTORSIZE), PAGESIZE, databuf); retval = alt_epcq_controller_read(epcq_dev, (USERDATA_OFFSET+entry*SECTORSIZE), databuf, PAGESIZE);
if (retval != 0) { if (retval != 0)
printf("Flash read error\n"); return retval;
return -1;
}
if (strncmp(((ude_hdr*)databuf)->userdata_key, "USRDATA", 8)) { if (strncmp(((ude_hdr*)databuf)->userdata_key, "USRDATA", 8)) {
printf("No userdata found on entry %u\n", entry); printf("No userdata found on entry %u\n", entry);
@ -207,7 +211,9 @@ int read_userdata(alt_u8 entry, int dry_run)
pageoffset = 0; pageoffset = 0;
pageno++; pageno++;
// check // check
read_flash(USERDATA_OFFSET+(entry*SECTORSIZE)+pageno*PAGESIZE, PAGESIZE, databuf); retval = alt_epcq_controller_read(epcq_dev, (USERDATA_OFFSET+entry*SECTORSIZE+pageno*PAGESIZE), databuf, PAGESIZE);
if (retval != 0)
return retval;
} else { } else {
memcpy((char*)video_modes+dstoffset, databuf+pageoffset, vm_to_read); memcpy((char*)video_modes+dstoffset, databuf+pageoffset, vm_to_read);
pageoffset += vm_to_read; pageoffset += vm_to_read;
@ -229,6 +235,7 @@ int read_userdata(alt_u8 entry, int dry_run)
int import_userdata() int import_userdata()
{ {
SDRESULTS res;
int retval; int retval;
int n, entries_imported=0; int n, entries_imported=0;
char *errmsg; char *errmsg;
@ -239,11 +246,10 @@ int import_userdata()
retval = check_sdcard(databuf); retval = check_sdcard(databuf);
SPI_CS_High(); SPI_CS_High();
if (retval != 0) if (retval != 0)
goto failure; goto sd_disable;
strncpy(menu_row1, "Import? 1=Y, 2=N", LCD_ROW_LEN+1); strncpy(menu_row2, "Import? 1=Y, 2=N", LCD_ROW_LEN+1);
*menu_row2 = '\0'; ui_disp_menu(2);
lcd_write_menu();
while (1) { while (1) {
btn_vec = IORD_ALTERA_AVALON_PIO_DATA(PIO_1_BASE) & RC_MASK; btn_vec = IORD_ALTERA_AVALON_PIO_DATA(PIO_1_BASE) & RC_MASK;
@ -252,23 +258,23 @@ int import_userdata()
break; break;
} else if (btn_vec == rc_keymap[RC_BTN2]) { } else if (btn_vec == rc_keymap[RC_BTN2]) {
retval = UDATA_IMPT_CANCELLED; retval = UDATA_IMPT_CANCELLED;
goto failure; strncpy(menu_row2, "Cancelled", LCD_ROW_LEN+1);
goto sd_disable;
} }
usleep(WAITLOOP_SLEEP_US); usleep(WAITLOOP_SLEEP_US);
} }
strncpy(menu_row1, "Loading settings", LCD_ROW_LEN+1); strncpy(menu_row2, "Loading...", LCD_ROW_LEN+1);
strncpy(menu_row2, "please wait...", LCD_ROW_LEN+1); ui_disp_menu(2);
lcd_write_menu();
// Import the userdata // Import the userdata
for (n=0; n<=MAX_USERDATA_ENTRY; ++n) { for (n=0; n<=MAX_USERDATA_ENTRY; ++n) {
retval = SD_Read(&sdcard_dev, &header, (512+n*SECTORSIZE)/SD_BLK_SIZE, 0, sizeof(header)); res = SD_Read(&sdcard_dev, &header, (512+n*SECTORSIZE)/SD_BLK_SIZE, 0, sizeof(header));
if (retval != 0) { if (res != SD_OK) {
printf("Failed to read SD card\n"); printf("Failed to read SD card\n");
retval = -retval; retval = -res;
goto failure; goto sd_disable;
} }
if (strncmp(header.userdata_key, "USRDATA", 8)) { if (strncmp(header.userdata_key, "USRDATA", 8)) {
@ -291,27 +297,21 @@ int import_userdata()
(header.type == UDE_PROFILE) ? sizeof(ude_profile) : sizeof(ude_initcfg), databuf); (header.type == UDE_PROFILE) ? sizeof(ude_profile) : sizeof(ude_initcfg), databuf);
if (retval != 0) { if (retval != 0) {
printf("Copy from SD to flash failed (error %d)\n", retval); printf("Copy from SD to flash failed (error %d)\n", retval);
goto failure; goto sd_disable;
} }
entries_imported++; entries_imported++;
} }
SPI_CS_High();
read_userdata(INIT_CONFIG_SLOT, 0); read_userdata(INIT_CONFIG_SLOT, 0);
profile_sel = input_profiles[target_input]; profile_sel = input_profiles[target_input];
read_userdata(profile_sel, 0); read_userdata(profile_sel, 0);
sniprintf(menu_row1, LCD_ROW_LEN+1, "%d entries", entries_imported); sniprintf(menu_row2, LCD_ROW_LEN+1, "%d slots loaded", entries_imported);
strncpy(menu_row2, "imported", LCD_ROW_LEN+1); retval = 1;
lcd_write_menu();
usleep(1000000);
return 0; sd_disable:
failure:
SPI_CS_High(); SPI_CS_High();
return -1; return retval;
} }

View File

@ -202,12 +202,12 @@
#define ALT_MODULE_CLASS_epcq_controller_0_avl_csr altera_epcq_controller_mod #define ALT_MODULE_CLASS_epcq_controller_0_avl_csr altera_epcq_controller_mod
#define EPCQ_CONTROLLER_0_AVL_CSR_BASE 0x20100 #define EPCQ_CONTROLLER_0_AVL_CSR_BASE 0x20100
#define EPCQ_CONTROLLER_0_AVL_CSR_FLASH_TYPE "EPCS64" #define EPCQ_CONTROLLER_0_AVL_CSR_FLASH_TYPE "EPCS16"
#define EPCQ_CONTROLLER_0_AVL_CSR_IRQ 2 #define EPCQ_CONTROLLER_0_AVL_CSR_IRQ 2
#define EPCQ_CONTROLLER_0_AVL_CSR_IRQ_INTERRUPT_CONTROLLER_ID 0 #define EPCQ_CONTROLLER_0_AVL_CSR_IRQ_INTERRUPT_CONTROLLER_ID 0
#define EPCQ_CONTROLLER_0_AVL_CSR_IS_EPCS 1 #define EPCQ_CONTROLLER_0_AVL_CSR_IS_EPCS 1
#define EPCQ_CONTROLLER_0_AVL_CSR_NAME "/dev/epcq_controller_0_avl_csr" #define EPCQ_CONTROLLER_0_AVL_CSR_NAME "/dev/epcq_controller_0_avl_csr"
#define EPCQ_CONTROLLER_0_AVL_CSR_NUMBER_OF_SECTORS 128 #define EPCQ_CONTROLLER_0_AVL_CSR_NUMBER_OF_SECTORS 32
#define EPCQ_CONTROLLER_0_AVL_CSR_PAGE_SIZE 256 #define EPCQ_CONTROLLER_0_AVL_CSR_PAGE_SIZE 256
#define EPCQ_CONTROLLER_0_AVL_CSR_SECTOR_SIZE 65536 #define EPCQ_CONTROLLER_0_AVL_CSR_SECTOR_SIZE 65536
#define EPCQ_CONTROLLER_0_AVL_CSR_SPAN 32 #define EPCQ_CONTROLLER_0_AVL_CSR_SPAN 32
@ -222,15 +222,15 @@
#define ALT_MODULE_CLASS_epcq_controller_0_avl_mem altera_epcq_controller_mod #define ALT_MODULE_CLASS_epcq_controller_0_avl_mem altera_epcq_controller_mod
#define EPCQ_CONTROLLER_0_AVL_MEM_BASE 0x800000 #define EPCQ_CONTROLLER_0_AVL_MEM_BASE 0x800000
#define EPCQ_CONTROLLER_0_AVL_MEM_FLASH_TYPE "EPCS64" #define EPCQ_CONTROLLER_0_AVL_MEM_FLASH_TYPE "EPCS16"
#define EPCQ_CONTROLLER_0_AVL_MEM_IRQ -1 #define EPCQ_CONTROLLER_0_AVL_MEM_IRQ -1
#define EPCQ_CONTROLLER_0_AVL_MEM_IRQ_INTERRUPT_CONTROLLER_ID -1 #define EPCQ_CONTROLLER_0_AVL_MEM_IRQ_INTERRUPT_CONTROLLER_ID -1
#define EPCQ_CONTROLLER_0_AVL_MEM_IS_EPCS 1 #define EPCQ_CONTROLLER_0_AVL_MEM_IS_EPCS 1
#define EPCQ_CONTROLLER_0_AVL_MEM_NAME "/dev/epcq_controller_0_avl_mem" #define EPCQ_CONTROLLER_0_AVL_MEM_NAME "/dev/epcq_controller_0_avl_mem"
#define EPCQ_CONTROLLER_0_AVL_MEM_NUMBER_OF_SECTORS 128 #define EPCQ_CONTROLLER_0_AVL_MEM_NUMBER_OF_SECTORS 32
#define EPCQ_CONTROLLER_0_AVL_MEM_PAGE_SIZE 256 #define EPCQ_CONTROLLER_0_AVL_MEM_PAGE_SIZE 256
#define EPCQ_CONTROLLER_0_AVL_MEM_SECTOR_SIZE 65536 #define EPCQ_CONTROLLER_0_AVL_MEM_SECTOR_SIZE 65536
#define EPCQ_CONTROLLER_0_AVL_MEM_SPAN 8388608 #define EPCQ_CONTROLLER_0_AVL_MEM_SPAN 2097152
#define EPCQ_CONTROLLER_0_AVL_MEM_SUBSECTOR_SIZE 4096 #define EPCQ_CONTROLLER_0_AVL_MEM_SUBSECTOR_SIZE 4096
#define EPCQ_CONTROLLER_0_AVL_MEM_TYPE "altera_epcq_controller_mod" #define EPCQ_CONTROLLER_0_AVL_MEM_TYPE "altera_epcq_controller_mod"
@ -397,7 +397,7 @@
#define ALT_MODULE_CLASS_osd_generator_0 osd_generator #define ALT_MODULE_CLASS_osd_generator_0 osd_generator
#define OSD_GENERATOR_0_BASE 0x24000 #define OSD_GENERATOR_0_BASE 0x24000
#define OSD_GENERATOR_0_SPAN 16 #define OSD_GENERATOR_0_SPAN 1024
/* /*
* pll_reconfig configuration * pll_reconfig configuration

File diff suppressed because one or more lines are too long

View File

@ -1,11 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<EnsembleReport name="sys" kind="sys" version="1.0" fabric="QSYS"> <EnsembleReport name="sys" kind="sys" version="1.0" fabric="QSYS">
<!-- Format version 19.1 670 (Future versions may contain additional information.) --> <!-- Format version 19.1 670 (Future versions may contain additional information.) -->
<!-- 2020.02.09.20:25:12 --> <!-- 2020.10.03.18:14:20 -->
<!-- A collection of modules and connections --> <!-- A collection of modules and connections -->
<parameter name="AUTO_GENERATION_ID"> <parameter name="AUTO_GENERATION_ID">
<type>java.lang.Integer</type> <type>java.lang.Integer</type>
<value>1581272712</value> <value>1601738060</value>
<derived>false</derived> <derived>false</derived>
<enabled>true</enabled> <enabled>true</enabled>
<visible>false</visible> <visible>false</visible>
@ -480,13 +480,13 @@ parameters are a RESULT of the module parameters. -->
<module <module
name="epcq_controller_0" name="epcq_controller_0"
kind="altera_epcq_controller_mod" kind="altera_epcq_controller_mod"
version="17.1" version="19.1"
path="epcq_controller_0"> path="epcq_controller_0">
<!-- Describes a single module. Module parameters are <!-- Describes a single module. Module parameters are
the requested settings for a module instance. --> the requested settings for a module instance. -->
<assignment> <assignment>
<name>embeddedsw.CMacro.FLASH_TYPE</name> <name>embeddedsw.CMacro.FLASH_TYPE</name>
<value>EPCS64</value> <value>EPCS16</value>
</assignment> </assignment>
<assignment> <assignment>
<name>embeddedsw.CMacro.IS_EPCS</name> <name>embeddedsw.CMacro.IS_EPCS</name>
@ -494,7 +494,7 @@ the requested settings for a module instance. -->
</assignment> </assignment>
<assignment> <assignment>
<name>embeddedsw.CMacro.NUMBER_OF_SECTORS</name> <name>embeddedsw.CMacro.NUMBER_OF_SECTORS</name>
<value>128</value> <value>32</value>
</assignment> </assignment>
<assignment> <assignment>
<name>embeddedsw.CMacro.PAGE_SIZE</name> <name>embeddedsw.CMacro.PAGE_SIZE</name>
@ -579,7 +579,7 @@ the requested settings for a module instance. -->
</parameter> </parameter>
<parameter name="ADDR_WIDTH"> <parameter name="ADDR_WIDTH">
<type>int</type> <type>int</type>
<value>21</value> <value>19</value>
<derived>true</derived> <derived>true</derived>
<enabled>true</enabled> <enabled>true</enabled>
<visible>false</visible> <visible>false</visible>
@ -630,7 +630,7 @@ the requested settings for a module instance. -->
</parameter> </parameter>
<parameter name="FLASH_TYPE"> <parameter name="FLASH_TYPE">
<type>java.lang.String</type> <type>java.lang.String</type>
<value>EPCS64</value> <value>EPCS16</value>
<derived>false</derived> <derived>false</derived>
<enabled>true</enabled> <enabled>true</enabled>
<visible>true</visible> <visible>true</visible>
@ -1189,7 +1189,7 @@ parameters are a RESULT of the module parameters. -->
</parameter> </parameter>
<parameter name="addressSpan"> <parameter name="addressSpan">
<type>java.math.BigInteger</type> <type>java.math.BigInteger</type>
<value>8388608</value> <value>2097152</value>
<derived>true</derived> <derived>true</derived>
<enabled>true</enabled> <enabled>true</enabled>
<visible>false</visible> <visible>false</visible>
@ -1512,7 +1512,7 @@ parameters are a RESULT of the module parameters. -->
<port> <port>
<name>avl_mem_addr</name> <name>avl_mem_addr</name>
<direction>Input</direction> <direction>Input</direction>
<width>21</width> <width>19</width>
<role>address</role> <role>address</role>
</port> </port>
<port> <port>
@ -4109,7 +4109,7 @@ parameters are a RESULT of the module parameters. -->
<module <module
name="master_0" name="master_0"
kind="altera_jtag_avalon_master_mod" kind="altera_jtag_avalon_master_mod"
version="17.1" version="19.1"
path="master_0"> path="master_0">
<!-- Describes a single module. Module parameters are <!-- Describes a single module. Module parameters are
the requested settings for a module instance. --> the requested settings for a module instance. -->
@ -5950,14 +5950,6 @@ parameters are a RESULT of the module parameters. -->
path="osd_generator_0"> path="osd_generator_0">
<!-- Describes a single module. Module parameters are <!-- Describes a single module. Module parameters are
the requested settings for a module instance. --> the requested settings for a module instance. -->
<parameter name="USE_MEMORY_BLOCKS">
<type>int</type>
<value>1</value>
<derived>false</derived>
<enabled>true</enabled>
<visible>true</visible>
<valid>true</valid>
</parameter>
<parameter name="deviceFamily"> <parameter name="deviceFamily">
<type>java.lang.String</type> <type>java.lang.String</type>
<value>UNKNOWN</value> <value>UNKNOWN</value>
@ -6102,7 +6094,7 @@ parameters are a RESULT of the module parameters. -->
</parameter> </parameter>
<parameter name="addressSpan"> <parameter name="addressSpan">
<type>java.math.BigInteger</type> <type>java.math.BigInteger</type>
<value>64</value> <value>1024</value>
<derived>true</derived> <derived>true</derived>
<enabled>true</enabled> <enabled>true</enabled>
<visible>false</visible> <visible>false</visible>
@ -6401,7 +6393,7 @@ parameters are a RESULT of the module parameters. -->
<port> <port>
<name>avalon_s_address</name> <name>avalon_s_address</name>
<direction>Input</direction> <direction>Input</direction>
<width>4</width> <width>8</width>
<role>address</role> <role>address</role>
</port> </port>
<port> <port>
@ -6512,7 +6504,7 @@ parameters are a RESULT of the module parameters. -->
<port> <port>
<name>osd_color</name> <name>osd_color</name>
<direction>Output</direction> <direction>Output</direction>
<width>1</width> <width>2</width>
<role>osd_color</role> <role>osd_color</role>
</port> </port>
</interface> </interface>
@ -9622,7 +9614,7 @@ parameters are a RESULT of the module parameters. -->
<slaveName>avalon_s</slaveName> <slaveName>avalon_s</slaveName>
<name>osd_generator_0.avalon_s</name> <name>osd_generator_0.avalon_s</name>
<baseAddress>147456</baseAddress> <baseAddress>147456</baseAddress>
<span>64</span> <span>1024</span>
</memoryBlock> </memoryBlock>
<memoryBlock> <memoryBlock>
<isBridge>false</isBridge> <isBridge>false</isBridge>
@ -9670,7 +9662,7 @@ parameters are a RESULT of the module parameters. -->
<slaveName>avl_mem</slaveName> <slaveName>avl_mem</slaveName>
<name>epcq_controller_0.avl_mem</name> <name>epcq_controller_0.avl_mem</name>
<baseAddress>8388608</baseAddress> <baseAddress>8388608</baseAddress>
<span>8388608</span> <span>2097152</span>
</memoryBlock> </memoryBlock>
<memoryBlock> <memoryBlock>
<isBridge>false</isBridge> <isBridge>false</isBridge>
@ -13244,7 +13236,7 @@ parameters are a RESULT of the module parameters. -->
<type>com.altera.entityinterfaces.IElementClass</type> <type>com.altera.entityinterfaces.IElementClass</type>
<subtype>com.altera.entityinterfaces.IModule</subtype> <subtype>com.altera.entityinterfaces.IModule</subtype>
<displayName>Altera Serial Flash Controller</displayName> <displayName>Altera Serial Flash Controller</displayName>
<version>17.1</version> <version>19.1</version>
</plugin> </plugin>
<plugin> <plugin>
<instanceCount>14</instanceCount> <instanceCount>14</instanceCount>
@ -13316,7 +13308,7 @@ parameters are a RESULT of the module parameters. -->
<type>com.altera.entityinterfaces.IElementClass</type> <type>com.altera.entityinterfaces.IElementClass</type>
<subtype>com.altera.entityinterfaces.IModule</subtype> <subtype>com.altera.entityinterfaces.IModule</subtype>
<displayName>JTAG to Avalon Master Bridge (customized)</displayName> <displayName>JTAG to Avalon Master Bridge (customized)</displayName>
<version>17.1</version> <version>19.1</version>
</plugin> </plugin>
<plugin> <plugin>
<instanceCount>3</instanceCount> <instanceCount>3</instanceCount>