Други ҺДМИ монитор на Распберри Пи3 преко ДПИ интерфејса и ФПГА плоче


Овај видео приказује: Распберри Пи3 плоча, повезана са њом преко ГПИО конектора је ФПГА плоча Марс Ровер2рпи (Цицлоне ИВ), на коју је повезан ХДМИ монитор. Други монитор је повезан преко стандардног ХДМИ конектора Распберри Пи3. Све функционише заједно као систем са двоструким монитором.

Затим ћу вам рећи како се ово спроводи.

Популарна Распберри Пи3 плоча има ГПИО конектор преко којег можете повезати различите картице за проширење: сензоре, ЛЕД диоде, драјвере корачних мотора и још много тога. Тачна функција сваког пина на конектору зависи од конфигурације порта. ГПИО АЛТ2 конфигурација вам омогућава да пребаците конектор у режим ДПИ интерфејса, Дисплаи Параллел Интерфаце. Постоје картице за проширење за повезивање ВГА монитора преко ДПИ. Међутим, прво, ВГА монитори више нису уобичајени као ХДМИ, а друго, дигитални интерфејс је све бољи од аналогног. Штавише, ДАЦ на таквим ВГА плочама за проширење се обично прави у облику Р-2-Р ланаца и често не више од 6 бита по боји.

У АЛТ2 режиму, пинови ГПИО конектора имају следеће значење:

Други ҺДМИ монитор на Распберри Пи3 преко ДПИ интерфејса и ФПГА плоче

Овде сам обојио РГБ пинове конектора црвеном, зеленом и плавом бојом. Други важни сигнали су В-СИНЦ и Х-СИНЦ сигнали, као и ЦЛК. Фреквенција ЦЛК такта је фреквенција на којој се вредности пиксела излазе на конектор; зависи од изабраног видео режима.

Да бисте повезали дигитални ХДМИ монитор, потребно је да ухватите ДПИ сигнале интерфејса и претворите их у ХДМИ сигнале. Ово се може урадити, на пример, помоћу неке врсте ФПГА плоче. Како се испоставило, плоча Марс Ровер2рпи је погодна за ове сврхе. Истина, главна опција за повезивање ове плоче преко посебног адаптера изгледа овако:

Други ҺДМИ монитор на Распберри Пи3 преко ДПИ интерфејса и ФПГА плоче

Ова плоча се користи за повећање броја ГПИО портова и за повезивање више периферних уређаја на малину. Истовремено, 4 ГПИО сигнала са овом везом се користе за ЈТАГ сигнале, тако да програм из Распберри-а може учитати ФПГА фирмвер у ФПГА. Због тога ми ова стандардна веза не одговара, испадају 4 ДПИ сигнала. На срећу, додатни чешљеви на плочи имају пиноут компатибилан са Распберри. Тако да могу да окренем плочу за 90 степени и још увек је повежем са мојом малином:

Други ҺДМИ монитор на Распберри Пи3 преко ДПИ интерфејса и ФПГА плоче

Наравно, мораћете да користите екстерни ЈТАГ програматор, али то није проблем.

Још увек постоји мали проблем. Не може се сваки ФПГА пин користити као улаз за сат. Постоји само неколико наменских иглица које се могу користити у ове сврхе. Тако се овде испоставило да ГПИО_0 ЦЛК сигнал не стиже до ФПГА улаза, који се може користити као ФПГА улаз такта. Тако да сам ипак морао да ставим једну жицу на шал. Повезујем ГПИО_0 и сигнал КЕИ[1] плоче:

Други ҺДМИ монитор на Распберри Пи3 преко ДПИ интерфејса и ФПГА плоче

Сада ћу вам рећи нешто о ФПГА пројекту. Главна потешкоћа у генерисању ХДМИ сигнала су веома високе фреквенције. Ако погледате пиноут ХДМИ конектора, можете видети да су РГБ сигнали сада серијски диференцијални сигнали:

Други ҺДМИ монитор на Распберри Пи3 преко ДПИ интерфејса и ФПГА плоче

