Driver

The HDMI IP requires a processor to setup the core. This can be any processor. A HDMI driver (prt_hdmi_drv) is provided for this task. It is plain C with no operating system or vendor library behind it, so it ports to whatever core sits next to the IP.

Each IP-core carries its own system controller, and that controller runs the firmware for the HDMI protocol itself: hot plug detect, EDID, SCDC, the link and the PHY. This is what makes the core autonomous, and it is the main reason for having it. The protocol keeps running on the system controller's own timers and interrupts, so the application processor is free of the low level HDMI work. It decides what it wants, such as starting video at a given resolution, and hears what came of it through the callbacks.

The application processor loads that firmware into the system controller at start up, and from then on the two communicate through a mailbox, exchanging the tokens defined in prt_hdmi_tokens.h. Most API functions are such an exchange: they send a token to the system controller and wait for its answer. For the same reason a few are asynchronous: prt_hdmi_sta returns right away and its values arrive a moment later, in the status callback.

One prt_hdmi_ds_struct describes one IP-core, so either the transmitter or the receiver. A design with both keeps two of them and passes the right one to every call, which is also how the API is split: shared functions, transmitter functions and receiver functions.

The IP-core raises an interrupt when the system controller has sent mail. prt_hdmi_irq_handler belongs in that interrupt; it only reads the message and raises an event flag. The application calls prt_hdmi_evt_handler from its main loop and that is what dispatches the callbacks. Because of this split a callback runs in thread context: it may take its time and call the other API functions, which an interrupt handler could not.

An IP-core is brought up in this order. The reference design in prt_hdmi_app.c shows it in full.

prt_hdmi_set_base (&hdmitx, HDMITX_BASE_ADDR);   // find the IP-core
                                                 // hook prt_hdmi_irq_handler to its interrupt
prt_hdmi_rom_init (&hdmitx, rom_len, rom);       // load the system controller firmware
prt_hdmi_ram_init (&hdmitx, ram_len, ram);
prt_hdmi_init     (&hdmitx, PRT_HDMITX_ID);

prt_hdmi_set_cb   (&hdmitx, PRT_HDMI_CB_HPD, &hdmitx_hpd_cb);
prt_hdmi_set_cb   (&hdmitx, PRT_HDMI_CB_LNK, &hdmi_lnk_cb);
/* ... the other callbacks ... */

while (1)
    prt_hdmi_evt_handler (&hdmitx);              // dispatches the callbacks

API

This section provides information about the driver API. The functions are grouped the same way as in prt_hdmi_drv.h: shared functions that apply to both IP-cores, followed by the transmitter and receiver functions.

Shared

prt_hdmi_set_base

  • description: Sets the HDMI IP-core base address and checks that the core responds.
  • syntax: uint8_t prt_hdmi_set_base (prt_hdmi_ds_struct *hdmi, uint32_t base);
  • parameters:
    • hdmipointer to HDMI IP-core
    • basebase address
  • returns: true when the identification register reads back correctly, else false.

prt_hdmi_set_cb

  • description: Registers a call back handler.
  • syntax: void prt_hdmi_set_cb (prt_hdmi_ds_struct *hdmi, prt_hdmi_cb_type cb_type, void *cb_handler);
  • parameters:
    • hdmipointer to HDMI IP-core
    • cb_typecall back type
      • PRT_HDMI_CB_CDCable detect
      • PRT_HDMI_CB_HPDHot Plug Detect
      • PRT_HDMI_CB_PHY_RATELink rate change
      • PRT_HDMI_CB_STAStatus
      • PRT_HDMI_CB_LNKLink
      • PRT_HDMI_CB_VIDVideo
      • PRT_HDMI_CB_DBGDebug
    • cb_handlerpointer to call back handler
  • returns: none

prt_hdmi_init

  • description: Initializes the HDMI IP-core.
  • syntax: void prt_hdmi_init (prt_hdmi_ds_struct *hdmi, uint8_t id);
  • parameters:
    • hdmipointer to HDMI IP-core
    • idHDMI IP-core identifier
  • returns: none

prt_hdmi_rom_init

  • description: Loads the system controller ROM code.
  • syntax: void prt_hdmi_rom_init (prt_hdmi_ds_struct *hdmi, uint32_t len, uint8_t *rom);
  • parameters:
    • hdmipointer to HDMI IP-core
    • lenlength of ROM code
    • rompointer to ROM code
  • returns: none

prt_hdmi_ram_init

  • description: Loads the system controller RAM code.
  • syntax: void prt_hdmi_ram_init (prt_hdmi_ds_struct *hdmi, uint32_t len, uint8_t *ram);
  • parameters:
    • hdmipointer to HDMI IP-core
    • lenlength of RAM code
    • rampointer to RAM code
  • returns: none

prt_hdmi_ping

  • description: Checks if the system controller is alive.
  • syntax: uint8_t prt_hdmi_ping (prt_hdmi_ds_struct *hdmi);
  • parameters:
    • hdmipointer to HDMI IP-core
  • returns: true when the IP-core is running, else false.

