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 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 OPAQUE_ADDRESS_MAP true
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 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 OPAQUE_ADDRESS_MAP true
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 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 AUTHOR "Altera Corporation"
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.
//
@ -20,32 +20,42 @@
#ifndef 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 {
struct {
alt_u8 enable:1;
alt_u8 status_refresh:1;
alt_u8 menu_active:1;
alt_u8 status_timeout:2;
alt_u8 x_offset:3;
alt_u8 y_offset:3;
alt_u8 x_size:2;
alt_u8 y_size:2;
alt_u32 osd_rsv:17;
uint8_t enable:1;
uint8_t status_refresh:1;
uint8_t menu_active:1;
uint8_t status_timeout:2;
uint8_t x_offset:3;
uint8_t y_offset:3;
uint8_t x_size:2;
uint8_t y_size:2;
uint8_t border_color:2;
uint32_t osd_rsv:15;
} __attribute__((packed, __may_alias__));
alt_u32 data;
uint32_t data;
} osd_config_reg;
// char regs
typedef struct {
char row1[16];
char row2[16];
} osd_char_regs;
char data[OSD_CHAR_ROWS][OSD_CHAR_SECTIONS][OSD_CHAR_COLS];
} osd_char_array;
typedef struct {
uint32_t mask;
} osd_enable_color_reg;
typedef struct {
osd_char_array osd_array;
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;
#endif //OSD_GENERATOR_REGS_H_

View File

@ -23,11 +23,11 @@ set_module_property REPORT_HIERARCHY false
#
# parameters
#
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_HINT boolean
set_parameter_property USE_MEMORY_BLOCKS UNITS None
set_parameter_property USE_MEMORY_BLOCKS HDL_PARAMETER true
#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_HINT boolean
#set_parameter_property USE_MEMORY_BLOCKS UNITS None
#set_parameter_property USE_MEMORY_BLOCKS HDL_PARAMETER true
#
# 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 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_readdata readdata Output 32
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 ypos ypos Input 11
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;
# 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

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.
//
@ -17,16 +17,14 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
module osd_generator_top #(
parameter USE_MEMORY_BLOCKS = 0
) (
module osd_generator_top (
// common
input clk_i,
input rst_i,
// avalon slave
input [31:0] avalon_s_writedata,
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 avalon_s_write,
input avalon_s_read,
@ -37,21 +35,33 @@ module osd_generator_top #(
input [10:0] xpos,
input [10:0] ypos,
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_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] 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] ypos_osd_area_scaled, ypos_text_scaled;
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 char_px;
wire render_enable = osd_config[0];
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 [1:0] x_size = osd_config[12:11];
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] ypos_scaled_w = (ypos >> y_size)-({3'h0, y_offset} << 3);
wire [7:0] rom_rdaddr;
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;
generate
if (USE_MEMORY_BLOCKS == 1) begin
char_array char_array_inst (
.byteena_a(avalon_s_byteenable),
.data(avalon_s_writedata),
.rdaddress(char_idx),
.rdclock(vclk),
.wraddress(avalon_s_address-1'b1),
.wrclock(clk_i),
.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_array char_array_inst (
.byteena_a(avalon_s_byteenable),
.data(avalon_s_writedata),
.rdaddress(char_idx),
.rdclock(vclk),
.wraddress(avalon_s_address),
.wrclock(clk_i),
.wren(avalon_s_chipselect && avalon_s_write && (avalon_s_address < CHAR_ROWS*CHAR_COLS*CHAR_SECTIONS)),
.q(rom_rdaddr)
);
char_rom char_rom_inst (
.clock(vclk),
@ -97,13 +101,13 @@ char_rom char_rom_inst (
);
// Pipeline structure
// | 0 | 1 | 2 | 3 | 4 | 5 |
// |----------|----------|---------|---------|---------|--------|
// > POS_TEXT | POS_AREA | | | | |
// > | PTR | PTR | PTR | PTR | |
// > | ENABLE | ENABLE | ENABLE | ENABLE | ENABLE |
// > | INDEX | INDEX | | | |
// > | | | CHARROM | CHARROM | COLOR |
// | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
// |----------|----------|---------|---------|---------|---------|--------|
// > POS_TEXT | POS_AREA | | | | | |
// > | PTR | PTR | PTR | PTR | | |
// > | ENABLE | ENABLE | ENABLE | ENABLE | ENABLE | ENABLE |
// > | INDEX | INDEX | | | | |
// > | | | CHARROM | CHARROM | CHAR_PX | COLOR |
integer idx, pp_idx;
always @(posedge vclk) begin
xpos_text_scaled <= xpos_scaled_w;
@ -119,32 +123,38 @@ always @(posedge vclk) begin
y_ptr[pp_idx] <= y_ptr[pp_idx-1];
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));
for(pp_idx = 3; pp_idx <= 5; pp_idx = pp_idx+1) begin
osd_text_act_pp[2] <= render_enable &
(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];
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)));
for(pp_idx = 4; pp_idx <= 5; pp_idx = pp_idx+1) begin
osd_act_pp[3] <= render_enable &
(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];
end
osd_enable <= osd_act_pp[5];
osd_color = osd_text_act_pp[5] ? char_data[y_ptr[5]][x_ptr[5]] : 1'b0;
end
char_px <= char_data[y_ptr[5]][x_ptr[5]];
generate
if (USE_MEMORY_BLOCKS == 0) begin
always @(posedge vclk) begin
char_idx_pp[2] <= char_idx;
char_idx_pp[3] <= char_idx_pp[2];
osd_enable <= osd_act_pp[6];
for(idx = 0; idx <= 7; idx = idx+1) begin
char_ptr_pp3[idx] <= char_ptr[{char_idx_pp[2][4:3], 3'(idx)}];
end
if (osd_text_act_pp[6]) begin
if (char_px) begin
osd_color <= config_reg[OSD_ROW_COLOR_REGNUM][char_row] ? BG_YELLOW : BG_WHITE;
end else begin
osd_color <= BG_BLUE;
end
end else begin // border
osd_color <= border_color;
end
endgenerate
end
// OSD status timeout counters
always @(posedge clk_i)
@ -188,39 +198,37 @@ always @(posedge clk_i or posedge rst_i) begin
end
end
genvar i;
generate
if (USE_MEMORY_BLOCKS == 0) begin
for (i = 0; i < (CHAR_ROWS*CHAR_COLS); i = i + 4) begin : genreg
always @(posedge clk_i or posedge rst_i) begin
if (rst_i) begin
char_ptr[i] <= 0;
char_ptr[i+1] <= 0;
char_ptr[i+2] <= 0;
char_ptr[i+3] <= 0;
end else begin
if (avalon_s_chipselect && avalon_s_write && (avalon_s_address==1+(i/4))) begin
if (avalon_s_byteenable[3])
char_ptr[i+3] <= avalon_s_writedata[31:24];
if (avalon_s_byteenable[2])
char_ptr[i+2] <= avalon_s_writedata[23:16];
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
for (i=OSD_ROW_LSEC_ENABLE_REGNUM; i <= OSD_ROW_COLOR_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
endgenerate
always @(*) begin
if (avalon_s_chipselect && avalon_s_read) begin
case (avalon_s_address)
OSD_CONFIG_REGNUM: avalon_s_readdata = osd_config;
default: avalon_s_readdata = 32'h00000000;
OSD_CONFIG_REGNUM: avalon_s_readdata = osd_config;
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
end else begin
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 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;
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 [10:0] xpos, xpos_sc, xpos_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;
always @(posedge PCLK_out) begin
HDMI_TX_RD <= osd_enable ? {8{osd_color}} : (enable_sc ? R_out_sc : R_out_vg);
HDMI_TX_GD <= osd_enable ? {8{osd_color}} : (enable_sc ? G_out_sc : G_out_vg);
HDMI_TX_BD <= osd_enable ? 8'hff : (enable_sc ? B_out_sc : B_out_vg);
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;

File diff suppressed because it is too large Load Diff

View File

@ -23,75 +23,23 @@
#include "flash.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)))
return -FLASH_DETECT_ERROR;
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;
}
if (epcq_dev == NULL)
return -1;
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) {
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)
return retval;

View File

@ -32,20 +32,10 @@
#define USERDATA_OFFSET 0x100000
#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
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);
#endif /* FLASH_H_ */

