An dara monatóir HDMI go Raspberry Pi3 trí chomhéadan DPI agus bord FPGA


Léiríonn an físeán seo: is bord FPGA Mars Rover3rpi (Cioclón IV) é bord Raspberry Pi2, ceangailte leis tríd an gcónascaire GPIO, a bhfuil monatóir HDMI nasctha leis. Tá an dara monatóir ceangailte trí nascóir caighdeánach HDMI an Raspberry Pi3. Oibríonn gach rud le chéile cosúil le córas monatóireachta dé.

Ansin inseoidh mé duit conas a chuirtear é seo i bhfeidhm.

Tá cónascaire GPIO ag an mbord tóir Raspberry Pi3 trínar féidir leat cártaí leathnaithe éagsúla a nascadh: braiteoirí, stiúir, tiománaithe mótair stepper agus go leor eile. Braitheann feidhm chruinn gach bioráin ar chónascaire ar chumraíocht an chalafoirt. Ligeann cumraíocht GPIO ALT2 duit an cónascaire a athrú go mód comhéadan DPI, Comhéadan Comhthreomhar Taispeána. Tá cártaí leathnaithe ann chun monatóirí VGA a nascadh trí DPI. Ar an gcéad dul síos, áfach, níl monatóirí VGA chomh coitianta le HDMI a thuilleadh, agus ar an dara dul síos, tá an comhéadan digiteach ag éirí níos fearr ná an comhéadan analógach. Thairis sin, is gnách go ndéantar an DAC ar bhoird leathnaithe VGA den sórt sin i bhfoirm slabhraí R-2-R agus go minic nach mó ná 6 giotán in aghaidh an dath.

I mód ALT2, tá an bhrí seo a leanas ag bioráin nascóirí GPIO:

An dara monatóir HDMI go Raspberry Pi3 trí chomhéadan DPI agus bord FPGA

Anseo tá na bioráin RGB den chónascaire daite agam dearg, glas agus gorm faoi seach. Comharthaí tábhachtacha eile is ea na comharthaí V-SYNC agus H-SYNC, chomh maith le CLK. Is é minicíocht clog CLK an mhinicíocht ag a ndéantar luachanna picteilín a aschur chuig an gcónascaire; braitheann sé ar an modh físe roghnaithe.

Chun monatóir digiteach HDMI a nascadh, ní mór duit comharthaí DPI an chomhéadain a ghabháil agus iad a thiontú go comharthaí HDMI. Is féidir é seo a dhéanamh, mar shampla, ag baint úsáide as cineál éigin de bhord FPGA. Mar a tharla sé, tá bord Mars Rover2rpi oiriúnach chun na gcríoch seo. Go deimhin, is é seo an príomh-rogha chun an bord seo a nascadh trí oiriúntóir speisialta:

An dara monatóir HDMI go Raspberry Pi3 trí chomhéadan DPI agus bord FPGA

Úsáidtear an bord seo chun líon na gcalafort GPIO a mhéadú agus chun feistí níos forimeallacha a nascadh leis an sú craobh. Ag an am céanna, úsáidtear 4 chomhartha GPIO leis an nasc seo le haghaidh comharthaí JTAG, ionas gur féidir leis an gclár ó Sú craobh an firmware FPGA a luchtú isteach sa FPGA. Mar gheall air seo, ní oireann an nasc caighdeánach seo domsa; titeann 4 chomhartha DPI amach. Ar ámharaí an tsaoil, tá pinout oiriúnach do sú craobh ag na cíora breise ar an gclár. Mar sin is féidir liom an bord a rothlú 90 céim agus é a nascadh le mo sú craobh:

An dara monatóir HDMI go Raspberry Pi3 trí chomhéadan DPI agus bord FPGA

Ar ndóigh, beidh ort ríomhchláraitheoir seachtrach JTAG a úsáid, ach ní fadhb é seo.