prt_hdmi_sta

  • description: Requests the IP-core status. The reply arrives asynchronously and raises the status call back; the values are read with prt_hdmi_get_sta.
  • syntax: void prt_hdmi_sta (prt_hdmi_ds_struct *hdmi);
  • parameters:
    • hdmipointer to HDMI IP-core
  • returns: none

prt_hdmi_get_sta

  • description: Gets the status values reported by the last prt_hdmi_sta request.
  • syntax: prt_hdmi_sta_struct prt_hdmi_get_sta (prt_hdmi_ds_struct *hdmi);
  • parameters:
    • hdmipointer to HDMI IP-core
  • returns: status structure
    • hw_ver_majorhardware version, major
    • hw_ver_minorhardware version, minor
    • sw_ver_majorsoftware version, major
    • sw_ver_minorsoftware version, minor
    • piosystem controller PIO state
    • hpdHot Plug Detect state
    • scrmscrambler state
    • tmds_freqmeasured TMDS frequency

prt_hdmi_is_lnk_up

  • description: Checks if the link is up.
  • syntax: uint8_t prt_hdmi_is_lnk_up (prt_hdmi_ds_struct *hdmi);
  • parameters:
    • hdmipointer to HDMI IP-core
  • returns: true when the link is up, else false.

prt_hdmi_get_lnk_reason

  • description: Gets the reason the link went down.
  • syntax: uint8_t prt_hdmi_get_lnk_reason (prt_hdmi_ds_struct *hdmi);
  • parameters:
    • hdmipointer to HDMI IP-core
  • returns: link down reason.

prt_hdmi_lnk_tmds_clk_get

  • description: Gets the TMDS clock of the link.
  • syntax: uint32_t prt_hdmi_lnk_tmds_clk_get (prt_hdmi_ds_struct *hdmi);
  • parameters:
    • hdmipointer to HDMI IP-core
  • returns: TMDS clock frequency in kHz.

prt_hdmi_is_vid_up

  • description: Checks if the video stream is up.
  • syntax: uint8_t prt_hdmi_is_vid_up (prt_hdmi_ds_struct *hdmi);
  • parameters:
    • hdmipointer to HDMI IP-core
  • returns: true when the video is up, else false.

Transmitter

prt_hdmitx_is_hpd

  • description: Checks if a sink is connected.
  • syntax: uint8_t prt_hdmitx_is_hpd (prt_hdmi_ds_struct *hdmi);
  • parameters:
    • hdmipointer to HDMI IP-core
  • returns: true when HPD is asserted, else false.

prt_hdmitx_vid_str

  • description: Starts the video stream.
  • syntax: uint8_t prt_hdmitx_vid_str (prt_hdmi_ds_struct *hdmi, uint32_t tmds_clk, uint8_t bpc, uint8_t vic);
  • parameters:
    • hdmipointer to HDMI IP-core
    • tmds_clkTMDS clock frequency (in kHz)
    • bpcbits per component (8 or 10)
    • vicVIC number
  • returns: true when the video is started, else false.

prt_hdmitx_vid_stp

  • description: Stops the video stream.
  • syntax: uint8_t prt_hdmitx_vid_stp (prt_hdmi_ds_struct *hdmi);
  • parameters:
    • hdmipointer to HDMI IP-core
  • returns: true when the video is stopped, else false.

prt_hdmitx_edid_rd

  • description: Reads EDID data from the connected HDMI sink.
  • syntax: uint8_t prt_hdmitx_edid_rd (prt_hdmi_ds_struct *hdmi, uint16_t adr, uint16_t len, uint8_t *dat);
  • parameters:
    • hdmipointer to HDMI IP-core
    • adrbase address
    • lenlength
    • datpointer to data buffer
  • returns: true when successful, else false.

prt_hdmitx_scdc_wr

  • description: Writes SCDC data.
  • syntax: uint8_t prt_hdmitx_scdc_wr (prt_hdmi_ds_struct *hdmi, uint8_t adr, uint8_t dat);
  • parameters:
    • hdmipointer to HDMI IP-core
    • adrSCDC address
    • datSCDC data
  • returns: true when successful, else false.

prt_hdmitx_scdc_rd

  • description: Reads SCDC data.
  • syntax: uint8_t prt_hdmitx_scdc_rd (prt_hdmi_ds_struct *hdmi, uint8_t adr, uint8_t *dat);
  • parameters:
    • hdmipointer to HDMI IP-core
    • adrSCDC address
    • datpointer to SCDC data
  • returns: true when successful, else false.

Receiver

prt_hdmirx_is_cd

  • description: Checks if a source cable is detected.
  • syntax: uint8_t prt_hdmirx_is_cd (prt_hdmi_ds_struct *hdmi);
  • parameters:
    • hdmipointer to HDMI IP-core
  • returns: true when a cable is detected, else false.