View File

@ -22,7 +22,7 @@
#include "flash.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;
@ -32,26 +32,33 @@ int check_sdcard(alt_u8 *databuf)
res = SD_Init(&sdcard_dev);
printf("SD det status: %u\n", res);
if (res != SD_OK)
return res;
if (res == SD_OK)
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)
{
SDRESULTS res;
int retval;
alt_u32 bytes_to_rw;
while (length > 0) {
bytes_to_rw = (length < SD_BLK_SIZE) ? length : SD_BLK_SIZE;
retval = SD_Read(&sdcard_dev, tmpbuf, sd_blknum, 0, bytes_to_rw);
if (retval != 0) {
res = SD_Read(&sdcard_dev, tmpbuf, sd_blknum, 0, bytes_to_rw);
if (res != SD_OK) {
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)
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 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);
strncpy((char*)osd->osd_chars.row2, menu_row2, LCD_ROW_LEN);
alt_u8 menu_page;
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);
}
inline void lcd_write_status() {
strncpy((char*)osd->osd_chars.row1, row1, LCD_ROW_LEN);
strncpy((char*)osd->osd_chars.row2, row2, LCD_ROW_LEN);
lcd_write((char*)&row1, (char*)&row2);
void ui_disp_status(alt_u8 refresh_osd_timer) {
if (!menu_active) {
if (refresh_osd_timer)
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
@ -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(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) {
osd->osd_config.status_refresh = 1;
lcd_write_status();
}
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);
@ -842,8 +860,8 @@ int init_hw()
}
#endif
if (check_flash() != 0) {
printf("Error: incorrect flash type detected\n");
if (init_flash() != 0) {
printf("Error: could not find flash\n");
return -1;
}
@ -863,17 +881,18 @@ int init_hw()
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.enable = !!osd_enable;
osd->osd_config.status_timeout = osd_status_timeout;
// Setup remote keymap
if (!(IORD_ALTERA_AVALON_PIO_DATA(PIO_1_BASE) & PB1_BIT))
setup_rc();
osd->osd_config.border_color = 1;
// init always in HDMI mode (fixes yellow screen bug)
cm.hdmitx_vic = HDMI_480p60;
TX_enable(TX_HDMI_RGB);
// Setup remote keymap
if (!(IORD_ALTERA_AVALON_PIO_DATA(PIO_1_BASE) & PB1_BIT))
setup_rc();
return 0;
}
@ -886,7 +905,7 @@ int latency_test() {
sys_ctrl |= LT_ACTIVE|(position<<LT_MODE_OFFS);
IOWR_ALTERA_AVALON_PIO_DATA(PIO_0_BASE, sys_ctrl);
sniprintf(menu_row2, LCD_ROW_LEN+1, "OK to init");
lcd_write_menu();
ui_disp_menu(0);
while (1) {
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);
IOWR_ALTERA_AVALON_PIO_DATA(PIO_0_BASE, sys_ctrl);
menu_row2[0] = 0;
lcd_write_menu();
ui_disp_menu(0);
usleep(400000);
sys_ctrl |= LT_ARMED|(position<<LT_MODE_OFFS);
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);
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);
lcd_write_menu();
ui_disp_menu(0);
} else if (btn_vec == rc_keymap[RC_BACK]) {
break;
}
@ -978,14 +997,12 @@ int main()
#else
strncpy(row2, "** DEBUG BUILD *", LCD_ROW_LEN+1);
#endif
osd->osd_config.status_refresh = 1;
lcd_write_status();
ui_disp_status(1);
usleep(500000);
} else {
sniprintf(row1, LCD_ROW_LEN+1, "Init error %d", init_stat);
strncpy(row2, "", LCD_ROW_LEN+1);
osd->osd_config.status_refresh = 1;
lcd_write_status();
ui_disp_status(1);
while (1) {}
}
@ -1146,10 +1163,7 @@ int main()
cm.clkcnt = 0; //TODO: proper invalidate
strncpy(row1, avinput_str[cm.avinput], LCD_ROW_LEN+1);
strncpy(row2, " NO SYNC", LCD_ROW_LEN+1);
if (!menu_active) {
osd->osd_config.status_refresh = 1;
lcd_write_status();
}
ui_disp_status(1);
if (man_input_change) {
// record last input if it was selected manually
if (def_input == AV_LAST)
@ -1180,8 +1194,13 @@ int main()
if ((osd_enable != osd_enable_pre) || (osd_status_timeout != osd_status_timeout_pre)) {
osd_enable = osd_enable_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;
if (menu_active) {
remote_code = 0;
render_osd_page();
display_menu(1);
}
}
if (cm.avinput != AV_TESTPAT) {
@ -1201,10 +1220,7 @@ int main()
//ths_source_sel(THS_STANDBY, 0);
strncpy(row1, avinput_str[cm.avinput], LCD_ROW_LEN+1);
strncpy(row2, " NO SYNC", LCD_ROW_LEN+1);
if (!menu_active) {
osd->osd_config.status_refresh = 1;
lcd_write_status();
}
ui_disp_status(1);
alt_timestamp_start();// reset auto input timer
auto_input_ctr = 0;
auto_input_current_ctr = 0;

View File

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

View File

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

View File

@ -27,6 +27,7 @@
#include "av_controller.h"
#include "lcd.h"
#include "utils.h"
#include "menu.h"
#include "altera_avalon_pio_regs.h"
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)
{
alt_u32 crcval=0, i, bytes_to_read;
int retval;
SDRESULTS res;
for (i=0; i<size; i=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);
//retval = read_sd_block(offset+i, bytes_to_read, tmpbuf);
res = SD_Read(&sdcard_dev, tmpbuf, (offset+i)/SD_BLK_SIZE, 0, bytes_to_read);
if (retval != SD_OK)
return retval;
if (res != SD_OK)
return -res;
crcval = crc32(tmpbuf, bytes_to_read, (i==0));
}
@ -106,14 +106,16 @@ int fw_update()
asm volatile("mov %0, sp" : "=r"(sp));
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);
lcd_write_menu();
ui_disp_menu(1);
usleep(1000000);
#endif
retval = check_sdcard(databuf);
SPI_CS_High();
if (retval != 0)
if (retval != 0) {
retval = -retval;
goto failure;
}
retval = check_fw_header(databuf, &fw_header);
if (retval != 0)
@ -121,14 +123,14 @@ int fw_update()
sniprintf(menu_row1, LCD_ROW_LEN+1, "Validating data");
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);
if (retval != 0)
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);
strncpy(menu_row2, "Update? 1=Y, 2=N", LCD_ROW_LEN+1);
lcd_write_menu();
ui_disp_menu(1);
while (1) {
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);
update_init:
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);
if (retval != 0)
@ -160,7 +162,7 @@ update_init:
strncpy(menu_row1, "Verifying flash", 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);
if (retval != 0)
goto failure;
@ -169,7 +171,7 @@ update_init:
strncpy(menu_row1, "Firmware updated", LCD_ROW_LEN+1);
strncpy(menu_row2, "please restart", LCD_ROW_LEN+1);
lcd_write_menu();
ui_disp_menu(1);
while (1) {}
return 0;
@ -196,24 +198,15 @@ failure:
case FW_UPD_CANCELLED:
errmsg = "Update cancelled";
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:
errmsg = "Flash verif fail";
break;
default:
errmsg = "Error";
errmsg = "SD/Flash error";
break;
}
strncpy(menu_row2, errmsg, LCD_ROW_LEN+1);
lcd_write_menu();
ui_disp_menu(1);
usleep(1000000);
// Critical error, retry update
@ -223,5 +216,6 @@ failure:
goto update_init;
}
render_osd_page();
return -1;
}

View File

@ -24,7 +24,7 @@
#include "sysconfig.h"
#define FW_VER_MAJOR 0
#define FW_VER_MINOR 86
#define FW_VER_MINOR 87
#define PROFILE_VER_MAJOR 0
#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 auto_input, auto_av1_ypbpr, auto_av2_ypbpr, auto_av3_ypbpr;
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 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 *lt_desc[] = { "Top-left", "Center", "Bottom-right" };
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 *rgsb_ypbpr_desc[] = { "RGsB", "YPbPr" };
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 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 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 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); }
@ -108,7 +109,7 @@ static const arg_info_t lt_arg_info = {&lt_sel, (sizeof(lt_desc)/sizeof(char*))-
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 } } },
{ "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. 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 } } },
@ -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 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) } } },
{ "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) } } },
#ifndef DEBUG
{ "<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;
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)
{
menucode_id code = NO_ACTION;
menuitem_type type;
menuitem_t *item;
alt_u8 *val, val_wrap, val_min, val_max;
alt_u16 *val_u16, val_u16_min, val_u16_max;
int i, func_called = 0, retval = 0;
@ -278,40 +342,46 @@ void display_menu(alt_u8 forcedisp)
if (!forcedisp && !remote_code)
return;
type = navi[navlvl].m->items[navi[navlvl].mp].type;
item = &navi[navlvl].m->items[navi[navlvl].mp];
// Parse menu control
switch (code) {
case PREV_PAGE:
navi[navlvl].mp = (navi[navlvl].mp == 0) ? navi[navlvl].m->num_items-1 : (navi[navlvl].mp-1);
break;
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;
case PREV_MENU:
if (navlvl > 0) {
navlvl--;
render_osd_page();
} else {
menu_active = 0;
osd->osd_config.menu_active = 0;
lcd_write_status();
ui_disp_status(0);
return;
}
break;
case OPT_SELECT:
switch (navi[navlvl].m->items[navi[navlvl].mp].type) {
switch (item->type) {
case OPT_SUBMENU:
if (navi[navlvl].m->items[navi[navlvl].mp].sub.arg_f)
navi[navlvl].m->items[navi[navlvl].mp].sub.arg_f();
if (item->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].m = navi[navlvl].m->items[navi[navlvl].mp].sub.menu;
navi[navlvl+1].m = item->sub.menu;
navlvl++;
render_osd_page();
break;
case OPT_FUNC_CALL:
retval = navi[navlvl].m->items[navi[navlvl].mp].fun.f();
retval = item->fun.f();
func_called = 1;
break;
default:
@ -320,13 +390,13 @@ void display_menu(alt_u8 forcedisp)
break;
case VAL_MINUS:
case VAL_PLUS:
switch (navi[navlvl].m->items[navi[navlvl].mp].type) {
switch (item->type) {
case OPT_AVCONFIG_SELECTION:
case OPT_AVCONFIG_NUMVALUE:
val = navi[navlvl].m->items[navi[navlvl].mp].sel.data;
val_wrap = navi[navlvl].m->items[navi[navlvl].mp].sel.wrap_cfg;
val_min = navi[navlvl].m->items[navi[navlvl].mp].sel.min;
val_max = navi[navlvl].m->items[navi[navlvl].mp].sel.max;
val = item->sel.data;
val_wrap = item->sel.wrap_cfg;
val_min = item->sel.min;
val_max = item->sel.max;
if (code == VAL_MINUS)
*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);
break;
case OPT_AVCONFIG_NUMVAL_U16:
val_u16 = navi[navlvl].m->items[navi[navlvl].mp].num_u16.data;
val_u16_min = navi[navlvl].m->items[navi[navlvl].mp].num_u16.min;
val_u16_max = navi[navlvl].m->items[navi[navlvl].mp].num_u16.max;
val_u16 = item->num_u16.data;
val_u16_min = item->num_u16.min;
val_u16_max = item->num_u16.max;
val_wrap = (val_u16_min == 0);
if (code == VAL_MINUS)
*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);
break;
case OPT_SUBMENU:
val = navi[navlvl].m->items[navi[navlvl].mp].sub.arg_info->data;
val_max = navi[navlvl].m->items[navi[navlvl].mp].sub.arg_info->max;
val = item->sub.arg_info->data;
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)
*val = (*val > 0) ? (*val-1) : 0;
else
@ -355,10 +425,10 @@ void display_menu(alt_u8 forcedisp)
}
break;
case OPT_FUNC_CALL:
val = navi[navlvl].m->items[navi[navlvl].mp].fun.arg_info->data;
val_max = navi[navlvl].m->items[navi[navlvl].mp].fun.arg_info->max;
val = item->fun.arg_info->data;
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)
*val = (*val > 0) ? (*val-1) : 0;
else
@ -374,37 +444,15 @@ void display_menu(alt_u8 forcedisp)
}
// Generate menu text
type = navi[navlvl].m->items[navi[navlvl].mp].type;
strncpy(menu_row1, navi[navlvl].m->items[navi[navlvl].mp].name, LCD_ROW_LEN+1);
switch (navi[navlvl].m->items[navi[navlvl].mp].type) {
case OPT_AVCONFIG_SELECTION:
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);
break;
case OPT_AVCONFIG_NUMVALUE:
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;
}
item = &navi[navlvl].m->items[navi[navlvl].mp];
strncpy(menu_row1, item->name, LCD_ROW_LEN+1);
write_option_value(item, func_called, retval);
strncpy((char*)osd->osd_array.data[navi[navlvl].mp][1], menu_row2, OSD_CHAR_COLS);
osd->osd_row_color.mask = (1<<navi[navlvl].mp);
if (func_called || ((item->type == OPT_FUNC_CALL) && item->fun.arg_info != NULL) || ((item->type == OPT_SUBMENU) && item->sub.arg_info != NULL))
osd->osd_sec_enable[1].mask |= (1<<navi[navlvl].mp);
lcd_write_menu();
ui_disp_menu(0);
}
static void vm_select() {
@ -445,8 +493,10 @@ static void vm_tweak(alt_u16 *v) {
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) || (v == &tc_h_samplerate_adj))
sniprintf(menu_row2, LCD_ROW_LEN+1, "%u.%.2u", video_modes[vm_edit].h_total, video_modes[vm_edit].h_total_adj*5);
else if (v == &tc_h_samplerate)
sniprintf(menu_row2, LCD_ROW_LEN+1, "%u", video_modes[vm_edit].h_total);
else if (v == &tc_h_samplerate_adj)
sniprintf(menu_row2, LCD_ROW_LEN+1, ".%.2u", video_modes[vm_edit].h_total_adj*5);
else
sniprintf(menu_row2, LCD_ROW_LEN+1, "%u", *v);
}

