From 6c5f7532453eb28151e1fdf309985bbce723e331 Mon Sep 17 00:00:00 2001 From: marqs Date: Sun, 12 Jun 2016 23:43:24 +0300 Subject: [PATCH] Misc updates -optimizations from Borti -more code refactoring -fix build warnings -change scanline mode logic --- software/ossc_sw.project | 11 +- software/sys_controller/Makefile | 8 +- software/sys_controller/it6613/HDMI_TX.c | 1 + software/sys_controller/it6613/hdmitx.h | 2 + software/sys_controller/it6613/it6613.c | 1 + software/sys_controller/it6613/it6613_drv.c | 2 +- software/sys_controller/it6613/it6613_sys.c | 4 +- software/sys_controller/memory/flash.c | 2 + .../sys_controller/{ => ossc}/av_controller.c | 524 ++---------------- software/sys_controller/ossc/av_controller.h | 71 +++ software/sys_controller/ossc/avconfig.c | 47 ++ software/sys_controller/ossc/avconfig.h | 62 +++ software/sys_controller/ossc/controls.c | 148 +++++ software/sys_controller/ossc/controls.h | 60 ++ software/sys_controller/ossc/firmware.c | 202 +++++++ software/sys_controller/ossc/firmware.h | 43 ++ software/sys_controller/ossc/menu.c | 136 ++--- software/sys_controller/ossc/menu.h | 83 +-- software/sys_controller/ossc/sysconfig.h | 2 + software/sys_controller/ossc/userdata.c | 131 +++++ software/sys_controller/ossc/userdata.h | 47 ++ software/sys_controller/spi_charlcd/lcd.c | 3 + software/sys_controller/tvp7002/tvp7002.c | 2 +- software/sys_controller/tvp7002/tvp7002.h | 2 +- 24 files changed, 952 insertions(+), 642 deletions(-) rename software/sys_controller/{ => ossc}/av_controller.c (55%) create mode 100644 software/sys_controller/ossc/av_controller.h create mode 100644 software/sys_controller/ossc/avconfig.c create mode 100644 software/sys_controller/ossc/avconfig.h create mode 100644 software/sys_controller/ossc/controls.c create mode 100644 software/sys_controller/ossc/controls.h create mode 100644 software/sys_controller/ossc/firmware.c create mode 100644 software/sys_controller/ossc/firmware.h create mode 100644 software/sys_controller/ossc/userdata.c create mode 100644 software/sys_controller/ossc/userdata.h diff --git a/software/ossc_sw.project b/software/ossc_sw.project index 49fd560..f6db809 100644 --- a/software/ossc_sw.project +++ b/software/ossc_sw.project @@ -58,7 +58,6 @@ - @@ -69,6 +68,16 @@ + + + + + + + + + + diff --git a/software/sys_controller/Makefile b/software/sys_controller/Makefile index e745cc0..35af6a7 100644 --- a/software/sys_controller/Makefile +++ b/software/sys_controller/Makefile @@ -142,7 +142,6 @@ ACDS_VERSION := 14.1 ELF := sys_controller.elf # Paths to C, C++, and assembly source files. -C_SRCS += av_controller.c C_SRCS += it6613/EDID.c C_SRCS += it6613/HDMI_TX.c C_SRCS += it6613/hdmitx_nios2.c @@ -155,7 +154,12 @@ C_SRCS += ths7353/ths7353.c C_SRCS += spi_charlcd/lcd.c C_SRCS += memory/flash.c C_SRCS += memory/sdcard.c +C_SRCS += ossc/av_controller.c +C_SRCS += ossc/avconfig.c +C_SRCS += ossc/controls.c +C_SRCS += ossc/firmware.c C_SRCS += ossc/menu.c +C_SRCS += ossc/userdata.c CXX_SRCS := ASM_SRCS := @@ -177,7 +181,7 @@ APP_CFLAGS_DEFINED_SYMBOLS := -DNO_I2C_DEBUG -DNO_DEBUG APP_CFLAGS_UNDEFINED_SYMBOLS := APP_CFLAGS_OPTIMIZATION := -Os APP_CFLAGS_DEBUG_LEVEL := -APP_CFLAGS_WARNINGS := -Wall +APP_CFLAGS_WARNINGS := -Wall -Wno-unused-but-set-variable -Wno-unused-variable -Wno-unused-function APP_CFLAGS_USER_FLAGS := -fdata-sections -ffunction-sections -fshort-enums APP_ASFLAGS_USER := diff --git a/software/sys_controller/it6613/HDMI_TX.c b/software/sys_controller/it6613/HDMI_TX.c index 580ee50..747662a 100644 --- a/software/sys_controller/it6613/HDMI_TX.c +++ b/software/sys_controller/it6613/HDMI_TX.c @@ -1,5 +1,6 @@ //#include "terasic_includes.h" //#include "mcu.h" +#include #include "it6613_sys.h" #include "hdmitx.h" #include "HDMI_TX.h" diff --git a/software/sys_controller/it6613/hdmitx.h b/software/sys_controller/it6613/hdmitx.h index fa4c45e..fe5d011 100644 --- a/software/sys_controller/it6613/hdmitx.h +++ b/software/sys_controller/it6613/hdmitx.h @@ -78,6 +78,8 @@ HDCP_ResumeAuthentication() } #endif +void DelayMS(unsigned int ms); + //#include "edid.h" // #include "dss_sha.h" #include "it6613_drv.h" diff --git a/software/sys_controller/it6613/it6613.c b/software/sys_controller/it6613/it6613.c index 675a683..b9473bf 100644 --- a/software/sys_controller/it6613/it6613.c +++ b/software/sys_controller/it6613/it6613.c @@ -1,5 +1,6 @@ #include #include +#include "sysconfig.h" #include "system.h" #include "i2c_opencores.h" #include "it6613.h" diff --git a/software/sys_controller/it6613/it6613_drv.c b/software/sys_controller/it6613/it6613_drv.c index 4920ce0..db4340b 100644 --- a/software/sys_controller/it6613/it6613_drv.c +++ b/software/sys_controller/it6613/it6613_drv.c @@ -1225,7 +1225,7 @@ SetInputMode(BYTE InputMode,BYTE bInputSignalType) static void SetCSCScale(BYTE bInputMode,BYTE bOutputMode) { - BYTE ucData,csc ; + BYTE ucData,csc=0 ; BYTE filter = 0 ; // filter is for Video CTRL DN_FREE_GO,EN_DITHER,and ENUDFILT diff --git a/software/sys_controller/it6613/it6613_sys.c b/software/sys_controller/it6613/it6613_sys.c index 5208186..d2a1608 100644 --- a/software/sys_controller/it6613/it6613_sys.c +++ b/software/sys_controller/it6613/it6613_sys.c @@ -279,7 +279,7 @@ HDMITX_ChangeDisplayOption(HDMI_Video_Type OutputVideoTiming, HDMI_OutputColorMo bInputColorMode &= ~F_VIDMODE_ITU709 ; } - if( Colorimetry != HDMI_640x480p60) + if( OutputVideoTiming != HDMI_640x480p60) { bInputColorMode |= F_VIDMODE_16_235 ; } @@ -377,7 +377,7 @@ ParseEDID() // collect the EDID ucdata of segment 0 BYTE CheckSum ; BYTE BlockCount ; - BOOL err ; + BOOL err = FALSE ; BOOL bValidCEA = FALSE ; int i ; diff --git a/software/sys_controller/memory/flash.c b/software/sys_controller/memory/flash.c index 427d589..e5876a9 100644 --- a/software/sys_controller/memory/flash.c +++ b/software/sys_controller/memory/flash.c @@ -18,8 +18,10 @@ // #include +#include #include "flash.h" #include "lcd.h" +#include "ci_crc.h" extern alt_epcq_controller_dev epcq_controller_0; extern char menu_row1[LCD_ROW_LEN+1], menu_row2[LCD_ROW_LEN+1]; diff --git a/software/sys_controller/av_controller.c b/software/sys_controller/ossc/av_controller.c similarity index 55% rename from software/sys_controller/av_controller.c rename to software/sys_controller/ossc/av_controller.c index ff361dd..277bc84 100644 --- a/software/sys_controller/av_controller.c +++ b/software/sys_controller/ossc/av_controller.c @@ -23,6 +23,7 @@ #include "string.h" #include "altera_avalon_pio_regs.h" #include "i2c_opencores.h" +#include "av_controller.h" #include "tvp7002.h" #include "ths7353.h" #include "video_modes.h" @@ -30,16 +31,14 @@ #include "flash.h" #include "sdcard.h" #include "menu.h" +#include "avconfig.h" #include "sysconfig.h" +#include "firmware.h" +#include "userdata.h" #include "it6613.h" #include "it6613_sys.h" #include "HDMI_TX.h" #include "hdmitx.h" -#include "ci_crc.h" - -alt_u8 fw_ver_major = 0; -alt_u8 fw_ver_minor = 70; -#define FW_UPDATE_RETRIES 3 #define LINECNT_THOLD 1 #define STABLE_THOLD 1 @@ -48,109 +47,18 @@ alt_u8 fw_ver_minor = 70; #define SYNC_LOSS_THOLD 5 #define STATUS_TIMEOUT 10000 -#define MAINLOOP_SLEEP_US 10000 - -#define DEFAULT_PRE_COAST 1 -#define DEFAULT_POST_COAST 0 -#define DEFAULT_SAMPLER_PHASE 16 -#define DEFAULT_SYNC_VTH 11 - -#define RC_MASK 0x0000ffff -#define PB_MASK 0x00030000 -#define PB0_BIT 0x00010000 -#define PB1_BIT 0x00020000 #define HDMITX_MODE_MASK 0x00040000 -static const char *rc_keydesc[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "MENU", "OK", "BACK", "UP", "DOWN", "LEFT", "RIGHT", "INFO", "LCD_BACKLIGHT", "SCANLINE_TGL", "SCANLINE_INT+", "SCANLINE_INT-"}; -#define REMOTE_MAX_KEYS (sizeof(rc_keydesc)/sizeof(char*)) -alt_u16 rc_keymap[REMOTE_MAX_KEYS] = {0x3E29, 0x3EA9, 0x3E69, 0x3EE9, 0x3E19, 0x3E99, 0x3E59, 0x3ED9, 0x3E39, 0x3EC9, 0x3E4D, 0x3E1D, 0x3EED, 0x3E2D, 0x3ECD, 0x3EAD, 0x3E6D, 0x3E65, 0x3E01, 0x1C48, 0x1C50, 0x1CD0}; - -#define lcd_write_menu() lcd_write((char*)&menu_row1, (char*)&menu_row2) -#define lcd_write_status() lcd_write((char*)&row1, (char*)&row2) - -static const char *avinput_str[] = { "-", "AV1: RGBS", "AV1: RGsB", "AV1: YPbPr", "AV2: YPbPr", "AV2: RGsB", "AV3: RGBHV", "AV3: RGBS", "AV3: RGsB", "AV3: YPbPr" }; - -typedef enum { - AV_KEEP = 0, - AV1_RGBs = 1, - AV1_RGsB = 2, - AV1_YPBPR = 3, - AV2_YPBPR = 4, - AV2_RGsB = 5, - AV3_RGBHV = 6, - AV3_RGBs = 7, - AV3_RGsB = 8, - AV3_YPBPR = 9 -} avinput_t; - -// In reverse order of importance -typedef enum { - NO_CHANGE = 0, - INFO_CHANGE = 1, - MODE_CHANGE = 2, - TX_MODE_CHANGE = 3, - ACTIVITY_CHANGE = 4 -} status_t; - -typedef enum { - TX_HDMI = 0, - TX_DVI = 1 -} tx_mode_t; - - - -// Target configuration -avconfig_t tc; - -//TODO: transform binary values into flags -typedef struct { - alt_u32 totlines; - alt_u32 clkcnt; - alt_u8 progressive; - alt_u8 macrovis; - alt_8 id; - alt_u8 sync_active; - alt_u8 linemult; - avinput_t avinput; - // Current configuration - avconfig_t cc; -} avmode_t; - // Current mode avmode_t cm; -typedef struct { - char fw_key[4]; - alt_u8 version_major; - alt_u8 version_minor; - char version_suffix[8]; - alt_u32 hdr_len; - alt_u32 data_len; - alt_u32 data_crc; - alt_u32 hdr_crc; -} fw_hdr; - -#define USERDATA_HDR_SIZE 11 -typedef struct { - char userdata_key[8]; - alt_u8 version_major; - alt_u8 version_minor; - alt_u8 num_entries; -} userdata_hdr; - -#define USERDATA_ENTRY_HDR_SIZE 2 -typedef struct { - alt_u8 type; - alt_u8 entry_len; -} userdata_entry; - -typedef enum { - UDE_REMOTE_MAP = 0, - UDE_AVCONFIG, -} userdata_entry_type; - extern mode_data_t video_modes[]; extern ypbpr_to_rgb_csc_t csc_coeffs[]; +extern alt_u16 rc_keymap[REMOTE_MAX_KEYS]; +extern alt_u32 remote_code; +extern alt_u32 btn_code, btn_code_prev; +extern alt_u8 remote_rpt, remote_rpt_prev; +extern avconfig_t tc; alt_u8 target_typemask; alt_u8 target_type; @@ -158,336 +66,16 @@ alt_u8 stable_frames; char row1[LCD_ROW_LEN+1], row2[LCD_ROW_LEN+1], menu_row1[LCD_ROW_LEN+1], menu_row2[LCD_ROW_LEN+1]; -alt_u8 menu_active; -alt_u32 remote_code; -alt_u8 remote_rpt, remote_rpt_prev; -alt_u32 btn_code, btn_code_prev; +extern alt_u8 menu_active; avinput_t target_mode; -int check_fw_header(alt_u8 *databuf, fw_hdr *hdr) +inline void lcd_write_menu() { - alt_u32 crcval, tmp; - - strncpy(hdr->fw_key, (char*)databuf, 4); - if (strncmp(hdr->fw_key, "OSSC", 4)) { - sniprintf(menu_row1, LCD_ROW_LEN+1, "Invalid image"); - menu_row2[0] = '\0'; - return 1; - } - - hdr->version_major = databuf[4]; - hdr->version_minor = databuf[5]; - strncpy(hdr->version_suffix, (char*)(databuf+6), 8); - hdr->version_suffix[7] = 0; - - memcpy(&tmp, databuf+14, 4); - hdr->hdr_len = ALT_CI_NIOS_CUSTOM_INSTR_ENDIANCONVERTER_0(tmp); - memcpy(&tmp, databuf+18, 4); - hdr->data_len = ALT_CI_NIOS_CUSTOM_INSTR_ENDIANCONVERTER_0(tmp); - memcpy(&tmp, databuf+22, 4); - hdr->data_crc = ALT_CI_NIOS_CUSTOM_INSTR_ENDIANCONVERTER_0(tmp); - // Always at bytes [508-511] - memcpy(&tmp, databuf+508, 4); - hdr->hdr_crc = ALT_CI_NIOS_CUSTOM_INSTR_ENDIANCONVERTER_0(tmp); - - if (hdr->hdr_len < 26 || hdr->hdr_len > 508) { - sniprintf(menu_row1, LCD_ROW_LEN+1, "Invalid header"); - menu_row2[0] = '\0'; - return -1; - } - - crcval = crcCI(databuf, hdr->hdr_len, 1); - - if (crcval != hdr->hdr_crc) { - sniprintf(menu_row1, LCD_ROW_LEN+1, "Invalid hdr CRC"); - menu_row2[0] = '\0'; - return -2; - } - - return 0; + lcd_write((char*)&menu_row1, (char*)&menu_row2); } -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; - - for (i=0; i PAGESIZE) { - retval = write_flash_page(databuf+PAGESIZE, (bytes_to_rw-PAGESIZE), (i/PAGESIZE)+1); - if (retval != 0) - goto failure; - } - } - - strncpy(menu_row1, "Verifying flash", LCD_ROW_LEN+1); - strncpy(menu_row2, "please wait...", LCD_ROW_LEN+1); - lcd_write_menu(); - retval = verify_flash(0, fw_header.data_len, fw_header.data_crc, databuf); - if (retval != 0) - goto failure; - - return 0; - - -failure: - lcd_write_menu(); - usleep(1000000); - - // Probable rw error, retry update - if ((retval <= -200) && (retries > 0)) { - sniprintf(menu_row1, LCD_ROW_LEN+1, "Retrying update"); - retries--; - goto update_init; - } - - return -1; -} -#endif - -int write_userdata() -{ - alt_u8 databuf[PAGESIZE]; - int retval; - - strncpy((char*)databuf, "USRDATA", 8); - databuf[8] = fw_ver_major; - databuf[9] = fw_ver_minor; - databuf[10] = 2; - - retval = write_flash_page(databuf, USERDATA_HDR_SIZE, (USERDATA_OFFSET/PAGESIZE)); - if (retval != 0) { - return -1; - } - - databuf[0] = UDE_REMOTE_MAP; - databuf[1] = 4+sizeof(rc_keymap); - databuf[2] = databuf[3] = 0; //padding - memcpy(databuf+4, rc_keymap, sizeof(rc_keymap)); - - retval = write_flash_page(databuf, databuf[1], (USERDATA_OFFSET/PAGESIZE)+1); - if (retval != 0) { - return -1; - } - - databuf[0] = UDE_AVCONFIG; - databuf[1] = 4+sizeof(avconfig_t); - databuf[2] = databuf[3] = 0; //padding - memcpy(databuf+4, &tc, sizeof(avconfig_t)); - - retval = write_flash_page(databuf, databuf[1], (USERDATA_OFFSET/PAGESIZE)+2); - if (retval != 0) { - return -1; - } - - return 0; -} - - -int set_default_avconfig() -{ - memset(&tc, 0, sizeof(avconfig_t)); - tc.pre_coast = DEFAULT_PRE_COAST; - tc.post_coast = DEFAULT_POST_COAST; - tc.sampler_phase = DEFAULT_SAMPLER_PHASE; - tc.sync_vth = DEFAULT_SYNC_VTH; - tc.vsync_thold = DEFAULT_VSYNC_THOLD; - tc.en_alc = 1; - - return 0; -} - -int read_userdata() -{ - int retval, i; - alt_u8 databuf[PAGESIZE]; - userdata_hdr udhdr; - userdata_entry udentry; - - retval = read_flash(USERDATA_OFFSET, USERDATA_HDR_SIZE, databuf); - if (retval != 0) { - printf("Flash read error\n"); - return -1; - } - - strncpy(udhdr.userdata_key, (char*)databuf, 8); - if (strncmp(udhdr.userdata_key, "USRDATA", 8)) { - printf("No userdata found on flash\n"); - return 1; - } - - udhdr.version_major = databuf[8]; - udhdr.version_minor = databuf[9]; - udhdr.num_entries = databuf[10]; - - //TODO: check version compatibility - printf("Userdata: v%u.%.2u, %u entries\n", udhdr.version_major, udhdr.version_minor, udhdr.num_entries); - - for (i=0; i>16); - - if (remote_code == rc_keymap[RC_BTN1]) { - target_mode = AV1_RGBs; - } else if (remote_code == rc_keymap[RC_BTN4]) { - target_mode = AV1_RGsB; - } else if (remote_code == rc_keymap[RC_BTN7]) { - target_mode = AV1_YPBPR; - } else if (remote_code == rc_keymap[RC_BTN2]) { - target_mode = AV2_YPBPR; - } else if (remote_code == rc_keymap[RC_BTN5]) { - target_mode = AV2_RGsB; - } else if (remote_code == rc_keymap[RC_BTN3]) { - target_mode = AV3_RGBHV; - } else if (remote_code == rc_keymap[RC_BTN6]) { - target_mode = AV3_RGBs; - } else if (remote_code == rc_keymap[RC_BTN9]) { - target_mode = AV3_RGsB; - } else if (remote_code == rc_keymap[RC_BTN0]) { - target_mode = AV3_YPBPR; - } else if (remote_code == rc_keymap[RC_MENU]) { - menu_active = !menu_active; - - if (menu_active) { - display_menu(1); - } else { - lcd_write_status(); - } - /*} else if (remote_code == rc_keymap[RC_BACK]) { - menu_active = 0; - lcd_write_status();*/ - } else if (remote_code == rc_keymap[RC_INFO]) { - sniprintf(menu_row1, LCD_ROW_LEN+1, "VMod: %s", video_modes[cm.id].name); - //sniprintf(menu_row1, LCD_ROW_LEN+1, "0x%x 0x%x 0x%x", ths_readreg(THS_CH1), ths_readreg(THS_CH2), ths_readreg(THS_CH3)); - sniprintf(menu_row2, LCD_ROW_LEN+1, "LO: %u VSM: %u", IORD_ALTERA_AVALON_PIO_DATA(PIO_4_BASE) & 0xffff, (IORD_ALTERA_AVALON_PIO_DATA(PIO_4_BASE) >> 16) & 0x3); - lcd_write_menu(); - printf("Mod: %s\n", video_modes[cm.id].name); - printf("Lines: %u M: %u\n", IORD_ALTERA_AVALON_PIO_DATA(PIO_4_BASE) & 0xffff, cm.macrovis); - } else if (remote_code == rc_keymap[RC_LCDBL]) { - IOWR_ALTERA_AVALON_PIO_DATA(PIO_0_BASE, (IORD_ALTERA_AVALON_PIO_DATA(PIO_0_BASE) ^ (1<<1))); - } else if (remote_code == rc_keymap[RC_SL_TGL]) { - tc.sl_mode = (tc.sl_mode > 0) ? 0 : 1; - } else if (remote_code == rc_keymap[RC_SL_MINUS]) { - if (tc.sl_str > 0) - tc.sl_str--; - } else if (remote_code == rc_keymap[RC_SL_PLUS]) { - if (tc.sl_str < SCANLINESTR_MAX) - tc.sl_str++; - } - - if (btn_code_prev == 0) { - if (btn_code & PB0_BIT) - target_mode = (cm.avinput == AV3_YPBPR) ? AV1_RGBs : (cm.avinput+1); - if (btn_code & PB1_BIT) - tc.sl_mode = (tc.sl_mode > 0) ? 0 : 1; - } -} - void set_lpf(alt_u8 lpf) { alt_u32 pclk; @@ -704,6 +228,7 @@ status_t get_status(tvp_input_t input, video_format format) } if ((tc.sl_mode != cm.cc.sl_mode) || + (tc.sl_type != cm.cc.sl_type) || (tc.sl_str != cm.cc.sl_str) || (tc.sl_id != cm.cc.sl_id) || (tc.h_mask != cm.cc.h_mask) || @@ -747,6 +272,8 @@ status_t get_status(tvp_input_t input, video_format format) void set_videoinfo() { alt_u8 slid_target; + alt_u8 sl_en_fpga; + alt_u8 sl_mode_fpga = 0; if (video_modes[cm.id].flags & MODE_L3ENABLE_MASK) { cm.linemult = 2; @@ -759,8 +286,20 @@ void set_videoinfo() slid_target = cm.cc.sl_id; } + if (cm.cc.sl_mode == 0) { + sl_en_fpga = 0; + } else if (cm.cc.sl_mode == 2) { //manual + sl_en_fpga = 1; + sl_mode_fpga = cm.cc.sl_type; + } else if ((video_modes[cm.id].flags & (MODE_L2ENABLE|MODE_L3ENABLE_MASK)) && !(video_modes[cm.id].flags & MODE_INTERLACED)) { + sl_en_fpga = 1; + sl_mode_fpga = 0; + } else { + sl_en_fpga = 0; + } + IOWR_ALTERA_AVALON_PIO_DATA(PIO_2_BASE, (cm.linemult<<30) | (cm.cc.l3_mode<<28) | (cm.cc.h_mask)<<22 | (video_modes[cm.id].h_active<<10) | video_modes[cm.id].h_backporch); - IOWR_ALTERA_AVALON_PIO_DATA(PIO_3_BASE, ((!!cm.cc.sl_mode)<<31) | (cm.cc.sl_mode > 0 ? (cm.cc.sl_mode-1)<<30 : 0) | (slid_target<<29) | (cm.cc.sl_str<<25) | (cm.cc.v_mask<<19) | (video_modes[cm.id].v_active<<7) | video_modes[cm.id].v_backporch); + IOWR_ALTERA_AVALON_PIO_DATA(PIO_3_BASE, (sl_en_fpga<<31) | (sl_mode_fpga<<30) | (slid_target<<29) | (cm.cc.sl_str<<25) | (cm.cc.v_mask<<19) | (video_modes[cm.id].v_active<<7) | video_modes[cm.id].v_backporch); } // Configure TVP7002 and scan converter logic based on the video mode @@ -787,7 +326,6 @@ void program_mode() data2 = tvp_readreg(TVP_VSINWIDTH); printf("Hswidth: %u Vswidth: %u Macrovision: %u\n", (unsigned)data1, (unsigned)(data2 & 0x1F), (unsigned)cm.macrovis); - //TODO: rewrite with strncpy to reduce code size 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)); //strncpy(row1, avinput_str[cm.avinput], LCD_ROW_LEN+1); @@ -919,7 +457,7 @@ int main() if (init_stat >= 0) { printf("### DIY VIDEO DIGITIZER / SCANCONVERTER INIT OK ###\n\n"); - sniprintf(row1, LCD_ROW_LEN+1, "OSSC fw. %u.%.2u", fw_ver_major, fw_ver_minor); + sniprintf(row1, LCD_ROW_LEN+1, "OSSC fw. %u.%.2u", FW_VER_MAJOR, FW_VER_MINOR); #ifndef DEBUG strncpy(row2, "2014-2016 marqs", LCD_ROW_LEN+1); #else diff --git a/software/sys_controller/ossc/av_controller.h b/software/sys_controller/ossc/av_controller.h new file mode 100644 index 0000000..6389deb --- /dev/null +++ b/software/sys_controller/ossc/av_controller.h @@ -0,0 +1,71 @@ +// +// Copyright (C) 2015-2016 Markus Hiienkari +// +// This file is part of Open Source Scan Converter project. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// + +#ifndef AV_CONTROLLER_H_ +#define AV_CONTROLLER_H_ + +#include "avconfig.h" + +static const char *avinput_str[] = { "-", "AV1: RGBS", "AV1: RGsB", "AV1: YPbPr", "AV2: YPbPr", "AV2: RGsB", "AV3: RGBHV", "AV3: RGBS", "AV3: RGsB", "AV3: YPbPr" }; + +typedef enum { + AV_KEEP = 0, + AV1_RGBs = 1, + AV1_RGsB = 2, + AV1_YPBPR = 3, + AV2_YPBPR = 4, + AV2_RGsB = 5, + AV3_RGBHV = 6, + AV3_RGBs = 7, + AV3_RGsB = 8, + AV3_YPBPR = 9 +} avinput_t; + +// In reverse order of importance +typedef enum { + NO_CHANGE = 0, + INFO_CHANGE = 1, + MODE_CHANGE = 2, + TX_MODE_CHANGE = 3, + ACTIVITY_CHANGE = 4 +} status_t; + +typedef enum { + TX_HDMI = 0, + TX_DVI = 1 +} tx_mode_t; + +//TODO: transform binary values into flags +typedef struct { + alt_u32 totlines; + alt_u32 clkcnt; + alt_u8 progressive; + alt_u8 macrovis; + alt_8 id; + alt_u8 sync_active; + alt_u8 linemult; + avinput_t avinput; + // Current configuration + avconfig_t cc; +} avmode_t; + +inline void lcd_write_menu(); +inline void lcd_write_status(); + +#endif diff --git a/software/sys_controller/ossc/avconfig.c b/software/sys_controller/ossc/avconfig.c new file mode 100644 index 0000000..e85be9f --- /dev/null +++ b/software/sys_controller/ossc/avconfig.c @@ -0,0 +1,47 @@ +// +// Copyright (C) 2015-2016 Markus Hiienkari +// +// This file is part of Open Source Scan Converter project. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// + +#include +#include "avconfig.h" +#include "tvp7002.h" + +#define DEFAULT_PRE_COAST 1 +#define DEFAULT_POST_COAST 0 +#define DEFAULT_SAMPLER_PHASE 16 +#define DEFAULT_SYNC_VTH 11 + +// Target configuration +avconfig_t tc; + +// Default configuration +const avconfig_t tc_default = { + .sampler_phase = DEFAULT_SAMPLER_PHASE, + .sync_vth = DEFAULT_SYNC_VTH, + .vsync_thold = DEFAULT_VSYNC_THOLD, + .en_alc = 1, + .pre_coast = DEFAULT_PRE_COAST, + .post_coast = DEFAULT_POST_COAST, +}; + +int set_default_avconfig() +{ + memcpy(&tc, &tc_default, sizeof(avconfig_t)); + + return 0; +} diff --git a/software/sys_controller/ossc/avconfig.h b/software/sys_controller/ossc/avconfig.h new file mode 100644 index 0000000..9f4a0f3 --- /dev/null +++ b/software/sys_controller/ossc/avconfig.h @@ -0,0 +1,62 @@ +// +// Copyright (C) 2015-2016 Markus Hiienkari +// +// This file is part of Open Source Scan Converter project. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// + +#ifndef AVCONFIG_H_ +#define AVCONFIG_H_ + +#include "alt_types.h" + +#define SCANLINESTR_MAX 15 +#define HV_MASK_MAX 63 +#define VIDEO_LPF_MAX 5 +#define SAMPLER_PHASE_MAX 31 +#define SYNC_VTH_MAX 31 +#define VSYNC_THOLD_MIN 10 +#define VSYNC_THOLD_MAX 200 +#define PLL_COAST_MAX 5 + +#define SL_MODE_MAX 2 +#define SL_TYPE_MAX 1 +#define LM_MODE_MAX 1 + +typedef struct { + alt_u8 sl_mode; + alt_u8 sl_type; + alt_u8 sl_str; + alt_u8 sl_id; + alt_u8 linemult_target; + alt_u8 l3_mode; + alt_u8 h_mask; + alt_u8 v_mask; + alt_u8 tx_mode; + alt_u8 s480p_mode; + alt_u8 sampler_phase; + alt_u8 ypbpr_cs; + alt_u8 sync_vth; + alt_u8 vsync_thold; + alt_u8 sync_lpf; + alt_u8 video_lpf; + alt_u8 en_alc; + alt_u8 pre_coast; + alt_u8 post_coast; +} avconfig_t; + +int set_default_avconfig(); + +#endif diff --git a/software/sys_controller/ossc/controls.c b/software/sys_controller/ossc/controls.c new file mode 100644 index 0000000..8b5f95f --- /dev/null +++ b/software/sys_controller/ossc/controls.c @@ -0,0 +1,148 @@ +// +// Copyright (C) 2015-2016 Markus Hiienkari +// +// This file is part of Open Source Scan Converter project. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// + +#include +#include +#include "alt_types.h" +#include "sysconfig.h" +#include "controls.h" +#include "menu.h" +#include "av_controller.h" +#include "video_modes.h" +#include "lcd.h" +#include "altera_avalon_pio_regs.h" + +static const char *rc_keydesc[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "MENU", "OK", "BACK", "UP", "DOWN", "LEFT", "RIGHT", "INFO", "LCD_BACKLIGHT", "SCANLINE_MODE", "SCANLINE_TYPE", "SCANLINE_INT+", "SCANLINE_INT-", "LINEMULT_MODE"}; +alt_u16 rc_keymap[REMOTE_MAX_KEYS] = {0x3E29, 0x3EA9, 0x3E69, 0x3EE9, 0x3E19, 0x3E99, 0x3E59, 0x3ED9, 0x3E39, 0x3EC9, 0x3E4D, 0x3E1D, 0x3EED, 0x3E2D, 0x3ECD, 0x3EAD, 0x3E6D, 0x3E65, 0x3E01, 0x1C48, 0x1C18, 0x1C50, 0x1CD0, 0x1CC8}; + +extern char menu_row1[LCD_ROW_LEN+1], menu_row2[LCD_ROW_LEN+1]; +extern const mode_data_t video_modes[]; +extern avmode_t cm; +extern avconfig_t tc; +extern avinput_t target_mode; +extern alt_u8 menu_active; + +alt_u32 remote_code; +alt_u8 remote_rpt, remote_rpt_prev; +alt_u32 btn_code, btn_code_prev; + +void setup_rc() +{ + int i, confirm; + alt_u32 remote_code_prev = 0; + + for (i=0; i>16); + + for (i = RC_BTN1; i < REMOTE_MAX_KEYS; i++) { + if (remote_code == rc_keymap[i]) + break; + if (i == REMOTE_MAX_KEYS - 1) + goto Button_Check; + } + + switch (i) { + case RC_BTN1: target_mode = AV1_RGBs; break; + case RC_BTN4: target_mode = AV1_RGsB; break; + case RC_BTN7: target_mode = AV1_YPBPR; break; + case RC_BTN2: target_mode = AV2_YPBPR; break; + case RC_BTN5: target_mode = AV2_RGsB; break; + case RC_BTN3: target_mode = AV3_RGBHV; break; + case RC_BTN6: target_mode = AV3_RGBs; break; + case RC_BTN9: target_mode = AV3_RGsB; break; + case RC_BTN0: target_mode = AV3_YPBPR; break; + case RC_MENU: + menu_active = !menu_active; + + if (menu_active) + display_menu(1); + else + lcd_write_status(); + + break; + case RC_INFO: + sniprintf(menu_row1, LCD_ROW_LEN+1, "VMod: %s", video_modes[cm.id].name); + sniprintf(menu_row2, LCD_ROW_LEN+1, "LO: %u VSM: %u", IORD_ALTERA_AVALON_PIO_DATA(PIO_4_BASE) & 0xffff, (IORD_ALTERA_AVALON_PIO_DATA(PIO_4_BASE) >> 16) & 0x3); + lcd_write_menu(); + printf("Mod: %s\n", video_modes[cm.id].name); + printf("Lines: %u M: %u\n", IORD_ALTERA_AVALON_PIO_DATA(PIO_4_BASE) & 0xffff, cm.macrovis); + break; + case RC_LCDBL: + IOWR_ALTERA_AVALON_PIO_DATA(PIO_0_BASE, (IORD_ALTERA_AVALON_PIO_DATA(PIO_0_BASE) ^ (1<<1))); + 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_LM_MODE: tc.linemult_target = (tc.linemult_target < LM_MODE_MAX) ? (tc.linemult_target + 1) : 0; break; + default: break; + } + +Button_Check: + if (btn_code_prev == 0) { + if (btn_code & PB0_BIT) + target_mode = (cm.avinput == AV3_YPBPR) ? AV1_RGBs : (cm.avinput+1); + if (btn_code & PB1_BIT) + tc.sl_mode = tc.sl_mode < SL_MODE_MAX ? tc.sl_mode + 1 : 0; + } +} diff --git a/software/sys_controller/ossc/controls.h b/software/sys_controller/ossc/controls.h new file mode 100644 index 0000000..0516617 --- /dev/null +++ b/software/sys_controller/ossc/controls.h @@ -0,0 +1,60 @@ +// +// Copyright (C) 2015-2016 Markus Hiienkari +// +// This file is part of Open Source Scan Converter project. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// + +#ifndef CONTROLS_H_ +#define CONTROLS_H_ + +#define RC_MASK 0x0000ffff +#define PB_MASK 0x00030000 +#define PB0_BIT 0x00010000 +#define PB1_BIT 0x00020000 + +typedef enum { + RC_BTN1 = 0, + RC_BTN2, + RC_BTN3, + RC_BTN4, + RC_BTN5, + RC_BTN6, + RC_BTN7, + RC_BTN8, + RC_BTN9, + RC_BTN0, + RC_MENU, + RC_OK, + RC_BACK, + RC_UP, + RC_DOWN, + RC_LEFT, + RC_RIGHT, + RC_INFO, + RC_LCDBL, + RC_SL_MODE, + RC_SL_TYPE, + RC_SL_PLUS, + RC_SL_MINUS, + RC_LM_MODE, +} rc_code_t; + +#define REMOTE_MAX_KEYS RC_LM_MODE-RC_BTN1+1 + +void setup_rc(); +void parse_control(); + +#endif diff --git a/software/sys_controller/ossc/firmware.c b/software/sys_controller/ossc/firmware.c new file mode 100644 index 0000000..b56f073 --- /dev/null +++ b/software/sys_controller/ossc/firmware.c @@ -0,0 +1,202 @@ +// +// Copyright (C) 2015-2016 Markus Hiienkari +// +// This file is part of Open Source Scan Converter project. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// + +#include +#include +#include "firmware.h" +#include "sdcard.h" +#include "flash.h" +#include "sysconfig.h" +#include "controls.h" +#include "tvp7002.h" +#include "av_controller.h" +#include "lcd.h" +#include "ci_crc.h" +#include "altera_avalon_pio_regs.h" + +extern char menu_row1[LCD_ROW_LEN+1], menu_row2[LCD_ROW_LEN+1]; +extern alt_u16 rc_keymap[REMOTE_MAX_KEYS]; + +static int check_fw_header(alt_u8 *databuf, fw_hdr *hdr) +{ + alt_u32 crcval, tmp; + + strncpy(hdr->fw_key, (char*)databuf, 4); + if (strncmp(hdr->fw_key, "OSSC", 4)) { + sniprintf(menu_row1, LCD_ROW_LEN+1, "Invalid image"); + menu_row2[0] = '\0'; + return 1; + } + + hdr->version_major = databuf[4]; + hdr->version_minor = databuf[5]; + strncpy(hdr->version_suffix, (char*)(databuf+6), 8); + hdr->version_suffix[7] = 0; + + memcpy(&tmp, databuf+14, 4); + hdr->hdr_len = ALT_CI_NIOS_CUSTOM_INSTR_ENDIANCONVERTER_0(tmp); + memcpy(&tmp, databuf+18, 4); + hdr->data_len = ALT_CI_NIOS_CUSTOM_INSTR_ENDIANCONVERTER_0(tmp); + memcpy(&tmp, databuf+22, 4); + hdr->data_crc = ALT_CI_NIOS_CUSTOM_INSTR_ENDIANCONVERTER_0(tmp); + // Always at bytes [508-511] + memcpy(&tmp, databuf+508, 4); + hdr->hdr_crc = ALT_CI_NIOS_CUSTOM_INSTR_ENDIANCONVERTER_0(tmp); + + if (hdr->hdr_len < 26 || hdr->hdr_len > 508) { + sniprintf(menu_row1, LCD_ROW_LEN+1, "Invalid header"); + menu_row2[0] = '\0'; + return -1; + } + + crcval = crcCI(databuf, hdr->hdr_len, 1); + + if (crcval != hdr->hdr_crc) { + sniprintf(menu_row1, LCD_ROW_LEN+1, "Invalid hdr CRC"); + menu_row2[0] = '\0'; + return -2; + } + + return 0; +} + +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; + + for (i=0; i PAGESIZE) { + retval = write_flash_page(databuf+PAGESIZE, (bytes_to_rw-PAGESIZE), (i/PAGESIZE)+1); + if (retval != 0) + goto failure; + } + } + + strncpy(menu_row1, "Verifying flash", LCD_ROW_LEN+1); + strncpy(menu_row2, "please wait...", LCD_ROW_LEN+1); + lcd_write_menu(); + retval = verify_flash(0, fw_header.data_len, fw_header.data_crc, databuf); + if (retval != 0) + goto failure; + + return 0; + + +failure: + lcd_write_menu(); + usleep(1000000); + + // Probable rw error, retry update + if ((retval <= -200) && (retries > 0)) { + sniprintf(menu_row1, LCD_ROW_LEN+1, "Retrying update"); + retries--; + goto update_init; + } + + return -1; +} +#endif diff --git a/software/sys_controller/ossc/firmware.h b/software/sys_controller/ossc/firmware.h new file mode 100644 index 0000000..5721947 --- /dev/null +++ b/software/sys_controller/ossc/firmware.h @@ -0,0 +1,43 @@ +// +// Copyright (C) 2015-2016 Markus Hiienkari +// +// This file is part of Open Source Scan Converter project. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// + +#ifndef FIRMWARE_H_ +#define FIRMWARE_H_ + +#include "alt_types.h" + +#define FW_VER_MAJOR 0 +#define FW_VER_MINOR 70 + +#define FW_UPDATE_RETRIES 3 + +typedef struct { + char fw_key[4]; + alt_u8 version_major; + alt_u8 version_minor; + char version_suffix[8]; + alt_u32 hdr_len; + alt_u32 data_len; + alt_u32 data_crc; + alt_u32 hdr_crc; +} fw_hdr; + +int fw_update(); + +#endif diff --git a/software/sys_controller/ossc/menu.c b/software/sys_controller/ossc/menu.c index 766a2af..b759385 100644 --- a/software/sys_controller/ossc/menu.c +++ b/software/sys_controller/ossc/menu.c @@ -19,18 +19,20 @@ #include #include "menu.h" +#include "av_controller.h" +#include "controls.h" #include "lcd.h" #include "tvp7002.h" +#define OPT_NOWRAP 0 +#define OPT_WRAP 1 + extern char row1[LCD_ROW_LEN+1], row2[LCD_ROW_LEN+1], menu_row1[LCD_ROW_LEN+1], menu_row2[LCD_ROW_LEN+1]; extern avconfig_t tc; extern alt_u32 remote_code; -extern alt_u8 menu_active; +extern alt_u16 rc_keymap[REMOTE_MAX_KEYS]; -//TODO: move to separate source file(s) -extern alt_u16 rc_keymap[22]; -#define lcd_write_menu() lcd_write((char*)&menu_row1, (char*)&menu_row2) -#define lcd_write_status() lcd_write((char*)&row1, (char*)&row2) +alt_u8 menu_active; static const char *off_on_desc[] = { "Off", "On" }; static const char *video_lpf_desc[] = { "Auto", "Off", "95MHz (HDTV II)", "35MHz (HDTV I)", "16MHz (EDTV)", "9MHz (SDTV)" }; @@ -39,7 +41,8 @@ static const char *s480p_mode_desc[] = { "Auto", "DTV 480p", "VGA 640x480" }; static const char *sync_lpf_desc[] = { "Off", "33MHz (min)", "10MHz (med)", "2.5MHz (max)" }; static const char *l3_mode_desc[] = { "Generic 16:9", "Generic 4:3", "320x240 optim.", "256x240 optim." }; static const char *tx_mode_desc[] = { "HDMI", "DVI" }; -static const char *sl_mode_desc[] = { "Off", "Horizontal", "Vertical" }; +static const char *sl_mode_desc[] = { "Off", "Auto", "Manual" }; +static const char *sl_type_desc[] = { "Horizontal", "Vertical" }; static const char *sl_id_desc[] = { "Even", "Odd" }; static void sampler_phase_disp(alt_u8 v) { sniprintf(menu_row2, LCD_ROW_LEN+1, "%d deg", (v*1125)/100); } @@ -50,49 +53,50 @@ static void lines_disp(alt_u8 v) { sniprintf(menu_row2, LCD_ROW_LEN+1, "%u lines static void pixels_disp(alt_u8 v) { sniprintf(menu_row2, LCD_ROW_LEN+1, "%u pixels", v); } MENU(menu_vinputproc, P99_PROTECT({ \ - { "Video LPF", OPT_AVCONFIG_SELECTION, { .sel = { &tc.video_lpf, SETTING_ITEM(video_lpf_desc) } } }, - { "YPbPr in ColSpa", OPT_AVCONFIG_SELECTION, { .sel = { &tc.ypbpr_cs, SETTING_ITEM(ypbpr_cs_desc) } } }, - { "Auto lev. ctrl", OPT_AVCONFIG_SELECTION, { .sel = { &tc.en_alc, SETTING_ITEM(off_on_desc) } } }, + { "Video LPF", OPT_AVCONFIG_SELECTION, { .sel = { &tc.video_lpf, OPT_WRAP, SETTING_ITEM(video_lpf_desc) } } }, + { "YPbPr in ColSpa", OPT_AVCONFIG_SELECTION, { .sel = { &tc.ypbpr_cs, OPT_WRAP, SETTING_ITEM(ypbpr_cs_desc) } } }, + { "Auto lev. ctrl", OPT_AVCONFIG_SELECTION, { .sel = { &tc.en_alc, OPT_WRAP, SETTING_ITEM(off_on_desc) } } }, })) MENU(menu_sampling, P99_PROTECT({ \ - { "Sampling phase", OPT_AVCONFIG_NUMVALUE, { .num = { &tc.sampler_phase, 0, 31, sampler_phase_disp } } }, - { "480p in sampler", OPT_AVCONFIG_SELECTION, { .sel = { &tc.s480p_mode, SETTING_ITEM(s480p_mode_desc) } } }, + { "Sampling phase", OPT_AVCONFIG_NUMVALUE, { .num = { &tc.sampler_phase, OPT_NOWRAP, 0, SAMPLER_PHASE_MAX, sampler_phase_disp } } }, + { "480p in sampler", OPT_AVCONFIG_SELECTION, { .sel = { &tc.s480p_mode, OPT_WRAP, SETTING_ITEM(s480p_mode_desc) } } }, //{ "Modeparam editor", OPT_SUBMENU, { .sub = NULL } }, })) MENU(menu_sync, P99_PROTECT({ \ - { "Analog sync LPF", OPT_AVCONFIG_SELECTION, { .sel = { &tc.sync_lpf, SETTING_ITEM(sync_lpf_desc) } } }, - { "Analog sync Vth", OPT_AVCONFIG_NUMVALUE, { .num = { &tc.sync_vth, 0, 31, sync_vth_disp } } }, - { "Vsync threshold", OPT_AVCONFIG_NUMVALUE, { .num = { &tc.vsync_thold, 10, 200, vsync_thold_disp } } }, - { "H-PLL Pre-Coast", OPT_AVCONFIG_NUMVALUE, { .num = { &tc.pre_coast, 0, 5, lines_disp } } }, - { "H-PLL Post-Coast", OPT_AVCONFIG_NUMVALUE, { .num = { &tc.post_coast, 0, 5, lines_disp } } }, + { "Analog sync LPF", OPT_AVCONFIG_SELECTION, { .sel = { &tc.sync_lpf, OPT_WRAP, SETTING_ITEM(sync_lpf_desc) } } }, + { "Analog sync Vth", OPT_AVCONFIG_NUMVALUE, { .num = { &tc.sync_vth, OPT_NOWRAP, 0, SYNC_VTH_MAX, sync_vth_disp } } }, + { "Vsync threshold", OPT_AVCONFIG_NUMVALUE, { .num = { &tc.vsync_thold, OPT_NOWRAP, VSYNC_THOLD_MIN, VSYNC_THOLD_MAX, vsync_thold_disp } } }, + { "H-PLL Pre-Coast", OPT_AVCONFIG_NUMVALUE, { .num = { &tc.pre_coast, OPT_NOWRAP, 0, PLL_COAST_MAX, lines_disp } } }, + { "H-PLL Post-Coast", OPT_AVCONFIG_NUMVALUE, { .num = { &tc.post_coast, OPT_NOWRAP, 0, PLL_COAST_MAX, lines_disp } } }, })) MENU(menu_output, P99_PROTECT({ \ - { "240p/288p lineX3", OPT_AVCONFIG_SELECTION, { .sel = { &tc.linemult_target, SETTING_ITEM(off_on_desc) } } }, - { "Linetriple mode", OPT_AVCONFIG_SELECTION, { .sel = { &tc.l3_mode, SETTING_ITEM(l3_mode_desc) } } }, + { "240p/288p lineX3", OPT_AVCONFIG_SELECTION, { .sel = { &tc.linemult_target, OPT_WRAP, SETTING_ITEM(off_on_desc) } } }, + { "Linetriple mode", OPT_AVCONFIG_SELECTION, { .sel = { &tc.l3_mode, OPT_WRAP, SETTING_ITEM(l3_mode_desc) } } }, //{ "Interlace passt.", OPT_AVCONFIG_SELECTION, { .sel = { &tc.s480p_mode, SETTING_ITEM(s480p_desc) } } }, - { "TX mode", OPT_AVCONFIG_SELECTION, { .sel = { &tc.tx_mode, SETTING_ITEM(tx_mode_desc) } } }, + { "TX mode", OPT_AVCONFIG_SELECTION, { .sel = { &tc.tx_mode, OPT_WRAP, SETTING_ITEM(tx_mode_desc) } } }, })) MENU(menu_postproc, P99_PROTECT({ \ - { "Scanlines", OPT_AVCONFIG_SELECTION, { .sel = { &tc.sl_mode, SETTING_ITEM(sl_mode_desc) } } }, - { "Scanline str.", OPT_AVCONFIG_NUMVALUE, { .num = { &tc.sl_str, 0, 15, sl_str_disp } } }, - { "Scanline id.", OPT_AVCONFIG_SELECTION, { .sel = { &tc.sl_id, SETTING_ITEM(sl_id_desc) } } }, - { "Horizontal mask", OPT_AVCONFIG_NUMVALUE, { .num = { &tc.h_mask, 0, 63, pixels_disp } } }, - { "Vertical mask", OPT_AVCONFIG_NUMVALUE, { .num = { &tc.v_mask, 0, 63, pixels_disp } } }, + { "Scanlines", OPT_AVCONFIG_SELECTION, { .sel = { &tc.sl_mode, OPT_WRAP, SETTING_ITEM(sl_mode_desc) } } }, + { "Scanline str.", OPT_AVCONFIG_NUMVALUE, { .num = { &tc.sl_str, OPT_NOWRAP, 0, SCANLINESTR_MAX, sl_str_disp } } }, + { "Scanline type", OPT_AVCONFIG_SELECTION, { .sel = { &tc.sl_type, OPT_WRAP, SETTING_ITEM(sl_type_desc) } } }, + { "Scanline id.", OPT_AVCONFIG_SELECTION, { .sel = { &tc.sl_id, OPT_WRAP, SETTING_ITEM(sl_id_desc) } } }, + { "Horizontal mask", OPT_AVCONFIG_NUMVALUE, { .num = { &tc.h_mask, OPT_NOWRAP, 0, HV_MASK_MAX, pixels_disp } } }, + { "Vertical mask", OPT_AVCONFIG_NUMVALUE, { .num = { &tc.v_mask, OPT_NOWRAP, 0, HV_MASK_MAX, pixels_disp } } }, })) MENU(menu_main, P99_PROTECT({ \ - { "Video in proc", OPT_SUBMENU, { .sub = &menu_vinputproc } }, \ - { "Sampling opt.", OPT_SUBMENU, { .sub = &menu_sampling } }, \ - { "Sync opt.", OPT_SUBMENU, { .sub = &menu_sync } }, \ - { "Output opt.", OPT_SUBMENU, { .sub = &menu_output } }, \ - { "Post-proc.", OPT_SUBMENU, { .sub = &menu_postproc } }, \ - { "Fw. update", OPT_FUNC_CALL, { .fun = { fw_update, "OK - pls restart" } } }, \ - { "Reset settings", OPT_FUNC_CALL, { .fun = { set_default_avconfig, "Reset done" } } }, \ - { "Save settings", OPT_FUNC_CALL, { .fun = { write_userdata, "Saved" } } }, \ + { "Video in proc >", OPT_SUBMENU, { .sub = &menu_vinputproc } }, \ + { "Sampling opt. >", OPT_SUBMENU, { .sub = &menu_sampling } }, \ + { "Sync opt. >", OPT_SUBMENU, { .sub = &menu_sync } }, \ + { "Output opt. >", OPT_SUBMENU, { .sub = &menu_output } }, \ + { "Post-proc. >", OPT_SUBMENU, { .sub = &menu_postproc } }, \ + { "Fw. update >", OPT_FUNC_CALL, { .fun = { fw_update, "OK - pls restart" } } }, \ + { "", OPT_FUNC_CALL, { .fun = { set_default_avconfig, "Reset done" } } }, \ + { "", OPT_FUNC_CALL, { .fun = { write_userdata, "Saved" } } }, \ })) // Max 2 levels currently @@ -102,27 +106,23 @@ alt_u8 navlvl = 0; void display_menu(alt_u8 forcedisp) { - menucode_id code; - int retval = 0; + menucode_id code = NO_ACTION; + menuitem_type type; + alt_u8 *val, val_wrap, val_min, val_max; + int i, retval = 0; - if (remote_code == rc_keymap[RC_UP]) - code = PREV_PAGE; - else if (remote_code == rc_keymap[RC_DOWN]) - code = NEXT_PAGE; - else if (remote_code == rc_keymap[RC_RIGHT]) - code = VAL_PLUS; - else if (remote_code == rc_keymap[RC_LEFT]) - code = VAL_MINUS; - else if (remote_code == rc_keymap[RC_OK]) - code = OPT_SELECT; - else if (remote_code == rc_keymap[RC_BACK]) - code = PREV_MENU; - else - code = NO_ACTION; + for (i=RC_OK; i < RC_INFO; i++) { + if (remote_code == rc_keymap[i]) { + code = i; + break; + } + } if (!forcedisp && (code == NO_ACTION)) return; + type = navi[navlvl].m->items[navi[navlvl].mp].type; + // Parse menu control switch (code) { case PREV_PAGE: @@ -156,31 +156,17 @@ void display_menu(alt_u8 forcedisp) } break; case VAL_MINUS: - switch (navi[navlvl].m->items[navi[navlvl].mp].type) { - case OPT_AVCONFIG_SELECTION: - if (*(navi[navlvl].m->items[navi[navlvl].mp].sel.data) > 0) - *(navi[navlvl].m->items[navi[navlvl].mp].sel.data) = *(navi[navlvl].m->items[navi[navlvl].mp].sel.data) - 1; - break; - case OPT_AVCONFIG_NUMVALUE: - if (*(navi[navlvl].m->items[navi[navlvl].mp].num.data) > navi[navlvl].m->items[navi[navlvl].mp].num.min) - *(navi[navlvl].m->items[navi[navlvl].mp].num.data) = *(navi[navlvl].m->items[navi[navlvl].mp].num.data) - 1; - break; - default: - break; - } - break; case VAL_PLUS: - switch (navi[navlvl].m->items[navi[navlvl].mp].type) { - case OPT_AVCONFIG_SELECTION: - if (*(navi[navlvl].m->items[navi[navlvl].mp].sel.data) < navi[navlvl].m->items[navi[navlvl].mp].sel.num_settings-1) - *(navi[navlvl].m->items[navi[navlvl].mp].sel.data) = *(navi[navlvl].m->items[navi[navlvl].mp].sel.data) + 1; - break; - case OPT_AVCONFIG_NUMVALUE: - if (*(navi[navlvl].m->items[navi[navlvl].mp].num.data) < navi[navlvl].m->items[navi[navlvl].mp].num.max) - *(navi[navlvl].m->items[navi[navlvl].mp].num.data) = *(navi[navlvl].m->items[navi[navlvl].mp].num.data) + 1; - break; - default: - break; + if ((type == OPT_AVCONFIG_SELECTION) || (type == 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; + + if (code == VAL_MINUS) + *val = (*val > val_min) ? (*val-1) : (val_wrap ? val_max : val_min); + else + *val = (*val < val_max) ? (*val+1) : (val_wrap ? val_min : val_max); } break; default: @@ -188,21 +174,19 @@ 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_row1, navi[navlvl].m->items[navi[navlvl].mp].name, LCD_ROW_LEN+1); 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: - strncpy(menu_row1, navi[navlvl].m->items[navi[navlvl].mp].name, LCD_ROW_LEN+1); navi[navlvl].m->items[navi[navlvl].mp].num.f(*(navi[navlvl].m->items[navi[navlvl].mp].num.data)); break; case OPT_SUBMENU: - sniprintf(menu_row1, LCD_ROW_LEN+1, "%s >", navi[navlvl].m->items[navi[navlvl].mp].name); menu_row2[0] = 0; break; case OPT_FUNC_CALL: - sniprintf(menu_row1, LCD_ROW_LEN+1, "<%s>", navi[navlvl].m->items[navi[navlvl].mp].name); if (code == OPT_SELECT) sniprintf(menu_row2, LCD_ROW_LEN+1, "%s", (retval==0) ? navi[navlvl].m->items[navi[navlvl].mp].fun.text_success : "Error"); else diff --git a/software/sys_controller/ossc/menu.h b/software/sys_controller/ossc/menu.h index 7080e80..dcb5081 100644 --- a/software/sys_controller/ossc/menu.h +++ b/software/sys_controller/ossc/menu.h @@ -17,11 +17,12 @@ // along with this program. If not, see . // -#include "alt_types.h" - #ifndef MENU_H_ #define MENU_H_ +#include "alt_types.h" +#include "controls.h" + typedef enum { OPT_AVCONFIG_SELECTION, OPT_AVCONFIG_NUMVALUE, @@ -35,12 +36,15 @@ typedef void (*disp_func)(alt_u8); typedef struct { alt_u8 *data; - alt_u8 num_settings; + alt_u8 wrap_cfg; + alt_u8 min; + alt_u8 max; const char **setting_str; } opt_avconfig_selection; typedef struct { alt_u8 *data; + alt_u8 wrap_cfg; alt_u8 min; alt_u8 max; disp_func f; @@ -73,81 +77,30 @@ typedef struct { menu_t *menu; } opt_submenu; -#define SETTING_ITEM(x) sizeof(x)/sizeof(char*), x +#define SETTING_ITEM(x) 0, sizeof(x)/sizeof(char*)-1, x #define MENU(X, Y) menuitem_t X##_items[] = Y; const menu_t X = { sizeof(X##_items)/sizeof(menuitem_t), X##_items }; #define P99_PROTECT(...) __VA_ARGS__ -#define MAX_MENU_LEVELS 4 - typedef enum { - NO_ACTION = 0, - NEXT_PAGE = 1, - PREV_PAGE = 2, - VAL_PLUS = 3, - VAL_MINUS = 4, - OPT_SELECT = 5, - PREV_MENU = 6, -} menucode_id; + NO_ACTION = 0, + OPT_SELECT = RC_OK, + PREV_MENU = RC_BACK, + PREV_PAGE = RC_UP, + NEXT_PAGE = RC_DOWN, + VAL_MINUS = RC_LEFT, + VAL_PLUS = RC_RIGHT, +} menucode_id; // order must be consequential with rc_code_t typedef struct { const menu_t *m; alt_u8 mp; } menunavi; +void display_menu(alt_u8 forcedisp); + //TODO: move all below to separate header(s) - -#define SCANLINESTR_MAX 15 -#define VIDEO_LPF_MAX 5 - -typedef struct { - alt_u8 sl_mode; - alt_u8 sl_str; - alt_u8 sl_id; - alt_u8 linemult_target; - alt_u8 l3_mode; - alt_u8 h_mask; - alt_u8 v_mask; - alt_u8 tx_mode; - alt_u8 s480p_mode; - alt_u8 sampler_phase; - alt_u8 ypbpr_cs; - alt_u8 sync_vth; - alt_u8 vsync_thold; - alt_u8 sync_lpf; - alt_u8 video_lpf; - alt_u8 en_alc; - alt_u8 pre_coast; - alt_u8 post_coast; -} avconfig_t; - -typedef enum { - RC_BTN1 = 0, - RC_BTN2, - RC_BTN3, - RC_BTN4, - RC_BTN5, - RC_BTN6, - RC_BTN7, - RC_BTN8, - RC_BTN9, - RC_BTN0, - RC_MENU, - RC_OK, - RC_BACK, - RC_UP, - RC_DOWN, - RC_LEFT, - RC_RIGHT, - RC_INFO, - RC_LCDBL, - RC_SL_TGL, - RC_SL_PLUS, - RC_SL_MINUS, -} rc_code_t; - int write_userdata(); int fw_update(); -int set_default_avconfig(); #endif diff --git a/software/sys_controller/ossc/sysconfig.h b/software/sys_controller/ossc/sysconfig.h index 64add6a..5915462 100644 --- a/software/sys_controller/ossc/sysconfig.h +++ b/software/sys_controller/ossc/sysconfig.h @@ -31,4 +31,6 @@ //#define printf alt_printf #endif +#define WAITLOOP_SLEEP_US 10000 + #endif /* SYSCONFIG_H_ */ diff --git a/software/sys_controller/ossc/userdata.c b/software/sys_controller/ossc/userdata.c new file mode 100644 index 0000000..04bf5e1 --- /dev/null +++ b/software/sys_controller/ossc/userdata.c @@ -0,0 +1,131 @@ +// +// Copyright (C) 2015-2016 Markus Hiienkari +// +// This file is part of Open Source Scan Converter project. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// + +#include +#include "userdata.h" +#include "sysconfig.h" +#include "flash.h" +#include "firmware.h" +#include "controls.h" +#include "av_controller.h" + +extern alt_u16 rc_keymap[REMOTE_MAX_KEYS]; +extern avconfig_t tc; + +int write_userdata() +{ + alt_u8 databuf[PAGESIZE]; + int retval; + + strncpy((char*)databuf, "USRDATA", 8); + databuf[8] = FW_VER_MAJOR; + databuf[9] = FW_VER_MINOR; + databuf[10] = 2; + + retval = write_flash_page(databuf, USERDATA_HDR_SIZE, (USERDATA_OFFSET/PAGESIZE)); + if (retval != 0) { + return -1; + } + + databuf[0] = UDE_REMOTE_MAP; + databuf[1] = 4+sizeof(rc_keymap); + databuf[2] = databuf[3] = 0; //padding + memcpy(databuf+4, rc_keymap, sizeof(rc_keymap)); + + retval = write_flash_page(databuf, databuf[1], (USERDATA_OFFSET/PAGESIZE)+1); + if (retval != 0) { + return -1; + } + + databuf[0] = UDE_AVCONFIG; + databuf[1] = 4+sizeof(avconfig_t); + databuf[2] = databuf[3] = 0; //padding + memcpy(databuf+4, &tc, sizeof(avconfig_t)); + + retval = write_flash_page(databuf, databuf[1], (USERDATA_OFFSET/PAGESIZE)+2); + if (retval != 0) { + return -1; + } + + return 0; +} + +int read_userdata() +{ + int retval, i; + alt_u8 databuf[PAGESIZE]; + userdata_hdr udhdr; + userdata_entry udentry; + + retval = read_flash(USERDATA_OFFSET, USERDATA_HDR_SIZE, databuf); + if (retval != 0) { + printf("Flash read error\n"); + return -1; + } + + strncpy(udhdr.userdata_key, (char*)databuf, 8); + if (strncmp(udhdr.userdata_key, "USRDATA", 8)) { + printf("No userdata found on flash\n"); + return 1; + } + + udhdr.version_major = databuf[8]; + udhdr.version_minor = databuf[9]; + udhdr.num_entries = databuf[10]; + + //TODO: check version compatibility + printf("Userdata: v%u.%.2u, %u entries\n", udhdr.version_major, udhdr.version_minor, udhdr.num_entries); + + for (i=0; i +// +// This file is part of Open Source Scan Converter project. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// + +#ifndef USERDATA_H_ +#define USERDATA_H_ + +#include "alt_types.h" + +#define USERDATA_HDR_SIZE 11 +typedef struct { + char userdata_key[8]; + alt_u8 version_major; + alt_u8 version_minor; + alt_u8 num_entries; +} userdata_hdr; + +#define USERDATA_ENTRY_HDR_SIZE 2 +typedef struct { + alt_u8 type; + alt_u8 entry_len; +} userdata_entry; + +typedef enum { + UDE_REMOTE_MAP = 0, + UDE_AVCONFIG, +} userdata_entry_type; + +#endif + +int write_userdata(); +int read_userdata(); diff --git a/software/sys_controller/spi_charlcd/lcd.c b/software/sys_controller/spi_charlcd/lcd.c index db203de..7ba12ee 100644 --- a/software/sys_controller/spi_charlcd/lcd.c +++ b/software/sys_controller/spi_charlcd/lcd.c @@ -17,9 +17,12 @@ // along with this program. If not, see . // +#include +#include #include "lcd.h" #include "alt_types.h" #include "altera_avalon_pio_regs.h" +#include "i2c_opencores.h" #define LCD_CMD 0x00 #define LCD_DATA 0x40 diff --git a/software/sys_controller/tvp7002/tvp7002.c b/software/sys_controller/tvp7002/tvp7002.c index 7e97e6a..82cdf8b 100755 --- a/software/sys_controller/tvp7002/tvp7002.c +++ b/software/sys_controller/tvp7002/tvp7002.c @@ -241,7 +241,7 @@ void tvp_sel_clk(alt_u8 refclk) } } -void tvp_sel_csc(ypbpr_to_rgb_csc_t *csc) +void tvp_sel_csc(const ypbpr_to_rgb_csc_t *csc) { tvp_writereg(TVP_CSC1HI, (csc->G_Y >> 8)); tvp_writereg(TVP_CSC1LO, (csc->G_Y & 0xff)); diff --git a/software/sys_controller/tvp7002/tvp7002.h b/software/sys_controller/tvp7002/tvp7002.h index 1261313..24e25e4 100755 --- a/software/sys_controller/tvp7002/tvp7002.h +++ b/software/sys_controller/tvp7002/tvp7002.h @@ -79,7 +79,7 @@ void tvp_setup_hpll(alt_u16 h_samplerate, alt_u16 v_lines, alt_u8 hz, alt_u8 pll void tvp_sel_clk(alt_u8 refclk); -void tvp_sel_csc(ypbpr_to_rgb_csc_t *csc); +void tvp_sel_csc(const ypbpr_to_rgb_csc_t *csc); void tvp_set_lpf(alt_u8 val);