prt_hdmirx_hpd

  • description: Sets the HDMI RX HPD line.
  • syntax: uint8_t prt_hdmirx_hpd (prt_hdmi_ds_struct *hdmi, uint8_t hpd);
  • parameters:
    • hdmipointer to HDMI IP-core
    • hpdhot plug state
      • PRT_HDMI_HPD_UNPLUGHPD deassert
      • PRT_HDMI_HPD_PLUGHPD assert
      • PRT_HDMI_HPD_IRQHPD interrupt
  • returns: true when successful, else false.

prt_hdmirx_edid_wr

  • description: Writes EDID data to the HDMI IP-core.
  • syntax: uint8_t prt_hdmirx_edid_wr (prt_hdmi_ds_struct *hdmi, uint16_t len, uint8_t *dat);
  • parameters:
    • hdmipointer to HDMI IP-core
    • lenlength
    • datpointer to data buffer
  • returns: true when successful, else false.

prt_hdmirx_tp_get

  • description: Gets the video timing parameters of the incoming stream.
  • syntax: prt_hdmi_tp_struct prt_hdmirx_tp_get (prt_hdmi_ds_struct *hdmi);
  • parameters:
    • hdmipointer to HDMI IP-core
  • returns: video timing parameters
    • htotalhorizontal total
    • hwidthhorizontal width
    • hstarthorizontal start
    • hswhorizontal sync width
    • vtotalvertical total
    • vheightvertical height
    • vstartvertical start
    • vswvertical sync width

prt_hdmirx_bpc_get

  • description: Gets the bits per component of the incoming stream.
  • syntax: uint8_t prt_hdmirx_bpc_get (prt_hdmi_ds_struct *hdmi);
  • parameters:
    • hdmipointer to HDMI IP-core
  • returns: bits per component.

prt_hdmirx_csf_get

  • description: Gets the colorspace format of the incoming stream.
  • syntax: prt_hdmi_csf_type prt_hdmirx_csf_get (prt_hdmi_ds_struct *hdmi);
  • parameters:
    • hdmipointer to HDMI IP-core
  • returns: colorspace format
    • PRT_HDMI_CSF_RGBRGB
    • PRT_HDMI_CSF_YCBCR422YCbCr 4:2:2
    • PRT_HDMI_CSF_YCBCR444YCbCr 4:4:4
    • PRT_HDMI_CSF_YCBCR420YCbCr 4:2:0

prt_hdmirx_vic_get

  • description: Gets the VIC of the incoming stream.
  • syntax: uint8_t prt_hdmirx_vic_get (prt_hdmi_ds_struct *hdmi);
  • parameters:
    • hdmipointer to HDMI IP-core
  • returns: VIC number.

Callbacks

The callback functions are used by the driver to signal the application about an event. Functions are registered using the prt_hdmi_set_cb function. The driver raises an event flag when the system controller reports something, and prt_hdmi_evt_handler dispatches the handlers from thread context, so a handler may take its time and use the other API functions. The handler names below are the ones used in the reference design. The diagram shows the HDMI states and the callbacks that follow from them; the status and debug callbacks are not part of that flow.

HDMI callbacks

Figure 1: HDMI callbacks

hdmirx_cd_cb

registered with: PRT_HDMI_CB_CD

description: The function is called when the cable detect state of the receiver changes, so when a source cable is plugged in or removed. The state is read with prt_hdmirx_is_cd.

hdmitx_hpd_cb

registered with: PRT_HDMI_CB_HPD

description: The function is called on a Hot Plug Detect event of the transmitter: a sink was plugged in, a sink was removed, or a sink issued an HPD pulse. The state is read with prt_hdmi_hpd_get, or with prt_hdmitx_is_hpd when only the plugged state matters.

hdmitx_phy_rate_cb / hdmirx_phy_rate_cb

registered with: PRT_HDMI_CB_PHY_RATE

description: The function is called when the PHY line rate has to be set. On the receiver this follows the TMDS clock that its system controller measures and reports. The transmitter has no mail that raises this event; the driver calls the handler from prt_hdmitx_vid_str, before the video start is sent, so the rate is programmed in time. The clock is read with prt_hdmi_lnk_tmds_clk_get.

hdmi_sta_cb

registered with: PRT_HDMI_CB_STA

description: The function is called when the system controller answers a prt_hdmi_sta request. Since that request does not block, this is where the reply arrives. The values are read with prt_hdmi_get_sta.

hdmi_lnk_cb

registered with: PRT_HDMI_CB_LNK

description: The function is called when the link goes up or down. The state is read with prt_hdmi_is_lnk_up, and prt_hdmi_get_lnk_reason gives the reason for a link down.

hdmitx_vid_cb / hdmirx_vid_cb

registered with: PRT_HDMI_CB_VID

description: The function is called when the video stream goes up or down. The state is read with prt_hdmi_is_vid_up. On the receiver the properties of the incoming stream are available here, through prt_hdmirx_tp_get, prt_hdmirx_bpc_get, prt_hdmirx_csf_get and prt_hdmirx_vic_get.

hdmi_debug_cb

registered with: PRT_HDMI_CB_DBG

description: The function is called when the system controller sends a debug byte. The event is a flag and not a counter, so the handler drains the whole buffer: read with prt_hdmi_debug_get for as long as prt_hdmi_is_debug returns true.

×