Skip to content

hdmi input board

Luc Verhaegen edited this page May 23, 2019 · 19 revisions

Table of Contents

The plan

The problem

In our current setup, for the slides boxes, we make use of:

  • a hardware hdmi scaler (for the speaker laptop)
  • an active hdmi splitter (which goes to the next stage, but which also sends the hdmi to the projector)
  • an fpga (?) based hw h.264 encoder which not only is a black box, it also is quite expensive.
  • an allwinner A20 based banana pi for management, copying the stream to the SSD and the network, and for providing status and preview on the 3.5"LCD.
  • an SSD attached to the bpi
  • an ethernet switch.
All of these things have to work together, and are hard to control. For instance, we are currently configuring the scaler through an IR led connected to the banana pi 3.5mm headphone socket, with specific pcm files being played to achieve specific menu steps, for changing the scaling resolution.

This is also a mass of cables, which adds a lot of potential for bad connections.

Finally, by having a scaler, then a splitter, then an encoder, we copy a lot of data around unnecessarily, and add needless overhead and latency, while wasting a lot of space and energy.

A solution

If we can get HDMI into the A20 SoC (through the camera connection), we can take advantage of a lot of functionality of the Allwinner A20, namely:

  • input scaling
  • open source h.264 encoding on cedrus
  • direct preview on the 3.5" lcd using overlays.
  • using the hdmi output for the projector, using the display engine for scaling to match the projector.
We then basically get a frame from the camera and scale it to a buffer, then use the same buffer 3 times; once for encoding, twice for scanout to both LCD and HDMI. While all of this will tax the system bus, nothing will be copied, apart from, of course, the h.264 encoded video.

We will need to create a custom HDMI to parallel RGB/YUV422/CCIR656 board that we can tie into the camera input connector. And if that is done, we simply need to fix up and write the driver support, and then tie everything together... Easy... Right?

Bandwidth?

If we use the 8bit parallel bus of the banana-pi connector, then we are forced to use YUV422 (at half the chrominance, losing fidelity), and have to use both rising and falling edges. In order to hit 1280x720@60Hz, we have to drive what is basically a 150MHz parallel signal over a 40pin FPC.

If we could use the full CSI bus, of CSI1, we can make use of 24bit data, at 75MHz. Sadly the banana pi does not provide those signals.

If we however take the Olimex A20 Lime2, we have almost all necessary io pins available on extensions headers.

The CSI1_D8 bit is sadly used by the LCD connector to provide LCD_PWR. Uwe made a very good suggestion to just ignore it. We fully expect this to be the lower bit of the Green channel, so in practice we will not notice this data missing. Tsvetan suggested that we can just use the PH8/LCD_PWR pin from the LCD connector, and use another, free, gpio pin to be our actual LCD_PWR line on our daughterboard.

Another advantage of using the lime2 is that we can develop a daughterboard that plugs on top of the existing board which will both be mechanically and electronically more stable than using yet another 40pin FPC. It offers us an affordable, relatively quick path to achieve our goal.

Preliminary design choices

The Analog Devices ADV7611 is a suitable device that is readily available. It is hand solderable, outputs RGB/YUV422/CCIR656 according to configuration (over i2c), has a built in DDC bus and (uploadable) edid rom. Datasheet and user manuals are readily available, and arrow has these in stock at around 8.5usd.

What's more, we have a hdmi to VGA converter (ligawo 6518829) which employs this very chip, with another one of probably the same make (Link-mi LM-HV01) en route. This has a very straightforward 2-layer board design.

For sound, we just plug straight through to the I2S io pins of the olimex lime2.

All of the lime extension connectors provide 5V and 3.3V. We will need a regulator for 1.8V for the ADV7611. The ADV7611 prefers a 28.6363MHz crystal.

We will need a hdmi connector, and some ESD protection for it (which can be gleaned from the olimex olinuxino schematics), and perhaps a gate-driver for the 5V HPD pin.

We might want to hook up power and reset to make life easy for the ADV7611, any free GPIO lines that cause the least routing issues can be chosen here.

Another addition is attaching a VGA connector to the exposed pins, so we can drive either HDMI or VGA from the secondary display pipeline. The cubietruck schematic has a sample circuit, but we will have to drive H/VSync from LCD1_HSYNC/VSYNC.

Existing OSHW board design

There was a project called "videobrick" started in the middle of 2014, to develop a HDMI input board for the olimex A10 lime, based off the ADV7611.

Here is their blog, a talk at the gstreamer conference, and their github account, with both the hardware designs and software work (for the allwinner kernel).

This is an amazing find and will massively boost our effort to design a daughterboard, as most of the groundwork has been done.

There were some issues with this design, and as stated in the gstreamer talk, the designers of this board were not too familiar with driver development. The fact that tried to flow solderpaste in a non-modified pizza oven does not bode well for their electronics experience either ;) So maybe we can improve on this with our comparatively vast team of experienced people on both sides.

