1# HDMI 2 3 4## Overview 5 6### HDMI 7 8High-definition multimedia interface (HDMI) is an interface for transmitting audio and video data from a source device, such as a DVD player or set-top box (STB), to a sink device, such as a TV or display. 9HDMI usually has a source and a sink. 10The HDMI APIs provide a set of common functions for HDMI transmission, including: 11 12- Opening and closing an HDMI controller 13- Starting and stopping HDMI transmission 14- Setting audio, video, and High Dynamic Range (HDR) attributes, color depth, and AV mute 15- Reading the raw Extended Display Identification Data (EDID) from a sink 16- Registering and unregistering a callback for HDMI hot plug detect (HPD) 17 18### Basic Concepts 19 20HDMI is an audio and video transmission protocol released by Hitachi, Panasonic, Philips, Silicon Image, Sony, Thomson, and Toshiba. The transmission process complies with the Transition-minimized Differential Signaling (TMDS). 21 22- TMDS is used to transmit audio, video, and various auxiliary data. 23- Display data channel (DDC) allows the TX and RX ends to obtain the transmitting and receiving capabilities. However, HDMI only needs to unidirectionally obtain the capabilities of the RX end (display). 24- Consumer Electronics Control (CEC) enables interaction between the HDMI TX and RX devices. 25- Fixed rate link (FRL) allows the maximum TMDS bandwidth to be increased from 18 Gbit/s to 48 Gbit/s. 26- High-bandwidth Digital Content Protection (HDCP) prevents copying of digital audio and video content being transmitted across devices. 27- EDID, usually stored in the display firmware, provides the vendor information, EDID version, maximum image size, color settings, vendor pre-settings, frequency range limit, display name, and serial number. 28 29### Working Principles 30 31The HDMI source provides +5 V and GND for DDC and CEC communication. Through the DDC, the source obtains the sink parameters, such as the RX capabilities. The CEC provides an optional channel to synchronize control signals between the source and sink for better user experience. There are four TMDS channels between the HDMI source and sink. The TMDS clock channel provides clock signals for TMDS, and the other three channels transmit audio, video, and auxiliary data. HDP is the hot plug detect port. When the sink is connected, the source responds by using an interrupt service routine (ISR). 32 33The figure below shows the HDMI physical connection. 34 35**Figure 1** HDMI physical connection 36 37![](figures/HDMI_physical_connection.png "HDMI_physical_connection") 38 39### Constraints 40 41Currently, the HDMI module supports only the kernels (LiteOS) of mini and small systems. 42 43## Development Guidelines 44 45### When to Use 46 47HDMI features high transmission rate, wide transmission bandwidth, high compatibility, and can transmit uncompressed audio and video signals. Compared with the traditional full analog interface, HDMI simplifies connection between devices and provides HDMI-specific intelligent features, which are ideal for high-quality audio and video transmission of small-sized devices. 48 49### Available APIs 50 51**Table 1** HDMI driver APIs 52 53 54| API | Description | 55| ----------------------------- | -------------------------- | 56| HdmiOpen | Opens an HDMI controller. | 57| HdmiClose | Closes an HDMI controller. | 58| HdmiStart | Starts HDMI transmission. | 59| HdmiStop | Stops HDMI transmission. | 60| HdmiAvmuteSet | Sets the AV mute feature. | 61| HdmiDeepColorSet | Sets the color depth. | 62| HdmiDeepColorGet | Obtains the color depth. | 63| HdmiSetVideoAttribute | Sets video attributes. | 64| HdmiSetAudioAttribute | Sets audio attributes. | 65| HdmiSetHdrAttribute | Sets HDR attributes. | 66| HdmiReadSinkEdid | Reads the raw EDID from a sink. | 67| HdmiRegisterHpdCallbackFunc | Registers a callback for HDMI HPD.| 68| HdmiUnregisterHpdCallbackFunc | Unregisters a callback for HDMI HPD.| 69 70### How to Develop 71 72The figure below illustrates the general HDMI development process. 73 74**Figure 2** Using HDMI driver APIs 75 76![](figures/using-HDMI-process.png "using-HDMI-process") 77 78#### Opening an HDMI Controller 79 80Before HDMI communication, call **HdmiOpen()** to open an HDMI controller. 81 82```c 83DevHandle HdmiOpen(int16_t number); 84``` 85 86**Table 2** Description of HdmiOpen 87 88| Parameter | Description | 89| ---------- | -------------------- | 90| number | HDMI controller ID. | 91| **Return Value**| **Description** | 92| NULL | The operation failed. | 93| Controller handle| Handle of the opened HDMI controller.| 94 95For example, open controller 0 of the two HDMI controllers (numbered 0 and 1) in the system: 96 97```c 98DevHandle hdmiHandle = NULL; /* HDMI controller handle / 99 100/* Open HDMI controller 0. */ 101hdmiHandle = HdmiOpen(0); 102if (hdmiHandle == NULL) { 103 HDF_LOGE("HdmiOpen: failed\n"); 104 return; 105} 106``` 107 108#### Registering a Callback for HPD 109 110```c 111int32_t HdmiRegisterHpdCallbackFunc(DevHandle handle, struct HdmiHpdCallbackInfo *callback); 112``` 113 114**Table 3** Description of HdmiRegisterHpdCallbackFunc 115 116| Parameter | Description | 117| ---------- | ------------------ | 118| handle | HDMI controller handle. | 119| callback | Pointer to the callback to be invoked to return the HPD result.| 120| **Return Value**| **Description** | 121| 0 | The operation is successful. | 122| Negative value | The operation failed. | 123 124The following is an example of registering a callback for HPD: 125 126```c 127/* Definition of the callback for HPD */ 128static void HdmiHpdHandle(void *data, bool hpd) 129{ 130 if (data == NULL) { 131 HDF_LOGE("priv data is NULL"); 132 return; 133 } 134 if (hpd == true) { 135 HDF_LOGD("HdmiHpdHandle: hot plug"); 136 /* Add related processing if required. */ 137 } else { 138 HDF_LOGD("HdmiHpdHandle: hot unplug"); 139 /* Add related processing if required. */ 140 } 141} 142 143/* Example of registering a callback for HPD */ 144··· 145struct HdmiHpdCallbackInfo info = {0}; 146info.data = handle; 147info.callbackFunc = HdmiHpdHandle; 148ret = HdmiRegisterHpdCallbackFunc(hdmiHandle, info); 149if (ret != 0) { 150 HDF_LOGE("HdmiRegisterHpdCallbackFunc: Register failed."); 151} 152··· 153``` 154 155#### Reading the Raw EDID 156 157```c 158int32_t HdmiReadSinkEdid(DevHandle handle, uint8_t *buffer, uint32_t len); 159``` 160 161**Table 4** Description of HdmiReadSinkEdid 162 163| Parameter | Description | 164| ---------- | ---------------------- | 165| handle | HDMI controller handle. | 166| buffer | Pointer to the data buffer. | 167| len | Data length. | 168| **Return Value**| **Description** | 169| Positive integer | Raw EDID read.| 170| Negative number or 0 | Failed to read the EDID. | 171 172The following is an example of reading the raw EDID from a sink: 173 174```c 175int32_t len; 176uint8_t edid[HDMI_EDID_MAX_LEN] = {0}; 177 178len = HdmiReadSinkEdid(hdmiHandle, edid, HDMI_EDID_MAX_LEN); 179if (len <= 0) { 180 HDF_LOGE("%s: HdmiReadSinkEdid failed len = %d.", __func__, len); 181} 182``` 183 184#### Setting Audio Attributes 185 186```c 187int32_t HdmiSetAudioAttribute(DevHandle handle, struct HdmiAudioAttr *attr); 188``` 189 190**Table 5** Description of HdmiSetAudioAttribute 191 192 193| Parameter | Description | 194| ------ | -------------- | 195| handle | HDMI controller handle.| 196| attr | Pointer to the audio attributes. | 197| **Return Value**| **Description** | 198| 0 | The operation is successful. | 199| Negative value | The operation failed. | 200 201The following is an example of setting audio attributes: 202 203```c 204struct HdmiAudioAttr audioAttr = {0}; 205int32_t ret; 206 207audioAttr.codingType = HDMI_AUDIO_CODING_TYPE_MP3; 208audioAttr.ifType = HDMI_AUDIO_IF_TYPE_I2S; 209audioAttr.bitDepth = HDMI_ADIO_BIT_DEPTH_16; 210audioAttr.sampleRate = HDMI_SAMPLE_RATE_8K; 211audioAttr.channels = HDMI_AUDIO_FORMAT_CHANNEL_3; 212ret = HdmiSetAudioAttribute(handle, &audioAttr); 213if (ret != 0) { 214 HDF_LOGE("HdmiSetAudioAttribute failed."); 215} 216``` 217 218#### Setting Video Attributes 219 220```c 221int32_t HdmiSetVideoAttribute(DevHandle handle, struct HdmiVideoAttr *attr); 222``` 223 224**Table 6** Description of HdmiSetVideoAttribute 225 226 227| Parameter | Description | 228| ---------- | -------------- | 229| handle | HDMI controller handle.| 230| attr | Pointer to the video attributes. | 231| **Return Value**| **Description**| 232| 0 | The operation is successful. | 233| Negative value | The operation failed. | 234 235The following is an example of setting video attributes: 236 237```c 238struct HdmiVideoAttr videoAttr = {0}; 239int32_t ret; 240 241videoAttr.colorSpace = HDMI_COLOR_SPACE_YCBCR444; 242videoAttr.colorimetry = HDMI_COLORIMETRY_EXTENDED; 243videoAttr.extColorimetry = HDMI_EXTENDED_COLORIMETRY_BT2020_CONST_LUM; 244videoAttr.quantization = HDMI_QUANTIZATION_RANGE_FULL; 245ret = HdmiSetVideoAttribute(handle, &videoAttr); 246if (ret != 0) { 247 HDF_LOGE("HdmiSetVideoAttribute failed."); 248} 249``` 250 251#### Setting HDR Attributes 252 253```c 254int32_t HdmiSetHdrAttribute(DevHandle handle, struct HdmiHdrAttr *attr); 255``` 256 257**Table 7** Description of HdmiSetHdrAttribute 258 259 260| Parameter | Description | 261| ---------- | -------------- | 262| handle | HDMI controller handle.| 263| attr | Pointer to the HDR attributes | 264| **Return Value**| **Description**| 265| 0 | The operation is successful. | 266| Negative value | The operation failed. | 267 268The following is an example of setting HDR attributes: 269 270```c 271struct HdmiHdrAttr hdrAttr = {0}; 272int32_t ret; 273 274hdrAttr.mode = HDMI_HDR_MODE_CEA_861_3; 275hdrAttr.userMode = HDMI_HDR_USERMODE_DOLBY; 276hdrAttr.eotfType = HDMI_EOTF_SMPTE_ST_2048; 277hdrAttr.metadataType = HDMI_DRM_STATIC_METADATA_TYPE_1; 278hdrAttr.colorimetry = HDMI_HDR_EXTENDED_COLORIMETRY_XV_YCC_709; 279ret = HdmiSetHdrAttribute(handle, &hdrAttr); 280if (ret != 0) { 281 HDF_LOGE("HdmiSetHdrAttribute failed."); 282} 283``` 284 285#### Setting HDMI AV Mute 286 287```c 288int32_t HdmiAvmuteSet(DevHandle handle, bool enable); 289``` 290 291**Table 8** Description of HdmiAvmuteSet 292 293 294| Parameter | Description | 295| ---------- | ----------------- | 296| handle | HDMI controller handle. | 297| enable | Whether to enable the AV mute feature.| 298| **Return Value**| **Description** | 299| 0 | The operation is successful. | 300| Negative value | The operation failed. | 301 302The following is an example of setting AV mute: 303 304```c 305int32_t ret; 306 307ret = HdmiAvmuteSet(hdmiHandle, true); 308if (ret != 0) { 309 HDF_LOGE("HdmiAvmuteSet failed."); 310} 311``` 312 313#### Setting the Color Depth 314 315```c 316int32_t HdmiDeepColorSet(DevHandle handle, enum HdmiDeepColor color); 317``` 318 319**Table 9** Description of HdmiDeepColorSet 320 321 322| Parameter | Description | 323| ---------- | -------------- | 324| handle | HDMI controller handle.| 325| color | Color depth to set. | 326| **Return Value**| **Description**| 327| 0 | The operation is successful. | 328| Negative value | The operation failed. | 329 330The following is an example of setting the color depth: 331 332```c 333int32_t ret; 334 335ret = HdmiDeepColorSet(handle, HDMI_DEEP_COLOR_48BITS); 336if (ret != 0) { 337 HDF_LOGE("HdmiDeepColorSet failed."); 338} 339``` 340 341#### Obtaining the Color Depth 342 343```c 344int32_t HdmiDeepColorGet(DevHandle handle, enum HdmiDeepColor *color); 345``` 346 347**Table 10** Description of HdmiDeepColorGet 348 349 350| Parameter | Description | 351| ---------- | -------------- | 352| handle | HDMI controller handle.| 353| color | Pointer to the color depth. | 354| **Return Value**| **Description**| 355| 0 | The operation is successful. | 356| Negative value | The operation failed. | 357 358The following is an example of obtaining the color depth: 359 360```c 361enum HdmiDeepColor color; 362int32_t ret; 363 364ret = HdmiDeepColorGet(handle, &color); 365if (ret != 0) { 366 HDF_LOGE("HdmiDeepColorGet failed."); 367} 368``` 369 370#### Starting HDMI Transmission 371 372```c 373int32_t HdmiStart(DevHandle handle); 374``` 375 376**Table 11** Description of HdmiStart 377 378 379| Parameter | Description | 380| ---------- | -------------- | 381| handle | HDMI controller handle.| 382| **Return Value**| **Description**| 383| 0 | The operation is successful. | 384| Negative value | The operation failed. | 385 386The following is an example of starting HDMI transmission: 387 388```c 389int32_t ret; 390 391ret = HdmiStart(hdmiHandle); 392if (ret != 0) { 393 HDF_LOGE("Failed to start transmission."); 394} 395``` 396 397#### Stopping HDMI Transmission<a name="section11"></a> 398 399```c 400int32_t HdmiStop(DevHandle handle); 401``` 402 403**Table 12** Description of HdmiStop 404 405 406| Parameter | Description | 407| ---------- | -------------- | 408| handle | HDMI controller handle.| 409| **Return Value**| **Description**| 410| 0 | The operation is successful. | 411| Negative value | The operation failed. | 412 413The following is an example of stopping HDMI transmission: 414 415```c 416int32_t ret; 417 418ret = HdmiStop(hdmiHandle); 419if (ret != 0) { 420 HDF_LOGE("Failed to stop transmission."); 421} 422``` 423 424#### Unregistering the Callback for HPD 425 426```c 427int32_t HdmiUnregisterHpdCallbackFunc(DevHandle handle); 428``` 429 430**Table 13** Description of HdmiUnregisterHpdCallbackFunc 431 432 433| Parameter | Description | 434| ---------- | -------------- | 435| handle | HDMI controller handle.| 436| **Return Value**| **Description**| 437| 0 | The operation is successful. | 438| Negative value | The operation failed. | 439 440The following is an example of unregistering the callback for HPD: 441 442```c 443int32_t ret; 444 445ret = HdmiUnregisterHpdCallbackFunc(hdmiHandle); 446if (ret != 0) { 447 HDF_LOGE("unregister failed."); 448} 449``` 450 451#### Closing an HDMI Controller 452 453```c 454void HdmiClose(DevHandle handle); 455``` 456 457**Table 14** Description of HdmiClose 458 459 460| Parameter | Description | 461| ---------- | -------------- | 462| handle | HDMI controller handle.| 463 464The following is an example of closing an HDMI controller: 465 466```c 467HdmiClose(hdmiHandle); 468``` 469 470### Example 471 472This following example shows how to use HDMI APIs to manage an HDMI device on a Hi3516D V300 development board. 473 474A virtual driver is used in this example. The hardware information is as follows: 475 476- SoC: Hi3516D V300 477 478- HDMI controller: HDMI controller 0 479 480 481The sample code is as follows: 482 483```c 484#include "hdmi_if.h" /* Header file for HDMI standard APIs */ 485#include "hdf_log.h" /* Header file for log APIs */ 486#include "osal_time.h" /* Header file for delay and sleep APIs */ 487 488/* Callback for hog plug detect */ 489static void HdmiHpdHandle(void *data, bool hpd) 490{ 491 if (data == NULL) { 492 HDF_LOGE("priv data is NULL"); 493 return; 494 } 495 496 if (hpd == true) { 497 HDF_LOGD("HdmiHpdHandle: hot plug"); 498 /* Add related processing if required. */ 499 } else { 500 HDF_LOGD("HdmiHpdHandle: hot unplug"); 501 /* Add related processing if required. */ 502 } 503} 504 505/* Set HDMI attributes. */ 506static int32_t TestHdmiSetAttr(DevHandle handle) 507{ 508 enum HdmiDeepColor color; 509 struct HdmiVideoAttr videoAttr = {0}; 510 struct HdmiAudioAttr audioAttr = {0}; 511 struct HdmiHdrAttr hdrAttr = {0}; 512 int32_t ret; 513 514 ret = HdmiDeepColorSet(handle, HDMI_DEEP_COLOR_48BITS); 515 516 if (ret != 0) { 517 HDF_LOGE("HdmiDeepColorSet failed."); 518 return ret; 519 } 520 ret = HdmiDeepColorGet(handle, &color); 521 if (ret != 0) { 522 HDF_LOGE("HdmiDeepColorGet failed."); 523 return ret; 524 } 525 HDF_LOGE("HdmiDeepColorGet successful, color = %d.", color); 526 videoAttr.colorSpace = HDMI_COLOR_SPACE_YCBCR444; 527 videoAttr.colorimetry = HDMI_COLORIMETRY_EXTENDED; 528 videoAttr.extColorimetry = HDMI_EXTENDED_COLORIMETRY_BT2020_CONST_LUM; 529 videoAttr.quantization = HDMI_QUANTIZATION_RANGE_FULL; 530 ret = HdmiSetVideoAttribute(handle, &videoAttr); 531 if (ret != 0) { 532 HDF_LOGE("HdmiSetVideoAttribute failed."); 533 return ret; 534 } 535 audioAttr.codingType = HDMI_AUDIO_CODING_TYPE_MP3; 536 audioAttr.ifType = HDMI_AUDIO_IF_TYPE_I2S; 537 audioAttr.bitDepth = HDMI_ADIO_BIT_DEPTH_16; 538 audioAttr.sampleRate = HDMI_SAMPLE_RATE_8K; 539 audioAttr.channels = HDMI_AUDIO_FORMAT_CHANNEL_3; 540 ret = HdmiSetAudioAttribute(handle, &audioAttr); 541 if (ret != 0) { 542 HDF_LOGE("HdmiSetAudioAttribute failed."); 543 return ret; 544 } 545 hdrAttr.mode = HDMI_HDR_MODE_CEA_861_3; 546 hdrAttr.userMode = HDMI_HDR_USERMODE_DOLBY; 547 hdrAttr.eotfType = HDMI_EOTF_SMPTE_ST_2048; 548 hdrAttr.metadataType = HDMI_DRM_STATIC_METADATA_TYPE_1; 549 hdrAttr.colorimetry = HDMI_HDR_EXTENDED_COLORIMETRY_XV_YCC_709; 550 ret = HdmiSetHdrAttribute(handle, &hdrAttr); 551 if (ret != 0) { 552 HDF_LOGE("HdmiSetHdrAttribute failed."); 553 return ret; 554 } 555 556 return 0; 557} 558 559/* Main entry of HDMI routines */ 560static int32_t TestCaseHdmi(void) 561{ 562 DevHandle handle = NULL; 563 int32_t ret; 564 565 struct HdmiHpdCallbackInfo info = {0}; 566 uint8_t data[128] = {0}; 567 568 HDF_LOGD("HdmiAdapterInit: successful."); 569 handle = HdmiOpen(0); 570 if (handle == NULL) { 571 HDF_LOGE("HdmiOpen failed."); 572 return ret; 573 } 574 info.data = handle; 575 info.callbackFunc = HdmiHpdHandle; 576 ret = HdmiRegisterHpdCallbackFunc(handle, &info); 577 if (ret != 0) { 578 HDF_LOGE("HdmiRegisterHpdCallbackFunc failed."); 579 return ret; 580 } 581 582 ret = HdmiReadSinkEdid(handle, data, 128); 583 if (ret <= 0) { 584 HDF_LOGE("HdmiReadSinkEdid failed."); 585 return ret; 586 } 587 HDF_LOGE("HdmiReadSinkEdid successful, data[6] = %d, data[8] = %d.", data[6], data[8]); 588 589 ret = TestHdmiSetAttr(handle); 590 if (ret != 0) { 591 HDF_LOGE("TestHdmiSetAttr failed."); 592 return ret; 593 } 594 595 ret = HdmiStart(handle); 596 if (ret != 0) { 597 HDF_LOGE("HdmiStart failed."); 598 return ret; 599 } 600 601 OsalMSleep(1000); 602 603 ret = HdmiStop(handle); 604 if (ret != 0) { 605 HDF_LOGE("HdmiStop failed."); 606 return ret; 607 } 608 609 ret = HdmiUnregisterHpdCallbackFunc(handle); 610 if (ret != 0) { 611 HDF_LOGE("HdmiUnregisterHpdCallbackFunc failed."); 612 return ret; 613 } 614 HdmiClose(handle); 615 return 0; 616} 617 618``` 619