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