Tá fadhb bheag fós ann. Ní féidir gach bioráin FPGA a úsáid mar ionchur clog. Níl ach cúpla bioráin tiomnaithe is féidir a úsáid chun na gcríoch sin. Mar sin d'éirigh sé amach anseo nach sroicheann an comhartha GPIO_0 CLK ionchur FPGA, is féidir a úsáid mar ionchur clog FPGA. Mar sin bhí orm fós sreang amháin a chur ar an scairf. Ceanglaím GPIO_0 agus comhartha KEY[1] an bhoird:

An dara monatóir HDMI go Raspberry Pi3 trí chomhéadan DPI agus bord FPGA

Anois inseoidh mé beagán duit faoi thionscadal FPGA. Is é an deacracht is mó maidir le comharthaí HDMI a ghiniúint minicíochtaí an-ard. Má fhéachann tú ar an nascóir HDMI piléar, is féidir leat a fheiceáil gur comharthaí difreálach sraitheacha iad na comharthaí RGB anois:

An dara monatóir HDMI go Raspberry Pi3 trí chomhéadan DPI agus bord FPGA

Ligeann úsáid comhartha difreálach duit cur isteach modh coitianta ar an líne tarchurtha a chomhrac. Sa chás seo, déantar an cód bunaidh ocht-giotán de gach comhartha datha a thiontú ina TMDS 10-giotán (Comharthaíocht dhifreálach idirthréimhse-íoslaghdaithe). Is modh códaithe speisialta é seo chun an comhpháirt DC a bhaint as an comhartha agus an t-athrú comhartha i líne difreálach a íoslaghdú. Ós rud é go gcaithfear 10 ngiotán a tharchur thar an sraitheach le haghaidh beart amháin datha, tarlaíonn sé go gcaithfidh luas clog an tsrathaitheora a bheith 10 n-uaire níos airde ná an luas clog picteilín. Má thógaimid mar shampla an modh físe 1280x720 60Hz, ansin is é 74,25 MHz minicíocht picteilín an mhód seo. Ba cheart go mbeadh an sraitheach 742,5 MHz.

Ar an drochuair, níl FPGAanna rialta in ann é seo a dhéanamh. Mar sin féin, go fortunately dúinn, tá bioráin DIO ionsuite ag an FPGA. Is conclúidí iad seo atá cheana féin, mar a bhí, sraitheoirí 2-go-1. Is é sin, is féidir leo dhá ghiotán a aschur go seicheamhach ar imill ardú agus titim na minicíochta clog. Ciallaíonn sé seo nach féidir leat 740 MHz, ach 370 MHz a úsáid i dtionscadal FPGA, ach ní mór duit eilimintí aschuir DIO a úsáid sa FPGA. Anois tá 370 MHz ina mhinicíocht iomlán insroichte cheana féin. Ar an drochuair, is é mód 1280x720 an teorainn. Ní féidir réiteach níos airde a bhaint amach inár FPGA Cyclone IV atá suiteáilte ar an mbord Mars Rover2rpi.

Mar sin, sa dearadh, téann an minicíocht picteilín ionchuir CLK chuig an PLL, áit a bhfuil sé iolraithe faoi 5. Ag an minicíocht seo, déantar na bytes R, G, B a thiontú ina mbeirteanna giotán. Seo a dhéanann an t-ionchódóir TMDS. Breathnaíonn an cód foinse i Verilog HDL mar seo:

module hdmi(
	input wire pixclk,		// 74MHz
	input wire clk_TMDS2,	// 370MHz
	input wire hsync,
	input wire vsync,
	input wire active,
	input wire [7:0]red,
	input wire [7:0]green,
	input wire [7:0]blue,
	output wire TMDS_bh,
	output wire TMDS_bl,
	output wire TMDS_gh,
	output wire TMDS_gl,
	output wire TMDS_rh,
	output wire TMDS_rl
);