Употреба диференцијалног сигнала вам омогућава да се борите против сметњи заједничког режима на далеководу. У овом случају, оригинални осмобитни код сваког сигнала у боји се конвертује у 10-битни ТМДС (диференцијална сигнализација минимизирана транзицијом). Ово је посебан метод кодирања за уклањање ДЦ компоненте из сигнала и минимизирање пребацивања сигнала у диференцијалној линији. Пошто 10 битова сада треба да се пренесе преко серијске линије за један бајт боје, испада да брзина такта серијализатора мора бити 10 пута већа од брзине такта пиксела. Ако узмемо на пример видео режим 1280к720 60Хз, онда је фреквенција пиксела овог режима 74,25 МХз. Сериализатор треба да буде 742,5 МХз.

Обични ФПГА, нажалост, нису способни за ово. Међутим, на нашу срећу, ФПГА има уграђене ДДИО пинове. То су закључци који су већ такорећи серијализатори 2 према 1. То јест, они могу да емитују два бита узастопно на растућој и опадајућој ивици фреквенције такта. То значи да у ФПГА пројекту можете користити не 740 МХз, већ 370 МХз, али морате користити ДДИО излазне елементе у ФПГА. Сада је 370 МХз већ потпуно достижна фреквенција. Нажалост, режим 1280к720 је ограничење. Већа резолуција се не може постићи у нашем Цицлоне ИВ ФПГА инсталираном на Марс Ровер2рпи плочи.

Дакле, у дизајну, улазна фреквенција пиксела ЦЛК иде у ПЛЛ, где се множи са 5. На овој фреквенцији, бајтови Р, Г, Б се претварају у парове битова. То је оно што ради ТМДС енкодер. Изворни код у Верилог ХДЛ-у изгледа овако:

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

Затим се излазни парови доводе до ДДИО излаза, који секвенцијално производи једнобитни сигнал на растућој и опадајућој ивици.

Сам ДДИО би се могао описати следећим Верилог кодом:

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

Али највероватније неће функционисати на тај начин. Морате да користите Алтерову мегафункцију АЛТДДИО_ОУТ да бисте заправо омогућили ДДИО излазне елементе. Мој пројекат користи компоненту библиотеке АЛТДДИО_ОУТ.

Све ово може изгледати мало незгодно, али функционише.

Можете погледати сав изворни код написан у Верилог ХДЛ-у овде на гитхуб-у.

Преведени фирмвер за ФПГА се флешује у ЕПЦС чип инсталиран на Марс Ровер2рпи плочи. Дакле, када се напајање примени на ФПГА плочу, ФПГА ће се иницијализовати из флеш меморије и покренути.

Сада морамо мало да причамо о конфигурацији самог Распберри.

Радим експерименте на Распберри ПИ ОС (32 бит) заснованом на Дебиан Бустер-у, верзија: август 2020,
Датум издавања: 2020, верзија кернела: 08.

Треба да урадите две ствари:

  • уредите датотеку цонфиг.ткт;
  • креирајте конфигурацију Кс сервера за рад са два монитора.

Када уређујете /боот/цонфиг.ткт датотеку потребно вам је:

  1. онемогући употребу и2ц, и2с, спи;
  2. омогући ДПИ режим помоћу преклапања дтоверлаи=дпи24;
  3. конфигуришите видео режим 1280×720 60Хз, 24 бита по пикселу на ДПИ;
  4. наведите потребан број фрамебуффера 2 (мак_фрамебуфферс=2, тек тада ће се појавити други уређај /дев/фб1)

Пун текст датотеке цонфиг.ткт изгледа овако.

# 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

Након овога, потребно је да креирате конфигурациону датотеку за Кс сервер да користи два монитора на два фрамебуффера /дев/фб0 и /дев/фб1:

Моја конфигурациона датотека /уср/схаре/к11/корг.цонф.д/60-дуалсцреен.цонф је оваква

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

Па, ако већ није инсталиран, онда морате да инсталирате Ксинераму. Тада ће простор радне површине бити у потпуности проширен на два монитора, као што је приказано у демо видеу изнад.

То је вероватно све. Сада ће власници Распберри Пи3 моћи да користе два монитора.

Опис и шема кола Марс Ровер2рпи плоче се могу наћи погледати овде.

Извор: ввв.хабр.цом