It-tieni monitor HDMI għal Raspberry Pi3 permezz ta 'interface DPI u bord FPGA


Dan il-video juri: bord Raspberry Pi3, imqabbad miegħu permezz tal-konnettur GPIO huwa bord FPGA Mars Rover2rpi (Cyclone IV), li miegħu huwa konness monitor HDMI. It-tieni monitor huwa konness permezz tal-konnettur HDMI standard tal-Raspberry Pi3. Kollox jaħdem flimkien bħal sistema ta 'moniter doppju.

Sussegwentement ngħidlek kif dan jiġi implimentat.

Il-bord popolari Raspberry Pi3 għandu konnettur GPIO li permezz tiegħu tista 'tqabbad diversi karti ta' espansjoni: sensuri, LEDs, sewwieqa tal-muturi stepper u ħafna aktar. Il-funzjoni eżatta ta 'kull pin fuq konnettur tiddependi fuq il-konfigurazzjoni tal-port. Il-konfigurazzjoni GPIO ALT2 tippermettilek taqleb il-konnettur għall-modalità tal-interface DPI, Display Parallel Interface. Hemm karti ta 'espansjoni għall-konnessjoni ta' monitors VGA permezz ta 'DPI. Madankollu, l-ewwelnett, il-moniters VGA m'għadhomx komuni daqs l-HDMI, u t-tieni, l-interface diġitali hija dejjem aktar aħjar minn dik analoga. Barra minn hekk, id-DAC fuq tali bordijiet ta 'espansjoni VGA normalment isir fil-forma ta' ktajjen R-2-R u ħafna drabi mhux aktar minn 6 bits għal kull kulur.

Fil-modalità ALT2, il-pinnijiet tal-konnettur GPIO għandhom it-tifsira li ġejja:

It-tieni monitor HDMI għal Raspberry Pi3 permezz ta 'interface DPI u bord FPGA

Hawnhekk ikkulurit il-brilli RGB tal-konnettur aħmar, aħdar u blu rispettivament. Sinjali importanti oħra huma s-sinjali V-SYNC u H-SYNC, kif ukoll CLK. Il-frekwenza tal-arloġġ CLK hija l-frekwenza li fiha l-valuri tal-pixel jinħarġu lill-konnettur; tiddependi fuq il-mod tal-vidjo magħżul.

Biex tikkonnettja monitor HDMI diġitali, għandek bżonn taqbad is-sinjali DPI tal-interface u tikkonvertihom għal sinjali HDMI. Dan jista 'jsir, pereżempju, bl-użu ta' xi tip ta 'bord FPGA. Kif jirriżulta, il-bord Mars Rover2rpi huwa adattat għal dawn l-għanijiet. Fil-verità, l-għażla ewlenija għall-konnessjoni ta 'dan il-bord permezz ta' adapter speċjali tidher bħal din:

It-tieni monitor HDMI għal Raspberry Pi3 permezz ta 'interface DPI u bord FPGA

Dan il-bord jintuża biex iżid in-numru ta 'portijiet GPIO u biex jgħaqqad aktar apparati periferali mal-lampun. Fl-istess ħin, 4 sinjali GPIO b'din il-konnessjoni jintużaw għal sinjali JTAG, sabiex il-programm minn Raspberry jista 'jtella' l-firmware FPGA fl-FPGA. Minħabba dan, din il-konnessjoni standard ma taqbilx lili; 4 sinjali DPI jitilqu. Fortunatament, il-pettijiet addizzjonali fuq il-bord għandhom pinout kompatibbli mal-Raspberry. Allura nista' ndawwar il-bord 90 grad u xorta nqabbadha mal-lampun tiegħi:

It-tieni monitor HDMI għal Raspberry Pi3 permezz ta 'interface DPI u bord FPGA

Naturalment, ser ikollok tuża programmatur JTAG estern, iżda din mhix problema.

Għad hemm problema żgħira. Mhux kull pin FPGA jista 'jintuża bħala input ta' arloġġ. Hemm biss ftit pinnijiet dedikati li jistgħu jintużaw għal dawn l-għanijiet. Allura rriżulta hawnhekk li s-sinjal GPIO_0 CLK ma jilħaqx l-input FPGA, li jista 'jintuża bħala input ta' arloġġ FPGA. Allura xorta kelli npoġġi wajer wieħed fuq ix-xalpa. Ngħaqqad GPIO_0 u s-sinjal KEY[1] tal-bord:

It-tieni monitor HDMI għal Raspberry Pi3 permezz ta 'interface DPI u bord FPGA

Issa ngħidlek ftit dwar il-proġett FPGA. Id-diffikultà ewlenija fil-ġenerazzjoni tas-sinjali HDMI hija frekwenzi għoljin ħafna. Jekk tħares lejn il-pinout tal-konnettur HDMI, tista 'tara li s-sinjali RGB issa huma sinjali differenzjali serjali:

It-tieni monitor HDMI għal Raspberry Pi3 permezz ta 'interface DPI u bord FPGA