wire [9:0] TMDS_red, TMDS_green, TMDS_blue;
TMDS_encoder encode_R(.clk(pixclk), .VD(red  ), .CD({vsync,hsync}), .VDE(active), .TMDS(TMDS_red));
TMDS_encoder encode_G(.clk(pixclk), .VD(green), .CD({vsync,hsync}), .VDE(active), .TMDS(TMDS_green));
TMDS_encoder encode_B(.clk(pixclk), .VD(blue ), .CD({vsync,hsync}), .VDE(active), .TMDS(TMDS_blue));

reg [2:0] TMDS_mod5=0;  // modulus 5 counter
reg [4:0] TMDS_shift_bh=0, TMDS_shift_bl=0;
reg [4:0] TMDS_shift_gh=0, TMDS_shift_gl=0;
reg [4:0] TMDS_shift_rh=0, TMDS_shift_rl=0;

wire [4:0] TMDS_blue_l  = {TMDS_blue[9],TMDS_blue[7],TMDS_blue[5],TMDS_blue[3],TMDS_blue[1]};
wire [4:0] TMDS_blue_h  = {TMDS_blue[8],TMDS_blue[6],TMDS_blue[4],TMDS_blue[2],TMDS_blue[0]};
wire [4:0] TMDS_green_l = {TMDS_green[9],TMDS_green[7],TMDS_green[5],TMDS_green[3],TMDS_green[1]};
wire [4:0] TMDS_green_h = {TMDS_green[8],TMDS_green[6],TMDS_green[4],TMDS_green[2],TMDS_green[0]};
wire [4:0] TMDS_red_l   = {TMDS_red[9],TMDS_red[7],TMDS_red[5],TMDS_red[3],TMDS_red[1]};
wire [4:0] TMDS_red_h   = {TMDS_red[8],TMDS_red[6],TMDS_red[4],TMDS_red[2],TMDS_red[0]};

always @(posedge clk_TMDS2)
begin
	TMDS_shift_bh <= TMDS_mod5[2] ? TMDS_blue_h  : TMDS_shift_bh  [4:1];
	TMDS_shift_bl <= TMDS_mod5[2] ? TMDS_blue_l  : TMDS_shift_bl  [4:1];
	TMDS_shift_gh <= TMDS_mod5[2] ? TMDS_green_h : TMDS_shift_gh  [4:1];
	TMDS_shift_gl <= TMDS_mod5[2] ? TMDS_green_l : TMDS_shift_gl  [4:1];
	TMDS_shift_rh <= TMDS_mod5[2] ? TMDS_red_h   : TMDS_shift_rh  [4:1];
	TMDS_shift_rl <= TMDS_mod5[2] ? TMDS_red_l   : TMDS_shift_rl  [4:1];
	TMDS_mod5 <= (TMDS_mod5[2]) ? 3'd0 : TMDS_mod5+3'd1;
end

assign TMDS_bh = TMDS_shift_bh[0];
assign TMDS_bl = TMDS_shift_bl[0];
assign TMDS_gh = TMDS_shift_gh[0];
assign TMDS_gl = TMDS_shift_gl[0];
assign TMDS_rh = TMDS_shift_rh[0];
assign TMDS_rl = TMDS_shift_rl[0];

endmodule

module TMDS_encoder(
	input clk,
	input [7:0] VD,	// video data (red, green or blue)
	input [1:0] CD,	// control data
	input VDE,  	// video data enable, to choose between CD (when VDE=0) and VD (when VDE=1)
	output reg [9:0] TMDS = 0
);

