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);