L-użu ta 'sinjal differenzjali jippermettilek tiġġieled l-interferenza tal-mod komuni fuq il-linja ta' trażmissjoni. F'dan il-każ, il-kodiċi oriġinali ta 'tmien bit ta' kull sinjal tal-kulur huwa kkonvertit f'TMDS ta '10 bit (sinjalazzjoni differenzjali minimizzata mit-tranżizzjoni). Dan huwa metodu ta 'kodifikazzjoni speċjali biex jitneħħa l-komponent DC mis-sinjal u jimminimizza l-bidla tas-sinjal f'linja differenzjali. Peress li 10 bits issa jeħtieġ li jiġu trażmessi fuq il-linja tas-serje għal byte wieħed ta 'kulur, jirriżulta li l-veloċità tal-arloġġ tas-serializer għandha tkun 10 darbiet ogħla mill-veloċità tal-arloġġ tal-pixel. Jekk nieħdu pereżempju l-modalità tal-vidjo 1280x720 60Hz, allura l-frekwenza tal-pixel ta 'din il-modalità hija 74,25 MHz. Is-serializzatur għandu jkun 742,5 MHz.

FPGAs regolari, sfortunatament, mhumiex kapaċi għal dan. Madankollu, fortunatament għalina, l-FPGA għandha pinnijiet DDIO mibnija. Dawn huma konklużjonijiet li huma diġà, kif kien, serializzaturi 2-to-1. Jiġifieri, jistgħu joħorġu żewġ bits b'mod sekwenzjali fuq it-truf li jogħlew u nieżel tal-frekwenza tal-arloġġ. Dan ifisser li fi proġett FPGA tista 'tuża mhux 740 MHz, iżda 370 MHz, iżda trid tuża elementi ta' output DDIO fl-FPGA. Issa 370 MHz diġà hija frekwenza li tista' tintlaħaq kompletament. Sfortunatament, il-modalità 1280x720 hija l-limitu. Ma tistax tinkiseb riżoluzzjoni ogħla fiċ-Ċiklun IV tagħna FPGA installat fuq il-bord Mars Rover2rpi.

Allura, fid-disinn, il-frekwenza tal-pixel tal-input CLK tmur għall-PLL, fejn hija mmultiplikata b'5. F'din il-frekwenza, il-bytes R, G, B huma kkonvertiti f'pari ta 'bits. Dan huwa dak li jagħmel l-encoder TMDS. Il-kodiċi tas-sors f'Verilog HDL jidher bħal dan:

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

Imbagħad il-pari tal-output jiġu mitmugħa lill-output tad-DDIO, li b'mod sekwenzjali jipproduċi sinjal ta 'bit wieħed fuq it-truf li qed jogħlew u li jinżlu.

Id-DDIO innifsu jista' jiġi deskritt bil-kodiċi Verilog li ġej:

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

Iżda x'aktarx mhux se taħdem hekk. Għandek bżonn tuża l-megafunzjoni ALTDDIO_OUT ta 'Alter biex fil-fatt tippermetti l-elementi tal-output tad-DDIO. Il-proġett tiegħi juża l-komponent tal-librerija ALTDDIO_OUT.

Dan kollu jista 'jidher ftit delikat, iżda jaħdem.

Tista' tara l-kodiċi sors kollu miktub f'Verilog HDL hawn fuq github.

Il-firmware ikkumpilat għall-FPGA jiġi flashed fiċ-ċippa EPCS installata fuq il-bord Mars Rover2rpi. Għalhekk, meta l-enerġija tiġi applikata fuq il-bord FPGA, l-FPGA se tiġi inizjalizzata mill-memorja flash u tibda.

Issa rridu nitkellmu ftit dwar il-konfigurazzjoni tal-Raspberry innifsu.

Qed nagħmel esperimenti fuq Raspberry PI OS (32 bit) ibbażati fuq Debian Buster, Verżjoni:Awissu 2020,
Data tar-rilaxx:2020-08-20, Verżjoni tal-kernel:5.4.

Trid tagħmel żewġ affarijiet:

  • editja l-fajl config.txt;
  • toħloq konfigurazzjoni ta 'server X biex taħdem ma' żewġ monitors.

Meta teditja l-fajl /boot/config.txt għandek bżonn:

  1. tiddiżattiva l-użu ta 'i2c, i2s, spi;
  2. ippermetti l-modalità DPI billi tuża overlay dtoverlay=dpi24;
  3. kkonfigurat il-mod tal-vidjo 1280 × 720 60Hz, 24 bits kull pixel fuq DPI;
  4. speċifika n-numru meħtieġ ta' framebuffers 2 (max_framebuffers=2, allura biss jidher it-tieni apparat /dev/fb1)

It-test sħiħ tal-fajl config.txt jidher bħal dan.

# 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

Wara dan, trid toħloq fajl ta' konfigurazzjoni għas-server X biex juża żewġ monitors fuq żewġ framebuffers /dev/fb0 u /dev/fb1:

Il-fajl tal-konfigurazzjoni tiegħi /usr/share/x11/xorg.conf.d/60-dualscreen.conf huwa bħal dan

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

Ukoll, jekk ma jkunx diġà installat, allura għandek bżonn tinstalla Xinerama. Imbagħad l-ispazju tad-desktop se jiġi estiż għal kollox għal żewġ monitors, kif muri fil-video demo hawn fuq.

Dak huwa probabbilment kollox. Issa, is-sidien tar-Raspberry Pi3 se jkunu jistgħu jużaw żewġ monitors.

Id-deskrizzjoni u d-dijagramma taċ-ċirkwit tal-bord Mars Rover2rpi jistgħu jinstabu ara hawn.

Sors: www.habr.com