Used A20 pins

  • 5V, 3.3V are exposed on every Lime2 io extension connector
  • full LCD0 interface on the LCD connector
    • Most things are probably wired straight through (verify me) to a 40pin FPC connector to match the banana-pi M1 LCD connector.
    • LCD_PWR/PH8 has to be wired to SDI1-D8, so that full 24 bit colour can be received from ADV7611
    • Any free gpio line (any free one from GPIO-1 seems sensible) can be used as LCD_PWR.
  • full I2S input on the GPIO-3 connector (PB5/MCLK, PB6/BCLK, PB7/LRCK, PB12/DI) attached to the ADV7611 I2S interface.
  • I2C on the GPIO-1 (TWI1-SCK/SDA) connector connected to I2C on the ADV7611
  • For the CSI link attached to the ADV7611
    • PCLK and H/Vsync on the GPIO-1 connector (PG0 and PG2, PG3)
    • DE is not needed for CSI1.
    • the first byte (R) on the GPIO-1 connector (PG4-PG11)
    • The lower bit of the middle byte (G) from the LCD connector (PH08/LCD_PWR)
    • The upper 7 bits of the middle byte (G) on the GPIO-3 connector (PH09-PH15)
    • The top byte (B) on the GPIO-3 connector (PH16-PH23)
  • For the VGA connector (make this a 2.54mm header to ease board design, trace length is not a big factor):
    • R, G, B on GPIO-1
    • LCD1_HSYNC and LCD1_VSYNC on GPIO-3 (PH26, PH27)
    • I2C from TWI2 on GPIO-1 (TWI2-SCK/SDA) for DDC.
  • Audio extension connector (optional 2.54mm header, for a future further daughterboard, trace length is not a factor).
    • +5V and GND from GPIO-1
    • +3.3V from either GPIO-1 or GPIO-4
    • HPOUTL, HPCOM, HPOUTR from GPIO-1
    • MICIN1 from GPIO-1
    • MICIN2 from GPIO-4

LCD connection list

LCD_01		FPC01		# +5V  == IPSOUT
LCD_01		FPC03		# +5V  == IPSOUT
LCD_02		FPC05		# GND  == GND0
LCD_04		FPC24		# GND  == GND1
LCD_05		FPC40		# PD16 == LCD_D16
LCD_06		FPC38		# PD17 == LCD_D17
LCD_07		FPC36		# PD18 == LCD_D18
LCD_08		FPC34		# PD19 == LCD_D19
LCD_09		FPC32		# PD20 == LCD_D20
LCD_10		FPC30		# PD21 == LCD_D21
LCD_11		FPC28		# PD22 == LCD_D22
LCD_12		FPC26		# PD23 == LCD_D23
LCD_13		FPC25		# PD08 == LCD_D08
LCD_14		FPC27		# PD09 == LCD_D09
LCD_15		FPC29		# PD10 == LCD_D10
LCD_16		FPC31		# PD11 == LCD_D11
LCD_17		FPC33		# PD12 == LCD_D12
LCD_18		FPC35		# PD13 == LCD_D13
LCD_19		FPC37		# PD14 == LCD_D14
LCD_20		FPC39		# PD15 == LCD_D15
LCD_21		FPC09		# PD00 == LCD_D00
LCD_22		FPC11		# PD01 == LCD_D01
LCD_23		FPC13		# PD02 == LCD_D02
LCD_24		FPC15		# PD03 == LCD_D03
LCD_25		FPC17		# PD04 == LCD_D04
LCD_26		FPC19		# PD05 == LCD_D05
LCD_27		FPC21		# PD06 == LCD_D06
LCD_28		FPC23		# PD07 == LCD_D07
LCD_29		FPC18		# PD26 == LCD_HSYNC
LCD_30		FPC16		# PD27 == LCD_VSYNC
LCD_31		FPC22		# PD24 == LCD_CLK (add 22 Ohm resistor, according to bpi schematic)
LCD_32		FPC14		# PD25 == LCD_DE
LCD_36		FPC10		# PB02 == PWM0

GPIO1_38	FPC07		# PC24 == LCD_PWR (can be trivially rewired to any free io line)
GPIO1_40	FPC08		# PC23 == LCD_IO1 (can be trivially rewired to any free io line)

NC		FPC02		# --  == TWI_SDA
NC		FPC04		# --  == TWI-SCK
NC		FPC06		# --  == LCD_IO0
NC		FPC12		# --  == LCD_IO2
NC		FPC20		# --  == LCD_CS

Software

There are 3 different tracks here.

1) Use KMS planes and hw h.264 decode

Currently, a lot of cpu is being used. By switching to sunxi hw h.264 decode and KMS with an overlay for the video, this should be brought down to a negligible amount. This can be done today.

2) Display decoded stream on HDMI out

This would prove double use of the decoded buffer. Depends on 1)

3) Test CSI (cmos sensor interface) in with bpi camera

2 such cameras are available. Pipe this straight out the overlay on the lcd and the hdmi connector. Can be tested separately, but could depend on 2)

4) Implement h.264 hw encoding

Partially RE-ed already. Can be done on raw streams.

5) Capture and encode line-in

So that this can be mixed into the stream, and so that cpu usage can be gauged.

6) re-use the captured CSI data for encoding

3 parallel uses of the csi buffers.

7) test ADV7611 support

And expand support to add 8bit support, edid upload, and further debugging.

Future

Since we are now starting with an olimex a20 lime2, we have 24bit RGB888 colour running at full 1280x720@60Hz.

We might want to do something similar for audio, and either have a daughterboard with 2 XLR inputs and 2 XLR outputs (GPIO-4), and perhaps some volume control that wires into the alsa mixer.

We could redesign this board to be an all-in affair, and add a (at least) 3 port Gigabit ethernet switch (like a KSZ9567RTXI) on the board, then we have everything we need then all we need is power-supply and an SSD.

As it stands though, this daughterboard and the related driver work, will put us lightyears ahead of where we are today.

Clone this wiki locally