📄 dvi_hdmi.c.070605.int
字号:
return DH_i2c_read_data(pRUA, pi2c_dev, sub_address, data, data_size);
}
static RMstatus DH_i2c_write_data(struct RUA *pRUA, struct DH_I2C *pi2c_dev, RMuint8 sub_address, RMuint8 *data, RMuint32 data_size)
{
struct I2C_WriteData_type i2c_write;
RMstatus err;
RMuint32 r;
if (data == NULL) {
return RM_FATALINVALIDPOINTER;
}
RMDBGLOG((DISABLE, "==== I2C Wr 0x%02X:0x%02X-0x%02X ====\n", pi2c_dev->dev.WrAddr, sub_address, sub_address + data_size - 1));
r = MAX_I2C_ATTEMPTS;
do {
if (RMFAILED(err = DH_update_i2c(pRUA, pi2c_dev))) continue;
i2c_write.UseSubAddr = TRUE;
i2c_write.SubAddr = sub_address;
i2c_write.DataSize = data_size;
RMMemcpy(i2c_write.Data, data, data_size);
#if DISABLE_I2C_BURST_WRITE
{
RMuint32 i;
struct I2C_WriteRMuint8_type i2c_write;
RMstatus e;
for (i = 0; i < data_size; i++) {
i2c_write.SubAddr = sub_address + i;
i2c_write.Data = data[i];
e = RUASetProperty(pRUA, pi2c_dev->I2C, RMI2CPropertyID_WriteRMuint8, &i2c_write, sizeof(i2c_write), 0);
if (RMFAILED(e)) err = e;
}
}
#else
err = RUASetProperty(pRUA, pi2c_dev->I2C, RMI2CPropertyID_WriteData, &i2c_write, sizeof(i2c_write), 0);
#endif
i2c_usage--; // decrease usage counter for this I2C configuration
} while (--r && RMFAILED(err));
if (RMFAILED(err)) {
RMDBGLOG((LOCALDBG, "Error setting RMI2CPropertyID_WriteData(0x%02X:0x%02X, 0x%02X) on I2C 0x%08lX GPIO %lu/%lu! %s\n",
pi2c_dev->dev.WrAddr, i2c_write.SubAddr, i2c_write.DataSize,
pi2c_dev->I2C, pi2c_dev->dev.PioClock, pi2c_dev->dev.PioData,
RMstatusToString(err)));
}
#if DH_I2C_VERIFY_WRITE
{
RMuint32 i;
DH_i2c_read_data(pRUA, pi2c_dev, sub_address, i2c_write.Data, i2c_write.DataSize);
for (i = 0; i < data_size; i++) {
if (i2c_write.Data[i] != data[i]) {
RMDBGLOG((LOCALDBG, "Error verifying 0x%02lX:0x%02lX, is 0x%02X instead of 0x%02X!\n",
pi2c_dev->dev.WrAddr, i2c_write.SubAddr + i, i2c_write.Data[i], data[i]));
}
}
}
#endif // DH_I2C_VERIFY_WRITE
return err;
}
static RMstatus DH_i2c_write_data_segment(
struct RUA *pRUA,
struct DH_I2C *pi2c_dev,
RMuint8 sub_address,
RMuint8 *data,
RMuint32 data_size,
RMuint8 segment_ptr,
RMuint8 segment)
{
struct I2C_SelectSegment_type i2c_segment;
RMstatus err;
RMuint32 r, index;
if (data == NULL) {
return RM_FATALINVALIDPOINTER;
}
r = MAX_I2C_ATTEMPTS;
do {
if (RMFAILED(err = DH_update_i2c(pRUA, pi2c_dev))) continue;
i2c_segment.SegmentPtr = segment_ptr;
i2c_segment.Segment = segment;
err = RUASetProperty(pRUA, pi2c_dev->I2C, RMI2CPropertyID_SelectSegment, &i2c_segment, sizeof(i2c_segment), 0);
i2c_usage--; // decrease usage counter for this I2C configuration
} while (--r && RMFAILED(err));
if (RMFAILED(err)) {
RMDBGLOG((LOCALDBG, "%s: failed to set RMI2CPropertyID_SelectSegment(0x%02X:0x%02X, 0x%02X) on I2C 0x%08lX GPIO %lu/%lu! %s\n",
(segment > 0) ? "Error" : "Warning",
pi2c_dev->dev.WrAddr, i2c_segment.SegmentPtr, i2c_segment.Segment,
pi2c_dev->I2C, pi2c_dev->dev.PioClock, pi2c_dev->dev.PioData,
RMstatusToString(err)));
if (segment > 0) return err;
}
//return DH_i2c_write_data(pRUA, pi2c_dev, sub_address, data, data_size);
for (index = 0; index < data_size; index++) {
RMuint8 v;
r = 10;
do {
err = DH_i2c_write(pRUA, pi2c_dev, sub_address + index, data[index]);
if (RMFAILED(err)) {
RMDBGLOG((LOCALDBG, "Error writing 0x%02X to %02X! %s\n", data[index], sub_address + index, RMstatusToString(err)));
}
RMMicroSecondSleep(100000); // Delay for EEPROM
err = DH_i2c_read(pRUA, pi2c_dev, sub_address + index, &v);
if (RMSUCCEEDED(err) && (v == data[index])) break;
} while (--r);
if (RMFAILED(err) || (v != data[index])) {
RMDBGLOG((LOCALDBG, "Error writing 0x%02X to %02X! Read back 0x%02X instead.\n", data[index], sub_address + index, v));
}
}
return err;
}
static RMstatus DHSetTMDSResistor(struct DH_control *pDH)
{
RMstatus err = RM_OK;
struct SystemBlock_GPIO_type gpio;
if (pDH->TMDS_Threshold) {
gpio.Bit = pDH->TMDS_GPIO;
gpio.Data = (pDH->VideoPixelClock >= pDH->TMDS_Threshold) ? 1 : 0;
if (RMFAILED(err = RUASetProperty(pDH->pRUA, SystemBlock, RMSystemBlockPropertyID_GPIO, &gpio, sizeof(gpio), 0))) {
RMDBGLOG((LOCALDBG, "Error setting GPIO %u to set external swing resistor of HDMI TMDS: %s\n", pDH->TMDS_GPIO, RMstatusToString(err)));
return err;
}
}
return err;
}
RMstatus DHSetTMDSMode(struct DH_control *pDH,
enum GPIOId_type GPIO,
RMuint32 PixelClockThreshold)
{
CHECK_pDH("DHSetTMDSMode");
pDH->TMDS_Threshold = PixelClockThreshold;
pDH->TMDS_GPIO = GPIO;
return RM_OK;
}
static RMstatus DHReset_siI164(struct DH_control *pDH)
{
RMstatus err = RM_OK;
struct SystemBlock_GPIO_type gpio;
// Set GPIO direction and Reset SiI170
if (! manutest) fprintf(stderr, "[HDMI] Resetting DVI transmitter with GPIO pin %u.\n", pDH->gpio_reset);
gpio.Bit = pDH->gpio_reset;
gpio.Data = 0;
if (RMFAILED(err = RUASetProperty(pDH->pRUA, SystemBlock, RMSystemBlockPropertyID_GPIO, &gpio, sizeof(gpio), 0))) {
RMDBGLOG((LOCALDBG, "Error setting GPIO to reset SiI170!!! %s\n", RMstatusToString(err)));
return err;
}
// Assert 50 uSec low time
RMMicroSecondSleep(50);
// Unreset SiI170
gpio.Bit = pDH->gpio_reset;
gpio.Data = 1;
if (RMFAILED(err = RUASetProperty(pDH->pRUA, SystemBlock, RMSystemBlockPropertyID_GPIO, &gpio, sizeof(gpio), 0))) {
RMDBGLOG((LOCALDBG, "Error setting GPIO to unreset SiI170!!! %s\n", RMstatusToString(err)));
return err;
}
if (pDH->part == DH_siI170) {
RMuint8 reg;
err = DH_i2c_read(pDH->pRUA, &(pDH->i2c_tx), HDCP_CTRL_ADDR, ®);
if (RMFAILED(err)) return err;
RMDBGLOG((LOCALDBG, "Read status from transmitter: %02X\n", reg));
if (reg & 0x01) {
if (! manutest) fprintf(stderr, "[HDMI] FATAL! Reset of DVI transmitter failed, encryption still enabled!\n");
}
}
RMMicroSecondSleep(10*1000);
return err;
}
// The following functions should work with all Sigma Reference Designs
#ifdef RMFEATURE_HAS_HDMI
static RMstatus DHResetHDMICore(struct RUA *pRUA)
{
RMstatus err = RM_OK;
enum DisplayBlock_HDMIState_type hs;
if (RMFAILED(err = RUAGetProperty(pRUA,
DisplayBlock, RMDisplayBlockPropertyID_HDMIState,
&hs, sizeof(hs)))) {
RMDBGLOG((LOCALDBG, "Error getting internal HDMI state! %s\n", RMstatusToString(err)));
return err;
}
if (hs == DisplayBlock_HDMIState_Running) {
if (! manutest) fprintf(stderr, "[HDMI] Resetting internal HDMI core!\n");
hs = DisplayBlock_HDMIState_ResetHDMI;
if (RMFAILED(err = RUASetProperty(pRUA,
DisplayBlock, RMDisplayBlockPropertyID_HDMIState,
&hs, sizeof(hs), 0))) {
RMDBGLOG((LOCALDBG, "Error setting internal HDMI state to ResetHDMI! %s\n", RMstatusToString(err)));
return err;
}
RMMicroSecondSleep(5*1000);
hs = DisplayBlock_HDMIState_Running;
if (RMFAILED(err = RUASetProperty(pRUA,
DisplayBlock, RMDisplayBlockPropertyID_HDMIState,
&hs, sizeof(hs), 0))) {
RMDBGLOG((LOCALDBG, "Error setting internal HDMI state to Running! %s\n", RMstatusToString(err)));
return err;
}
RMMicroSecondSleep(5*1000);
}
return err;
}
// Reset: if TRUE, assure that a ResetHDMI to Running transition is performed
static RMstatus DHUnresetHDMICore(struct RUA *pRUA, RMbool Reset)
{
RMstatus err = RM_OK;
enum DisplayBlock_HDMIState_type hs;
if (RMFAILED(err = RUAGetProperty(pRUA,
DisplayBlock, RMDisplayBlockPropertyID_HDMIState,
&hs, sizeof(hs)))) {
RMDBGLOG((LOCALDBG, "Error getting internal HDMI state! %s\n", RMstatusToString(err)));
return err;
}
if (Reset && (hs == DisplayBlock_HDMIState_Running)) {
return DHResetHDMICore(pRUA);
}
if (hs == DisplayBlock_HDMIState_ResetConfig) {
hs = DisplayBlock_HDMIState_ResetKeymemI2C;
if (RMFAILED(err = RUASetProperty(pRUA,
DisplayBlock, RMDisplayBlockPropertyID_HDMIState,
&hs, sizeof(hs), 0))) {
RMDBGLOG((LOCALDBG, "Error setting internal HDMI state to ResetKeymemI2C! %s\n", RMstatusToString(err)));
return err;
}
RMMicroSecondSleep(5*1000); // wait 5 ms
}
if (hs == DisplayBlock_HDMIState_ResetKeymemI2C) {
hs = DisplayBlock_HDMIState_ResetHDMI;
if (RMFAILED(err = RUASetProperty(pRUA,
DisplayBlock, RMDisplayBlockPropertyID_HDMIState,
&hs, sizeof(hs), 0))) {
RMDBGLOG((LOCALDBG, "Error setting internal HDMI state to ResetHDMI! %s\n", RMstatusToString(err)));
return err;
}
RMMicroSecondSleep(5*1000); // wait 5 ms
}
if (hs == DisplayBlock_HDMIState_ResetHDMI) {
hs = DisplayBlock_HDMIState_Running;
if (RMFAILED(err = RUASetProperty(pRUA,
DisplayBlock, RMDisplayBlockPropertyID_HDMIState,
&hs, sizeof(hs), 0))) {
RMDBGLOG((LOCALDBG, "Error setting internal HDMI state to Running! %s\n", RMstatusToString(err)));
return err;
}
}
return err;
}
#endif
RMstatus DHCheckHDCPKeyMem(struct DH_control *pDH)
{
RMstatus err;
RMuint8 bist;
RMuint64 t0, t1;
CHECK_pDH("DHCheckHDCPKeyMem");
if (pDH->part == DH_cat6611)
{
return RM_OK ;
}
if ((pDH->part != DH_siI9030) && (pDH->part != DH_siI170)) {
RMDBGLOG((LOCALDBG, "Call to DHCheckHDCPKeyMem: Error, only siI9030 supports this function\n"));
return RM_ERROR;
}
err = DH_i2c_write(pDH->pRUA, &(pDH->i2c_tx), 0xFA, 0x03);
t0 = RMGetTimeInMicroSeconds();
do {
err = DH_i2c_read(pDH->pRUA, &(pDH->i2c_tx), 0xF9, &bist);
t1 = RMGetTimeInMicroSeconds();
if (RMCyclesElapsed64(t0, t1) > 200000) err = RM_TIMEOUT; // 0.2 sec
} while (RMSUCCEEDED(err) && ((bist & 0x01) == 0));
if (err == RM_TIMEOUT) {
if (! manutest) fprintf(stderr, "[HDMI] HDCP BIST Timeout!\n");
} else {
if (! manutest) fprintf(stderr, "[HDMI] HDCP BIST took %llu mSec.\n", RMCyclesElapsed64(t0, t1) / 1000);
}
if (bist & 0x02) {
if (! manutest) fprintf(stderr, "[HDMI] HDCP BIST failed! 0x%02X\n", bist);
err = RM_ERROR;
}
return err;
}
static RMstatus DHCreate(struct RUA *pRUA, struct DH_control **ppDH)
{
if (! manutest) fprintf(stderr, "[HDMI] ========================== creating pDH ==========================\n");
#ifdef HDCP_USE_FACSIMILE_KEY
if (! manutest) fprintf(stderr, "[HDMI] === COMPILED WITH HDCP FACSIMILE KEYS -- Not for production! ===\n");
if (! manutest) fprintf(stderr, "[HDMI] ==================================================================\n");
#endif
*ppDH = (struct DH_control *)RMMalloc(sizeof(struct DH_control));
if (*ppDH == NULL) {
if (! manutest) fprintf(stderr, "[HDMI] FATAL! Not enough memory for struct DH_control!\n");
return RM_FATALOUTOFMEMORY;
}
RMMemset(*ppDH, 0, sizeof(struct DH_control));
(*ppDH)->pRUA = pRUA;
(*ppDH)->SRM_dss.y = bignum_from_bytes((RMuint8 *)SRM_y, 128);
(*ppDH)->SRM_dss.p = bignum_from_bytes((RMuint8 *)SRM_p, 128);
(*ppDH)->SRM_dss.q = bignum_from_bytes((RMuint8 *)SRM_q, 20);
(*ppDH)->SRM_dss.g = bignum_from_bytes((RMuint8 *)SRM_g, 128);
return RM_OK;
}
RMstatus DHInitWithAutoDetectReset(struct RUA *pRUA,
RMuint8 pio_clock_transmitter, RMuint8 pio_data_transmitter, RMuint32 i2c_module,
RMuint8 gpio_reset, struct DH_control **ppDH, RMbool Reset)
{
RMstatus err = RM_OK;
RMuint8 vendor_id[4];
RMuint8 part_num, index;
RMbool found_part;
if (pRUA == NULL) {
if (! manutest) fprintf(stderr, "[HDMI] Call to DHInitWithAutoDetect with invalid RUA structure!\n");
return RM_FATALINVALIDPOINTER;
}
CHECK_PTR("DHInitWithAutoDetect", ppDH);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -