diff --git a/Source code/Embedded/HMD-MCU.cproj b/Source code/Embedded/HMD-MCU.cproj index 1fee3fa..8e97a94 100644 --- a/Source code/Embedded/HMD-MCU.cproj +++ b/Source code/Embedded/HMD-MCU.cproj @@ -708,6 +708,142 @@ .elf + + + -mmcu=atxmega256a3bu -B "%24(PackRepoDir)\atmel\XMEGAA_DFP\1.0.39\gcc\dev\atxmega256a3bu" + True + True + True + True + False + True + + + CONFIG_NVM_IGNORE_XMEGA_A3_D3_REVB_ERRATA + IOPORT_XMEGA_COMPAT + DEBUG + BOARD=USER_BOARD + + + + + ../src/Variants/HDK_20 + ../src/ASF/xmega/boards/xmega_a3bu_xplained + ../src + ../src/config + ../src/ASF/xmega/boards + ../src/ASF/common/boards + ../src/ASF/xmega/drivers/cpu + ../src/ASF/xmega/drivers/nvm + ../src/ASF/xmega/drivers/pmic + ../src/ASF/xmega/drivers/sleep + ../src/ASF/xmega/drivers/spi + ../src/ASF/common/services/clock + ../src/ASF/common/services/delay + ../src/ASF/common/services/gpio + ../src/ASF/common/services/ioport + ../src/ASF/common/services/sleepmgr + ../src/ASF/common/services/spi/xmega_spi + ../src/ASF/common/services/spi + ../src/ASF/common/services/twi + ../src/ASF/common/services/usb + ../src/ASF/common/services/usb/class/cdc + ../src/ASF/common/services/usb/class/cdc/device + ../src/ASF/common/services/usb/udc + ../src/ASF/common/utils + ../src/ASF/xmega/drivers/twi + ../src/ASF/xmega/drivers/usart + ../src/ASF/xmega/drivers/usb + ../src/ASF/xmega/utils/preprocessor + ../src/ASF/xmega/utils + ../src/ASF/common/services/serial/xmega_usart + ../src/ASF/common/services/serial + ../src/ASF/xmega/drivers/rtc + ../src/ASF/xmega/drivers/tc + ../src/ASF/xmega/services/pwm + ../src/ASF/xmega/drivers/rtc32 + ../src/ASF/xmega/services/timeout + ../src/ASF/common/services/usb/class/composite/device + ../src/ASF/common/services/usb/class/hid + ../src/ASF/common/services/usb/class/hid/device + ../src/ASF/common/services/usb/class/hid/device/generic + ../src/DeviceDrivers/bno-hostif/src + ../vendor/libhdk20 + %24(PackRepoDir)\atmel\XMEGAA_DFP\1.0.39\include + + + Optimize most (-O3) + True + True + Maximum (-g3) + True + -std=gnu99 -fno-strict-aliasing -Wstrict-prototypes -Wmissing-prototypes -Werror-implicit-function-declaration -Wpointer-arith -mrelax + + + libm + libhdk20.1.01 + + + + + ../vendor/libhdk20 + + + -Wl,--relax -Wl,--section-start=.BOOT=0x40000 + -mrelax -DBOARD=USER_BOARD -DCONFIG_NVM_IGNORE_XMEGA_A3_D3_REVB_ERRATA -DIOPORT_XMEGA_COMPAT + + + ../src/Variants/HDK_OLED + ../src/ASF/xmega/boards/xmega_a3bu_xplained + ../src + ../src/config + ../src/ASF/xmega/boards + ../src/ASF/common/boards + ../src/ASF/xmega/drivers/cpu + ../src/ASF/xmega/drivers/nvm + ../src/ASF/xmega/drivers/pmic + ../src/ASF/xmega/drivers/sleep + ../src/ASF/xmega/drivers/spi + ../src/ASF/common/services/clock + ../src/ASF/common/services/delay + ../src/ASF/common/services/gpio + ../src/ASF/common/services/ioport + ../src/ASF/common/services/sleepmgr + ../src/ASF/common/services/spi/xmega_spi + ../src/ASF/common/services/spi + ../src/ASF/common/services/twi + ../src/ASF/common/services/usb + ../src/ASF/common/services/usb/class/cdc + ../src/ASF/common/services/usb/class/cdc/device + ../src/ASF/common/services/usb/udc + ../src/ASF/common/utils + ../src/ASF/xmega/drivers/twi + ../src/ASF/xmega/drivers/usart + ../src/ASF/xmega/drivers/usb + ../src/ASF/xmega/utils/preprocessor + ../src/ASF/xmega/utils + ../src/ASF/common/services/serial/xmega_usart + ../src/ASF/common/services/serial + ../src/ASF/xmega/drivers/rtc + ../src/ASF/xmega/drivers/tc + ../src/ASF/xmega/services/pwm + ../src/ASF/xmega/drivers/rtc32 + ../src/ASF/xmega/services/timeout + ../src/ASF/common/services/usb/class/composite/device + ../src/ASF/common/services/usb/class/hid + ../src/ASF/common/services/usb/class/hid/device + ../src/ASF/common/services/usb/class/hid/device/generic + %24(PackRepoDir)\atmel\XMEGAA_DFP\1.0.39\include + + + Default (-Wa,-g) + + + HDK-20-HMD-MCU + .elf + bin\HDK_20\ + + -mmcu=atxmega256a3bu -B "%24(PackRepoDir)\atmel\XMEGAA_DFP\1.0.39\gcc\dev\atxmega256a3bu" @@ -727,7 +863,7 @@ - ../src/Variants/HDK_20 + ../src/Variants/HDK_20_SVR ../src/ASF/xmega/boards/xmega_a3bu_xplained ../src ../src/config @@ -781,7 +917,7 @@ libm - libhdk20.1.01 + libhdk20.1.01.svr1020 @@ -839,9 +975,9 @@ Default (-Wa,-g) - HDK-20-HMD-MCU + HDK-20-SVR-HMD-MCU .elf - bin\HDK_20\ + bin\HDK_20_SVR\ @@ -912,6 +1048,7 @@ + @@ -1084,6 +1221,12 @@ compile + + compile + + + compile + compile diff --git a/Source code/Embedded/src/Console.c b/Source code/Embedded/src/Console.c index 2573cc6..96201bd 100644 --- a/Source code/Embedded/src/Console.c +++ b/Source code/Embedded/src/Console.c @@ -7,6 +7,7 @@ */ #include "Console.h" +#include "USB.h" // asf headers #include @@ -21,6 +22,11 @@ uint8_t DebugLevel = 0xff; // start by opening all debug messages int MaxTimerCounter = 0; void Write(const char *const Data) { + if (!usb_cdc_is_active()) + { + // Early out if no USB CDC. + return; + } if (!Data) { // Given a null pointer - that's not very polite. diff --git a/Source code/Embedded/src/DeviceDrivers/Display_DualAUO_TC358870.c b/Source code/Embedded/src/DeviceDrivers/Display_DualAUO_TC358870.c index 5ce6964..3284f3e 100644 --- a/Source code/Embedded/src/DeviceDrivers/Display_DualAUO_TC358870.c +++ b/Source code/Embedded/src/DeviceDrivers/Display_DualAUO_TC358870.c @@ -8,41 +8,94 @@ #include "GlobalOptions.h" #if defined(SVR_IS_HDK_20) +#include "my_hardware.h" + #include "Display.h" #include "Console.h" #include "SvrYield.h" +#include #include "DeviceDrivers/Toshiba_TC358870.h" #include -static void tc358870_mystery_setup_commands(); -inline static void tc358870_mystery_setup_commands() +// whether to send the sleep in/out and display on/off commands with a parameter of 0x00, or with no parameter. Appears +// to work both ways, docs are contradictory: AUO app note says use a parameter, standard says don't +#undef SLEEP_HAS_NULL_PARAMETER +static void AUO_Null_Param_DSI_Cmd(uint8_t cmd); + +static void AUO_H381DLN01_Send_Panel_Init_Commands(void); +static void AUO_H381DLN01_Panel_Reset(void); + +typedef struct CommandSequenceElt +{ + uint8_t addr; + uint8_t param; +} CommandSequenceElt_t; + +static const CommandSequenceElt_t AUO_H381DLN01_Init_Commands[] = { + {0xFE, 0x07}, {0x00, 0xEC}, {0x0B, 0xEC}, {0x16, 0xEC}, {0x21, 0xEC}, {0x2D, 0xEC}, {0xA9, 0xBA}, {0xAB, 0x06}, + {0xBB, 0x84}, {0xBC, 0x1C}, {0xFE, 0x08}, {0x07, 0x1A}, {0xFE, 0x0A}, {0x2A, 0x1B}, {0xFE, 0x0D}, {0x02, 0x65}, + {0x4D, 0x41}, {0x4B, 0x0F}, {0x53, 0xFE}, {0xFE, 0x00}, {0xC2, 0x03}, {0x51, 0xFF}}; + +inline static void AUO_H381DLN01_Send_Panel_Init_Commands() +{ + /// Run all display setup commands for these panels from the app note. + unsigned int numCommands = sizeof(AUO_H381DLN01_Init_Commands) / sizeof(AUO_H381DLN01_Init_Commands[0]); + for (unsigned int i = 0; i < numCommands; ++i) + { + Toshiba_TC358870_DSI_Write_Cmd_Short_Param(AUO_H381DLN01_Init_Commands[i].addr, + AUO_H381DLN01_Init_Commands[i].param); + svr_yield_ms(16); + } +} + +inline static void AUO_H381DLN01_Panel_Reset() { - /// This code was originally in "write_solomon()" in the Coretronic fork of the firmware. It would have gotten - /// triggered once: during init_solomon_device, the call to read_solomon_id starts with a write_solomon (which would - /// call this). The subsequent read was replaced with a dummy function returning 0, so the init_solomon_device would - /// always fail out at that point (not receiving the ID it expected), but these two writes would have taken place. - /// @todo why was this implementation included? what does it do? - TC358870_i2c_Write(0x0504, 0x0015, 2); - TC358870_i2c_Write(0x0504, 0x07FE, 2); + ioport_set_pin_low(PANEL_RESET); + // >3ms recommended to move from deep standby to sleep state. + svr_yield_ms(10); + ioport_set_pin_high(PANEL_RESET); + // Reset after this signal takes at most 5ms during sleep mode, 120ms during non-sleep mode (and can't "sleep out" + // for 120ms) + svr_yield_ms(120); +} + +inline static void AUO_Null_Param_DSI_Cmd(uint8_t cmd) +{ +#ifdef SLEEP_HAS_NULL_PARAMETER + Toshiba_TC358870_DSI_Write_Cmd_Short_Param(cmd, 0x00); +#else + Toshiba_TC358870_DSI_Write_Cmd_Short(cmd); +#endif } void Display_System_Init() { Toshiba_TC358870_Init(); } -void Display_Init(uint8_t deviceID) { tc358870_mystery_setup_commands(); } +void Display_Init(uint8_t deviceID) +{ + AUO_H381DLN01_Panel_Reset(); + AUO_H381DLN01_Send_Panel_Init_Commands(); +} void Display_On(uint8_t deviceID) { - // delay_ms(500); +#ifdef HDMI_VERBOSE WriteLn("Turning display on"); +#endif - // display power on - svr_yield_ms(20); +/// @todo ugly workaround for resetting things. #if 0 - // Exit Sleep - TC358870_i2c_Write(0x0504, 0x0005, 2); - TC358870_i2c_Write(0x0504, 0x0011, 2); - svr_yield_ms(33); + Toshiba_TC358870_Init(); +#else + /// This one is at least a little bit less extreme + AUO_H381DLN01_Panel_Reset(); + AUO_H381DLN01_Send_Panel_Init_Commands(); + svr_yield_ms(120); + Toshiba_TC358870_Init_Receiver(); #endif + + // display power on - wait 120 ms in case this is after a reset. + svr_yield_ms(120); + #if 0 // Not for SSD2848 TC358870_i2c_Write(0x0504, 0x8029, 2); // DCSCMD Long Write TC358870_i2c_Write(0x0504, 0x0006, 2); // Number of data @@ -50,16 +103,20 @@ void Display_On(uint8_t deviceID) TC358870_i2c_Write(0x0504, 0x0000, 2); // DCSCMD_Q TC358870_i2c_Write(0x0504, 0x2903, 2); // DCSCMD_Q #endif + + // Sleep Out + AUO_Null_Param_DSI_Cmd(0x11); svr_yield_ms(166); //>10 frame // Display On - TC358870_i2c_Write(0x0504, 0x0005 /*0x0015*/, 2); - TC358870_i2c_Write(0x0504, 0x0029, 2); + AUO_Null_Param_DSI_Cmd(0x29); } void Display_Off(uint8_t deviceID) { +#ifdef HDMI_VERBOSE WriteLn("Turning display off"); +#endif #if 0 // Not for SSD2848 // video mode off TC358870_i2c_Write(0x0504, 0x8029, 2); // DCSCMD Long Write @@ -70,19 +127,26 @@ void Display_Off(uint8_t deviceID) svr_yield_ms(16); #endif -#if 1 // Display Off - TC358870_i2c_Write(0x0504, 0x0005 /*0x0015*/, 2); - TC358870_i2c_Write(0x0504, 0x0028, 2); + AUO_Null_Param_DSI_Cmd(0x28); + svr_yield_ms(166); + + // Sleep in + AUO_Null_Param_DSI_Cmd(0x10); svr_yield_ms(16); -#if 0 - // Sleep In - TC358870_i2c_Write(0x0504, 0x0005, 2); - TC358870_i2c_Write(0x0504, 0x0010, 2); - svr_yield_ms(20); // delay > 1 frames -#endif +/// @todo ugly workaround for resetting things. +/// This first version is uglier (more binary blob) but avoids a 1-2second period of a bright horizontal stripe on the +/// display during shutdown. +#if 1 + Toshiba_TC358870_Init(); #else + Display_Reset(Display1); + AUO_H381DLN01_Panel_Reset(); + AUO_H381DLN01_Send_Panel_Init_Commands(); +#endif + +#if 0 TC358870_i2c_Write(0x0004, 0x0004, 2); // ConfCtl0 TC358870_i2c_Write(0x0002, 0x3F01, 2); // SysCtl TC358870_i2c_Write(0x0002, 0x0000, 2); // SysCtl @@ -93,32 +157,32 @@ void Display_Reset(uint8_t deviceID) { /// Note: essentially the same as VideoInput_Reset - since one chip does both ends! Toshiba_TC358870_Trigger_Reset(); + svr_yield_ms(16); + Toshiba_TC358870_Init_Receiver(); + + /// @todo we could actually panel reset here... } void Display_Powercycle(uint8_t deviceID) { WriteLn("Display Power Cycle"); // Display Off - TC358870_i2c_Write(0x0504, 0x0015, 2); - TC358870_i2c_Write(0x0504, 0x0028, 2); + AUO_Null_Param_DSI_Cmd(0x28); svr_yield_ms(120); // Sleep In - TC358870_i2c_Write(0x0504, 0x0005, 2); - TC358870_i2c_Write(0x0504, 0x0010, 2); + AUO_Null_Param_DSI_Cmd(0x10); svr_yield_ms(1000); // Exit Sleep - TC358870_i2c_Write(0x0504, 0x0005, 2); - TC358870_i2c_Write(0x0504, 0x0011, 2); + AUO_Null_Param_DSI_Cmd(0x11); svr_yield_ms(166); //>10 frame // Display On - TC358870_i2c_Write(0x0504, 0x0015, 2); - TC358870_i2c_Write(0x0504, 0x0029, 2); + AUO_Null_Param_DSI_Cmd(0x29); } #endif diff --git a/Source code/Embedded/src/DeviceDrivers/Toshiba_TC358870.c b/Source code/Embedded/src/DeviceDrivers/Toshiba_TC358870.c index 2fdac68..ad601f5 100644 --- a/Source code/Embedded/src/DeviceDrivers/Toshiba_TC358870.c +++ b/Source code/Embedded/src/DeviceDrivers/Toshiba_TC358870.c @@ -27,7 +27,9 @@ static uint8_t s_tc358870_init_count = 0; void Toshiba_TC358870_Init(void) { +#ifdef HDMI_VERBOSE WriteLn("Toshiba_TC358870_Init: Start"); +#endif // Dennis Yeh 2016/03/14 : for TC358870 uint8_t tc_data; TC358870_i2c_Init(); @@ -35,20 +37,50 @@ void Toshiba_TC358870_Init(void) PowerOnSeq(); s_tc358870_init_count++; +#ifdef HDMI_VERBOSE WriteLn("Toshiba_TC358870_Init: End"); +#endif } +void Toshiba_TC358870_Init_Receiver() { TC358870_Init_Receive_HDMI_Signal(); } uint8_t Toshiba_TC358870_Get_Init_Count() { return s_tc358870_init_count; } -void Toshiba_TC358870_Trigger_Reset(void) +void Toshiba_TC358870_Trigger_Reset() { WriteLn("Toshiba_TC358870 Resetting"); ioport_set_pin_low(TC358870_Reset_Pin); svr_yield_ms(12); ioport_set_pin_high(TC358870_Reset_Pin); } -/// @todo currently disabled because it is instead referenced circularly by libhdk20 by a different name + +#define TC_MAKE_SINGLE_BIT_MASK(BIT) (0x01 << BIT) + +enum +{ + TC_REG_DCSCMD_Q = 0x0504, + TC_REG_SYS_STATUS = 0x8520, #if 0 -/* +TC_REG_SYS_STATUS_HAVE_VIDEO_MASK = TC_MAKE_SINGLE_BIT_MASK(7) | TC_MAKE_SINGLE_BIT_MASK(3) /* PHY DE detect */ | TC_MAKE_SINGLE_BIT_MASK(2) /* PHY PLL lock */ | TC_MAKE_SINGLE_BIT_MASK(1) /* TMDS input amplitude */ | TC_MAKE_SINGLE_BIT_MASK(0) /* DDC_Power input */ +#endif + TC_REG_SYS_STATUS_HAVE_VIDEO_BIT_MASK = TC_MAKE_SINGLE_BIT_MASK(7) +}; + +/// Checks that all the bits in the mask are set. Factored out because I'm not sure what will give the best performance. +static inline bool checkMask(uint8_t value, uint8_t mask) +{ +#if 0 + return (value & mask) == mask; +#else + // xor should flip all masked bits from 1 to 0, if they were set, then the and should give us only any + // previously-unset bits in the masked bits that remain. This lets us compare against 0. Who knows, the compiler may + // be clever enough to turn the first approach into this. + return ((value ^ mask) & mask) == 0x0; +#endif +} + +/// assumes the mask you pass has only one bit set! +static inline bool checkBit(uint8_t value, uint8_t mask) { return (value & mask) != 0; } +/* Documentation from old Coretronic-authored predecessor to this function follows: note that the comparison to 0x9f is + faulty. Function : Toshiba_TC358870_HDMI_IsVideoExisting IN : void OUT: 0: video does not exist @@ -58,18 +90,37 @@ void Toshiba_TC358870_Trigger_Reset(void) if the value is 0x9F, means the video is ready, otherwise it's not exist. */ -bool Toshiba_TC358870_HDMI_IsVideoExisting(void) +bool Toshiba_TC358870_Have_Video_Sync(void) { uint8_t tc_data; - if (TC358870_i2c_Read(0x8520, &tc_data) != TC358870_OK) // get SYS_STATUS + if (TC358870_i2c_Read(TC_REG_SYS_STATUS, &tc_data) != TC358870_OK) // get SYS_STATUS return false; - if (tc_data != 0x9F) - return false; + /// @todo - should we check the lower nybble too (PHY DE detect, PHY PLL, TMDS input amplitude, and DDC power + /// input)? + /// Bit 7 is input video sync - bits 6, 5, and 4 are unimportant to the task at hand, so equality to 0x9f is not + /// quite right. + return checkBit(tc_data, TC_REG_SYS_STATUS_HAVE_VIDEO_BIT_MASK); +} + +/// Send a short DSI command with no parameter. +void Toshiba_TC358870_DSI_Write_Cmd_Short(uint8_t cmd) +{ + TC358870_i2c_Write(TC_REG_DCSCMD_Q, 0x0005, 2); + TC358870_i2c_Write(TC_REG_DCSCMD_Q, (uint32_t)cmd, 2); +} - return true; +/// Send a short DSI command with one parameter. +void Toshiba_TC358870_DSI_Write_Cmd_Short_Param(uint8_t cmd, uint8_t param) +{ + TC358870_i2c_Write(TC_REG_DCSCMD_Q, 0x0015, 2); + // uint8_t yyCmd, uint8_t zzArg + // want to send 0xzzyy + TC358870_i2c_Write(TC_REG_DCSCMD_Q, (((uint16_t)param) << sizeof(cmd)) | ((uint16_t)cmd), 2); } -#endif + +/// Send a "long" DSI command with data (may be of length 0) +// void Toshiba_TC358870_DSI_Write_Cmd_Long(uint8_t cmd, uint16_t len, uint8_t * data); #endif // SVR_HAVE_TOSHIBA_TC358870 \ No newline at end of file diff --git a/Source code/Embedded/src/DeviceDrivers/Toshiba_TC358870.h b/Source code/Embedded/src/DeviceDrivers/Toshiba_TC358870.h index f9d7d23..f7bbfaf 100644 --- a/Source code/Embedded/src/DeviceDrivers/Toshiba_TC358870.h +++ b/Source code/Embedded/src/DeviceDrivers/Toshiba_TC358870.h @@ -22,6 +22,9 @@ /// things, eventually calls the other libhdk20 function TC358870_Init_Receive_HDMI_Signal void Toshiba_TC358870_Init(void); +/// Wraps libhdk20 function TC358870_Init_Receive_HDMI_Signal +void Toshiba_TC358870_Init_Receiver(void); + /// Returns the number of times that Toshiba_TC358870_Init() has been called. uint8_t Toshiba_TC358870_Get_Init_Count(void); @@ -29,21 +32,16 @@ uint8_t Toshiba_TC358870_Get_Init_Count(void); /// (Can't call it just Toshiba_TC358870_Reset, libhdk20 exports a symbol by that name.) void Toshiba_TC358870_Trigger_Reset(void); -/// @todo currently disabled because it is instead referenced circularly by libhdk20 by a different name -#if 0 -/* - HDMI IF Functions +/// Checks the status register to see if the toshiba chip has stable video sync. +bool Toshiba_TC358870_Have_Video_Sync(void); - Coretronic - FC Tu -*/ -/* - Function : Toshiba_TC358870_HDMI_IsVideoExisting - IN : void - OUT: false: video does not exist - true: video exist -*/ -bool Toshiba_TC358870_HDMI_IsVideoExisting(void); -#endif +/// Send a short DSI command with no parameter. +void Toshiba_TC358870_DSI_Write_Cmd_Short(uint8_t cmd); + +/// Send a short DSI command with one parameter. +void Toshiba_TC358870_DSI_Write_Cmd_Short_Param(uint8_t cmd, uint8_t param); + +/// Send a "long" DSI command with data (may be of length 0) +// void Toshiba_TC358870_DSI_Write_Cmd_Long(uint8_t cmd, uint16_t len, uint8_t * data); #endif /* TOSHIBA_TC358870_H_ */ \ No newline at end of file diff --git a/Source code/Embedded/src/DeviceDrivers/VideoInput.c b/Source code/Embedded/src/DeviceDrivers/VideoInput.c index 7c1899f..c2a34b2 100644 --- a/Source code/Embedded/src/DeviceDrivers/VideoInput.c +++ b/Source code/Embedded/src/DeviceDrivers/VideoInput.c @@ -30,11 +30,16 @@ static inline void internal_report_detected_event() s_everSignal = true; VideoInput_Events.firstVideoDetected = true; } + // new video: must update resolution detection (HDMIStatus) + VideoInput_Update_Resolution_Detection(); } static inline void internal_report_lost_event() { // report event VideoInput_Events.videoLost = true; + + // Update HDMIStatus. + HDMIStatus = 0; } void VideoInput_Protected_Report_Status(bool signalStatus) { diff --git a/Source code/Embedded/src/DeviceDrivers/VideoInput_Toshiba_TC358870.c b/Source code/Embedded/src/DeviceDrivers/VideoInput_Toshiba_TC358870.c index 2ecb2fc..4c87b47 100644 --- a/Source code/Embedded/src/DeviceDrivers/VideoInput_Toshiba_TC358870.c +++ b/Source code/Embedded/src/DeviceDrivers/VideoInput_Toshiba_TC358870.c @@ -38,7 +38,7 @@ void UpdateResolutionDetection() } #endif } - +#if 0 /// @todo We actually need to export this function as bool HDMI_IsVideoExisting(void) so libhdk20.a can link against it /// circularly... (IsVideoExistingPolling contains a reference to it) /// @@ -67,7 +67,7 @@ bool HDMI_IsVideoExisting() VideoInput_Protected_Report_Signal(); return true; } - +#endif static bool haveInitOnce = false; void VideoInput_Init(void) { @@ -93,13 +93,7 @@ void VideoInput_Update_Resolution_Detection(void) HDMIStatus = (VideoInput_Get_Status() ? VIDSTATUS_VIDEO_LANDSCAPE : VIDSTATUS_NOVIDEO); } -void VideoInput_Task(void) -{ - // This method reportedly calls HDMI_IsVideoExisting, so we supply a version that contains calls to - // VideoInput_Protected_Report_No_Signal() and VideoInput_Protected_Report_Signal() - IsVideoExistingPolling(); -} - +void VideoInput_Task(void) {} void VideoInput_Reset(uint8_t inputId) { if (inputId == 1) @@ -115,11 +109,7 @@ static const char LIBHDK2_NOT_SUPPORTED[] = "TC358870 via libhdk20 does not supp void VideoInput_Suspend(void) { WriteLn(LIBHDK2_NOT_SUPPORTED); } void VideoInput_Resume(void) { WriteLn(LIBHDK2_NOT_SUPPORTED); } -void VideoInput_Poll_Status(void) -{ - // does not require separate polling outside the task. -} - +void VideoInput_Poll_Status(void) { VideoInput_Protected_Report_Status(Toshiba_TC358870_Have_Video_Sync()); } // to console void VideoInput_Report_Status(void) { diff --git a/Source code/Embedded/src/USB.c b/Source code/Embedded/src/USB.c index 05a855a..9300237 100644 --- a/Source code/Embedded/src/USB.c +++ b/Source code/Embedded/src/USB.c @@ -56,6 +56,7 @@ void main_cdc_disable(uint8_t port) uart_close(port); } +bool usb_cdc_is_active(void) { return main_b_cdc_enable; } void main_cdc_set_dtr(uint8_t port, bool b_enable) { if (b_enable) diff --git a/Source code/Embedded/src/USB.h b/Source code/Embedded/src/USB.h index 1202d88..0884540 100644 --- a/Source code/Embedded/src/USB.h +++ b/Source code/Embedded/src/USB.h @@ -8,6 +8,9 @@ #ifndef USB_H_ #define USB_H_ +#include +#include + /*! \brief Opens the communication port * This is called by CDC interface when USB Host enable it. * @@ -20,6 +23,9 @@ bool main_cdc_enable(uint8_t port); */ void main_cdc_disable(uint8_t port); +/// @brief Check to see if USB CDC is active. +bool usb_cdc_is_active(void); + /*! \brief Manages the leds behaviors * Called when a start of frame is received on USB line each 1ms. */ diff --git a/Source code/Embedded/src/Variants/HDK_20/VariantOptions.h b/Source code/Embedded/src/Variants/HDK_20/VariantOptions.h index 3a1aaef..186c5ee 100644 --- a/Source code/Embedded/src/Variants/HDK_20/VariantOptions.h +++ b/Source code/Embedded/src/Variants/HDK_20/VariantOptions.h @@ -41,6 +41,10 @@ #define SVR_DISABLE_VIDEO_INPUT #endif +// Interval in number of mainloop cycles that should elapse between polling for video status. +// Quite a few, because polling this is fairly expensive. +#define SVR_VIDEO_INPUT_POLL_INTERVAL 10000 + #define SVR_VARIANT_STRING "HDK_20" #endif /* VARIANTOPTIONS_H_ */ diff --git a/Source code/Embedded/src/Variants/HDK_20_SVR/VariantOptions.h b/Source code/Embedded/src/Variants/HDK_20_SVR/VariantOptions.h index 0fde3b6..813289e 100644 --- a/Source code/Embedded/src/Variants/HDK_20_SVR/VariantOptions.h +++ b/Source code/Embedded/src/Variants/HDK_20_SVR/VariantOptions.h @@ -14,6 +14,8 @@ #undef SVR_VARIANT_STRING #define SVR_VARIANT_STRING "HDK_20_SVR" +#define SVR_IS_HDK_20_SVR + #define SVR_HAVE_EDID_INFO_STRING extern const char svrEdidInfoString[]; diff --git a/Source code/Embedded/src/Variants/HDK_20_SVR/svr1020.edid_info.c b/Source code/Embedded/src/Variants/HDK_20_SVR/svr1020.edid_info.c index 639f9de..ff65315 100644 --- a/Source code/Embedded/src/Variants/HDK_20_SVR/svr1020.edid_info.c +++ b/Source code/Embedded/src/Variants/HDK_20_SVR/svr1020.edid_info.c @@ -1,5 +1,8 @@ #include "VariantOptions.h" +// Guard since Atmel Studio doesn't allow conditional compilation of files in just some build configurations +#ifdef SVR_IS_HDK_20_SVR const char svrEdidInfoString[] = "SVR1019, based on 1.01, all dims 26x15 (r3)"; +#endif /* svr1020.edid.bin swapped in as the contents of section .rodata.EDID_LUT in libhdk20.1.01.a to produce libhdk20.1.01.svr1020.a */ diff --git a/Source code/Embedded/src/config/GlobalOptions.h b/Source code/Embedded/src/config/GlobalOptions.h index 07c79b0..b13d39e 100644 --- a/Source code/Embedded/src/config/GlobalOptions.h +++ b/Source code/Embedded/src/config/GlobalOptions.h @@ -11,7 +11,7 @@ #include "VariantOptions.h" #define MajorVersion 1 -#define MinorVersion 96 +#define MinorVersion 97 /// @ingroup Build-time options /// @{ diff --git a/Source code/Embedded/src/config/my_hardware.h b/Source code/Embedded/src/config/my_hardware.h index 9a742d0..a6d9f9a 100644 --- a/Source code/Embedded/src/config/my_hardware.h +++ b/Source code/Embedded/src/config/my_hardware.h @@ -110,13 +110,16 @@ extern uint8_t #endif // SVR_HAVE_TOSHIBA_TC358870 +#ifdef SVR_IS_HDK_20 +#define PANEL_RESET IOPORT_CREATE_PIN(PORTF, 4) // out, panel reset. hw power reset. +#endif + /// @todo This section is pins that are entirely unreferenced anywhere in the HDK_20 Coretronic fork except in /// custom_board_init #ifdef SVR_IS_HDK_20 #define MCU_LEVEL_SHIFT_OE IOPORT_CREATE_PIN(PORTA, 1) // out, level shift enable, low enable. U55 #define Left_SWIRE IOPORT_CREATE_PIN(PORTF, 1) // out, Right Panel SWIRE #define Right_SWIRE IOPORT_CREATE_PIN(PORTF, 3) // out, Right Panel SWIRE -#define PANEL_RESET IOPORT_CREATE_PIN(PORTF, 4) // out, panel reset. hw power reset. #define ANA_PWR_IN IOPORT_CREATE_PIN(PORTA, 6) // in, 5v power good. #define EDID_EEP_WP IOPORT_CREATE_PIN(PORTA, 7) // out, edid eeprom write protection, 0: write protect diff --git a/Source code/Embedded/src/main.c b/Source code/Embedded/src/main.c index c3faecc..558c72f 100644 --- a/Source code/Embedded/src/main.c +++ b/Source code/Embedded/src/main.c @@ -191,10 +191,6 @@ int main(void) #endif // DSIGHT // ProgramMTP0(); - - /// @todo This also gets set to true in VideoInput_Init - remove this line? - HDMI_task = true; - #endif // SVR_ENABLE_VIDEO_INPUT #ifdef BNO070 @@ -229,14 +225,6 @@ int main(void) uint16_t videoPollCounter = 0; #endif -#ifdef OSVRHDK -// ioport_set_pin_high(FPGA_Reset_Pin); // release FPGA reset -#endif - -#ifdef HDK_20 - VideoInput_Init(); -#endif - // Main loop while (true) { diff --git a/Source code/HMD-MCU.atsln b/Source code/HMD-MCU.atsln index 26faf35..204f78a 100644 --- a/Source code/HMD-MCU.atsln +++ b/Source code/HMD-MCU.atsln @@ -8,6 +8,7 @@ EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution dSight_Sharp_LCD|AVR = dSight_Sharp_LCD|AVR + HDK_20_SVR|AVR = HDK_20_SVR|AVR HDK_20|AVR = HDK_20|AVR HDK_OLED|AVR = HDK_OLED|AVR HDK_Sharp_LCD|AVR = HDK_Sharp_LCD|AVR @@ -15,6 +16,8 @@ Global GlobalSection(ProjectConfigurationPlatforms) = postSolution {75C0D83C-7332-42DE-8522-9585F1DF6614}.dSight_Sharp_LCD|AVR.ActiveCfg = dSight_Sharp_LCD|AVR {75C0D83C-7332-42DE-8522-9585F1DF6614}.dSight_Sharp_LCD|AVR.Build.0 = dSight_Sharp_LCD|AVR + {75C0D83C-7332-42DE-8522-9585F1DF6614}.HDK_20_SVR|AVR.ActiveCfg = HDK_20_SVR|AVR + {75C0D83C-7332-42DE-8522-9585F1DF6614}.HDK_20_SVR|AVR.Build.0 = HDK_20_SVR|AVR {75C0D83C-7332-42DE-8522-9585F1DF6614}.HDK_20|AVR.ActiveCfg = HDK_20|AVR {75C0D83C-7332-42DE-8522-9585F1DF6614}.HDK_20|AVR.Build.0 = HDK_20|AVR {75C0D83C-7332-42DE-8522-9585F1DF6614}.HDK_OLED|AVR.ActiveCfg = HDK_OLED|AVR