View File

@ -114,6 +114,8 @@ typedef struct {
alt_u8 mp;
} menunavi;
menunavi* get_current_menunavi();
void render_osd_page();
void display_menu(alt_u8 forcedisp);
static void vm_select();
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 osd_enable_pre, osd_status_timeout_pre;
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];
@ -79,9 +80,9 @@ int write_userdata(alt_u8 entry)
((ude_initcfg*)databuf)->osd_enable = osd_enable_pre;
((ude_initcfg*)databuf)->osd_status_timeout = osd_status_timeout_pre;
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)
return -1;
return retval;
printf("Initconfig data written (%u bytes)\n", sizeof(ude_initcfg) - offsetof(ude_initcfg, last_profile));
break;
@ -103,15 +104,20 @@ int write_userdata(alt_u8 entry)
memcpy(databuf+pageoffset, &tc, 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);
srcoffset = 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
if (vm_to_write > 0)
write_flash((alt_u8*)video_modes+srcoffset, vm_to_write, ((USERDATA_OFFSET+entry*SECTORSIZE)/PAGESIZE) + 1);
if (vm_to_write > 0) {
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);
break;
@ -137,11 +143,9 @@ int read_userdata(alt_u8 entry, int dry_run)
return -1;
}
retval = read_flash(USERDATA_OFFSET+(entry*SECTORSIZE), PAGESIZE, databuf);
if (retval != 0) {
printf("Flash read error\n");
return -1;
}
retval = alt_epcq_controller_read(epcq_dev, (USERDATA_OFFSET+entry*SECTORSIZE), databuf, PAGESIZE);
if (retval != 0)
return retval;
if (strncmp(((ude_hdr*)databuf)->userdata_key, "USRDATA", 8)) {
printf("No userdata found on entry %u\n", entry);
@ -207,7 +211,9 @@ int read_userdata(alt_u8 entry, int dry_run)
pageoffset = 0;
pageno++;
// 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 {
memcpy((char*)video_modes+dstoffset, databuf+pageoffset, vm_to_read);
pageoffset += vm_to_read;
@ -229,6 +235,7 @@ int read_userdata(alt_u8 entry, int dry_run)
int import_userdata()
{
SDRESULTS res;
int retval;
int n, entries_imported=0;
char *errmsg;
@ -239,11 +246,10 @@ int import_userdata()
retval = check_sdcard(databuf);
SPI_CS_High();
if (retval != 0)
goto failure;
goto sd_disable;
strncpy(menu_row1, "Import? 1=Y, 2=N", LCD_ROW_LEN+1);
*menu_row2 = '\0';
lcd_write_menu();
strncpy(menu_row2, "Import? 1=Y, 2=N", LCD_ROW_LEN+1);
ui_disp_menu(2);
while (1) {
btn_vec = IORD_ALTERA_AVALON_PIO_DATA(PIO_1_BASE) & RC_MASK;
@ -252,23 +258,23 @@ int import_userdata()
break;
} else if (btn_vec == rc_keymap[RC_BTN2]) {
retval = UDATA_IMPT_CANCELLED;
goto failure;
strncpy(menu_row2, "Cancelled", LCD_ROW_LEN+1);
goto sd_disable;
}
usleep(WAITLOOP_SLEEP_US);
}
strncpy(menu_row1, "Loading settings", LCD_ROW_LEN+1);
strncpy(menu_row2, "please wait...", LCD_ROW_LEN+1);
lcd_write_menu();
strncpy(menu_row2, "Loading...", LCD_ROW_LEN+1);
ui_disp_menu(2);
// Import the userdata
for (n=0; n<=MAX_USERDATA_ENTRY; ++n) {
retval = SD_Read(&sdcard_dev, &header, (512+n*SECTORSIZE)/SD_BLK_SIZE, 0, sizeof(header));
if (retval != 0) {
res = SD_Read(&sdcard_dev, &header, (512+n*SECTORSIZE)/SD_BLK_SIZE, 0, sizeof(header));
if (res != SD_OK) {
printf("Failed to read SD card\n");
retval = -retval;
goto failure;
retval = -res;
goto sd_disable;
}
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);
if (retval != 0) {
printf("Copy from SD to flash failed (error %d)\n", retval);
goto failure;
goto sd_disable;
}
entries_imported++;
}
SPI_CS_High();
read_userdata(INIT_CONFIG_SLOT, 0);
profile_sel = input_profiles[target_input];
read_userdata(profile_sel, 0);
sniprintf(menu_row1, LCD_ROW_LEN+1, "%d entries", entries_imported);
strncpy(menu_row2, "imported", LCD_ROW_LEN+1);
lcd_write_menu();
usleep(1000000);
sniprintf(menu_row2, LCD_ROW_LEN+1, "%d slots loaded", entries_imported);
retval = 1;
return 0;
failure:
sd_disable:
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 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_INTERRUPT_CONTROLLER_ID 0
#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_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_SECTOR_SIZE 65536
#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 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_INTERRUPT_CONTROLLER_ID -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_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_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_TYPE "altera_epcq_controller_mod"
@ -397,7 +397,7 @@
#define ALT_MODULE_CLASS_osd_generator_0 osd_generator
#define OSD_GENERATOR_0_BASE 0x24000
#define OSD_GENERATOR_0_SPAN 16
#define OSD_GENERATOR_0_SPAN 1024
/*
* 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"?>
<EnsembleReport name="sys" kind="sys" version="1.0" fabric="QSYS">
<!-- 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 -->
<parameter name="AUTO_GENERATION_ID">
<type>java.lang.Integer</type>
<value>1581272712</value>
<value>1601738060</value>
<derived>false</derived>
<enabled>true</enabled>
<visible>false</visible>
@ -480,13 +480,13 @@ parameters are a RESULT of the module parameters. -->
<module
name="epcq_controller_0"
kind="altera_epcq_controller_mod"
version="17.1"
version="19.1"
path="epcq_controller_0">
<!-- Describes a single module. Module parameters are
the requested settings for a module instance. -->
<assignment>
<name>embeddedsw.CMacro.FLASH_TYPE</name>
<value>EPCS64</value>
<value>EPCS16</value>
</assignment>
<assignment>
<name>embeddedsw.CMacro.IS_EPCS</name>
@ -494,7 +494,7 @@ the requested settings for a module instance. -->
</assignment>
<assignment>
<name>embeddedsw.CMacro.NUMBER_OF_SECTORS</name>
<value>128</value>
<value>32</value>
</assignment>
<assignment>
<name>embeddedsw.CMacro.PAGE_SIZE</name>
@ -579,7 +579,7 @@ the requested settings for a module instance. -->
</parameter>
<parameter name="ADDR_WIDTH">
<type>int</type>
<value>21</value>
<value>19</value>
<derived>true</derived>
<enabled>true</enabled>
<visible>false</visible>
@ -630,7 +630,7 @@ the requested settings for a module instance. -->
</parameter>
<parameter name="FLASH_TYPE">
<type>java.lang.String</type>
<value>EPCS64</value>
<value>EPCS16</value>
<derived>false</derived>
<enabled>true</enabled>
<visible>true</visible>
@ -1189,7 +1189,7 @@ parameters are a RESULT of the module parameters. -->
</parameter>
<parameter name="addressSpan">
<type>java.math.BigInteger</type>
<value>8388608</value>
<value>2097152</value>
<derived>true</derived>
<enabled>true</enabled>
<visible>false</visible>
@ -1512,7 +1512,7 @@ parameters are a RESULT of the module parameters. -->
<port>
<name>avl_mem_addr</name>
<direction>Input</direction>
<width>21</width>
<width>19</width>
<role>address</role>
</port>
<port>
@ -4109,7 +4109,7 @@ parameters are a RESULT of the module parameters. -->
<module
name="master_0"
kind="altera_jtag_avalon_master_mod"
version="17.1"
version="19.1"
path="master_0">
<!-- Describes a single module. Module parameters are
the requested settings for a module instance. -->
@ -5950,14 +5950,6 @@ parameters are a RESULT of the module parameters. -->
path="osd_generator_0">
<!-- Describes a single module. Module parameters are
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">
<type>java.lang.String</type>
<value>UNKNOWN</value>
@ -6102,7 +6094,7 @@ parameters are a RESULT of the module parameters. -->
</parameter>
<parameter name="addressSpan">
<type>java.math.BigInteger</type>
<value>64</value>
<value>1024</value>
<derived>true</derived>
<enabled>true</enabled>
<visible>false</visible>
@ -6401,7 +6393,7 @@ parameters are a RESULT of the module parameters. -->
<port>
<name>avalon_s_address</name>
<direction>Input</direction>
<width>4</width>
<width>8</width>
<role>address</role>
</port>
<port>
@ -6512,7 +6504,7 @@ parameters are a RESULT of the module parameters. -->
<port>
<name>osd_color</name>
<direction>Output</direction>
<width>1</width>
<width>2</width>
<role>osd_color</role>
</port>
</interface>
@ -9622,7 +9614,7 @@ parameters are a RESULT of the module parameters. -->
<slaveName>avalon_s</slaveName>
<name>osd_generator_0.avalon_s</name>
<baseAddress>147456</baseAddress>
<span>64</span>
<span>1024</span>
</memoryBlock>
<memoryBlock>
<isBridge>false</isBridge>
@ -9670,7 +9662,7 @@ parameters are a RESULT of the module parameters. -->
<slaveName>avl_mem</slaveName>
<name>epcq_controller_0.avl_mem</name>
<baseAddress>8388608</baseAddress>
<span>8388608</span>
<span>2097152</span>
</memoryBlock>
<memoryBlock>
<isBridge>false</isBridge>
@ -13244,7 +13236,7 @@ parameters are a RESULT of the module parameters. -->
<type>com.altera.entityinterfaces.IElementClass</type>
<subtype>com.altera.entityinterfaces.IModule</subtype>
<displayName>Altera Serial Flash Controller</displayName>
<version>17.1</version>
<version>19.1</version>
</plugin>
<plugin>
<instanceCount>14</instanceCount>
@ -13316,7 +13308,7 @@ parameters are a RESULT of the module parameters. -->
<type>com.altera.entityinterfaces.IElementClass</type>
<subtype>com.altera.entityinterfaces.IModule</subtype>
<displayName>JTAG to Avalon Master Bridge (customized)</displayName>
<version>17.1</version>
<version>19.1</version>
</plugin>
<plugin>
<instanceCount>3</instanceCount>