wire [3:0] Nb1s = VD[0] + VD[1] + VD[2] + VD[3] + VD[4] + VD[5] + VD[6] + VD[7];
wire XNOR = (Nb1s>4'd4) || (Nb1s==4'd4 && VD[0]==1'b0);
wire [8:0] q_m = {~XNOR, q_m[6:0] ^ VD[7:1] ^ {7{XNOR}}, VD[0]};

reg [3:0] balance_acc = 0;
wire [3:0] balance = q_m[0] + q_m[1] + q_m[2] + q_m[3] + q_m[4] + q_m[5] + q_m[6] + q_m[7] - 4'd4;
wire balance_sign_eq = (balance[3] == balance_acc[3]);
wire invert_q_m = (balance==0 || balance_acc==0) ? ~q_m[8] : balance_sign_eq;
wire [3:0] balance_acc_inc = balance - ({q_m[8] ^ ~balance_sign_eq} & ~(balance==0 || balance_acc==0));
wire [3:0] balance_acc_new = invert_q_m ? balance_acc-balance_acc_inc : balance_acc+balance_acc_inc;
wire [9:0] TMDS_data = {invert_q_m, q_m[8], q_m[7:0] ^ {8{invert_q_m}}};
wire [9:0] TMDS_code = CD[1] ? (CD[0] ? 10'b1010101011 : 10'b0101010100) : (CD[0] ? 10'b0010101011 : 10'b1101010100);

always @(posedge clk) TMDS <= VDE ? TMDS_data : TMDS_code;
always @(posedge clk) balance_acc <= VDE ? balance_acc_new : 4'h0;

endmodule

Ansin cuirtear na péirí aschuir chuig an aschur DIO, a tháirgeann comhartha aon-ghiotán go seicheamhach ar na himill ardú agus titim.

D’fhéadfaí cur síos a dhéanamh ar DIO féin leis an gcód Verilog seo a leanas:

module ddio(
	input wire d0,
	input wire d1,
	input wire clk,
	output wire out
	);

reg r_d0;
reg r_d1;
always @(posedge clk)
begin
	r_d0 <= d0;
	r_d1 <= d1;
end
assign out = clk ? r_d0 : r_d1;
endmodule

Ach is dócha nach n-oibreoidh sé mar sin. Ní mór duit meigefheidhm Alter ALTDDIO_OUT a úsáid chun na heilimintí aschuir DIO a chumasú. Úsáideann mo thionscadal an chomhpháirt leabharlainne ALTDDIO_OUT.

Féadfaidh sé seo go léir breathnú beagán tricky, ach oibríonn sé.

Is féidir leat an cód foinse ar fad atá scríofa in Verilog HDL a fheiceáil anseo ar github.

Tá an firmware tiomsaithe don FPGA flashed isteach sa sliseanna EPCS atá suiteáilte ar an mbord Mars Rover2rpi. Mar sin, nuair a chuirtear an chumhacht i bhfeidhm ar bhord FPGA, déanfar an FPGA a thúsú ó chuimhne flash agus tús.

Anois ní mór dúinn labhairt beagán faoi chumraíocht an sú craobh féin.

Tá turgnaimh á ndéanamh agam ar Raspberry PI OS (32 giotán) bunaithe ar Debian Buster, Leagan: Lúnasa 2020,
Dáta eisiúna: 2020-08-20, leagan Eithne: 5.4.

Ní mór duit dhá rud a dhéanamh:

  • cuir an comhad config.txt in eagar;
  • cruthaigh cumraíocht freastalaí X chun oibriú le dhá mhonatóir.

Agus an comhad /boot/config.txt á chur in eagar, beidh ort:

  1. díchumasaigh úsáid i2c, i2s, spi;
  2. mód PSO a chumasú trí úsáid a bhaint as forleagan dtoverlay=dpi24;
  3. cumraigh mód físeáin 1280 × 720 60Hz, 24 giotán in aghaidh an picteilín ar PSO;
  4. sonraigh an líon riachtanach maoláin fhráma 2 (max_framebuffers = 2, is ansin a bheidh an dara gléas /dev/fb1 le feiceáil)

Breathnaíonn téacs iomlán an chomhaid config.txt mar seo.

# For more options and information see
# http://rpf.io/configtxt
# Some settings may impact device functionality. See link above for details

# uncomment if you get no picture on HDMI for a default "safe" mode
#hdmi_safe=1

# uncomment this if your display has a black border of unused pixels visible
# and your display can output without overscan
disable_overscan=1

# uncomment the following to adjust overscan. Use positive numbers if console
# goes off screen, and negative if there is too much border
#overscan_left=16
#overscan_right=16
#overscan_top=16
#overscan_bottom=16

# uncomment to force a console size. By default it will be display's size minus
# overscan.
#framebuffer_width=1280
#framebuffer_height=720

# uncomment if hdmi display is not detected and composite is being output
hdmi_force_hotplug=1

# uncomment to force a specific HDMI mode (this will force VGA)
#hdmi_group=1
#hdmi_mode=1

# uncomment to force a HDMI mode rather than DVI. This can make audio work in
# DMT (computer monitor) modes
#hdmi_drive=2

# uncomment to increase signal to HDMI, if you have interference, blanking, or
# no display
#config_hdmi_boost=4

# uncomment for composite PAL
#sdtv_mode=2

#uncomment to overclock the arm. 700 MHz is the default.
#arm_freq=800

# Uncomment some or all of these to enable the optional hardware interfaces
#dtparam=i2c_arm=on
#dtparam=i2s=on
#dtparam=spi=on

dtparam=i2c_arm=off
dtparam=spi=off
dtparam=i2s=off

dtoverlay=dpi24
overscan_left=0
overscan_right=0
overscan_top=0
overscan_bottom=0
framebuffer_width=1280
framebuffer_height=720
display_default_lcd=0
enable_dpi_lcd=1
dpi_group=2
dpi_mode=87
#dpi_group=1
#dpi_mode=4
dpi_output_format=0x6f027
dpi_timings=1280 1 110 40 220 720 1 5 5 20 0 0 0 60 0 74000000 3

# Uncomment this to enable infrared communication.
#dtoverlay=gpio-ir,gpio_pin=17
#dtoverlay=gpio-ir-tx,gpio_pin=18

# Additional overlays and parameters are documented /boot/overlays/README

# Enable audio (loads snd_bcm2835)
dtparam=audio=on

[pi4]
# Enable DRM VC4 V3D driver on top of the dispmanx display stack
#dtoverlay=vc4-fkms-v3d
max_framebuffers=2

[all]
#dtoverlay=vc4-fkms-v3d
max_framebuffers=2

Ina dhiaidh seo, ní mór duit comhad cumraíochta a chruthú don fhreastalaí X chun dhá mhonatóir a úsáid ar dhá mhaolán fráma /dev/fb0 agus /dev/fb1:

Tá mo chomhad cumraíochta /usr/share/x11/xorg.conf.d/60-dualscreen.conf mar seo

Section "Device"
        Identifier      "LCD"
        Driver          "fbturbo"
        Option          "fbdev" "/dev/fb0"
        Option          "ShadowFB" "off"
        Option          "SwapbuffersWait" "true"
EndSection

Section "Device"
        Identifier      "HDMI"
        Driver          "fbturbo"
        Option          "fbdev" "/dev/fb1"
        Option          "ShadowFB" "off"
        Option          "SwapbuffersWait" "true"
EndSection

Section "Monitor"
        Identifier      "LCD-monitor"
        Option          "Primary" "true"
EndSection

Section "Monitor"
        Identifier      "HDMI-monitor"
        Option          "RightOf" "LCD-monitor"
EndSection

Section "Screen"
        Identifier      "screen0"
        Device          "LCD"
        Monitor         "LCD-monitor"
EndSection

Section "Screen"
        Identifier      "screen1"
        Device          "HDMI" 
	Monitor         "HDMI-monitor"
EndSection

Section "ServerLayout"
        Identifier      "default"
        Option          "Xinerama" "on"
        Option          "Clone" "off"
        Screen 0        "screen0"
        Screen 1        "screen1" RightOf "screen0"
EndSection

Bhuel, mura bhfuil sé suiteáilte cheana féin, ansin ní mór duit Xinerama a shuiteáil. Ansin leathnófar an spás deisce go hiomlán chuig dhá mhonatóir, mar a thaispeántar san fhíseán taispeána thuas.

Sin é is dócha. Anois, beidh úinéirí Raspberry Pi3 in ann dhá mhonatóir a úsáid.

Is féidir cur síos agus léaráid chiorcaid de bhord Mars Rover2rpi a fháil féach anseo.

Foinse: will.com