Монитори дуюми HDMI ба Raspberry Pi3 тавассути интерфейси DPI ва тахтаи FPGA


Ин видео нишон медиҳад: тахтаи Raspberry Pi3, ки ба он тавассути пайвасткунаки GPIO, тахтаи FPGA Mars Rover2rpi (Cyclone IV) пайваст шудааст, ки ба он монитор HDMI пайваст шудааст. Монитори дуюм тавассути пайвасткунаки стандартии Raspberry Pi3 HDMI пайваст карда шудааст. Ҳама якҷоя он ҳамчун системаи мониторҳои дугона кор мекунад.

Минбаъд ман ба шумо мегӯям, ки он чӣ гуна амалӣ карда мешавад.

Тахтаи машҳури Raspberry Pi3 дорои пайвасткунаки GPIO мебошад, ки тавассути он шумо метавонед тахтаҳои гуногуни васеъкуниро пайваст кунед: сенсорҳо, LEDҳо, драйверҳои мотори қадам ва ғайра. Вазифаи мушаххаси ҳар як пин дар пайвасткунак аз конфигуратсияи порт вобаста аст. Конфигуратсияи GPIO ALT2 ба шумо имкон медиҳад, ки пайвасткунакро ба ҳолати интерфейси DPI, Намоиши интерфейси параллелӣ гузаред. Барои пайваст кардани мониторҳои VGA тавассути DPI панелҳои васеъ мавҷуданд. Аммо, аввалан, мониторҳои VGA дигар мисли HDMI маъмул нестанд ва дуюм, интерфейси рақамӣ аз аналогӣ беҳтар мешавад. Ғайр аз он, DAC дар чунин кортҳои тавсеаи VGA одатан дар шакли занҷирҳои R-2-R сохта мешавад ва аксар вақт на бештар аз 6 бит барои як ранг.

Дар ҳолати ALT2, пинҳои пайвасткунандаи GPIO маънои зеринро доранд:

Монитори дуюми HDMI ба Raspberry Pi3 тавассути интерфейси DPI ва тахтаи FPGA

Дар ин ҷо ман пинҳои RGB-и пайвасткунакро мутаносибан сурх, сабз ва кабуд ранг кардам. Дигар сигналҳои муҳим ин сигналҳои синхронизатсияи V-SYNC ва H-SYNC ва инчунин CLK мебошанд. Басомади соати CLK басомадест, ки дар он арзишҳои пиксел ба пайвасткунак бароварда мешаванд ва аз ҳолати интихобшудаи видео вобаста аст.

Барои пайваст кардани монитори рақамии HDMI, шумо бояд сигналҳои интерфейси DPI-ро сабт кунед ва онҳоро ба сигналҳои HDMI табдил диҳед. Инро, масалан, бо истифода аз ҳама гуна тахтаи FPGA анҷом додан мумкин аст. Тавре маълум гардид, тахтаи Mars Rover2rpi барои ин мақсад мувофиқ аст. Дар ҳақиқат, варианти асосии пайваст кардани ин тахта тавассути адаптери махсус чунин аст:

Монитори дуюми HDMI ба Raspberry Pi3 тавассути интерфейси DPI ва тахтаи FPGA

Ин тахта барои зиёд кардани шумораи бандарҳои GPIO ва пайваст кардани таҷҳизоти иловагӣ ба малина истифода мешавад. Ҳамзамон, 4 сигнали GPIO бо ин пайвастшавӣ барои сигналҳои JTAG истифода мешаванд, то ки барнома аз тақсимот метавонад нармафзори FPGA-ро ба FPGA бор кунад. Аз ин сабаб, чунин пайвасти мунтазам ба ман мувофиқат намекунад, сигналҳои 4 DPI хориҷ мешаванд. Хушбахтона, шонаҳои иловагӣ дар тахта дорои pinout бо Малина мувофиқанд. То ки ман метавонам тахтаро 90 дараҷа гардиш кунам ва то ҳол онро ба малинаи худ пайваст кунам:

Монитори дуюми HDMI ба Raspberry Pi3 тавассути интерфейси DPI ва тахтаи FPGA

Албатта, шумо бояд як барномасози берунии JTAG истифода баред, аммо ин мушкилот нест.

Ҳанӯз як мушкилоти хурд вуҷуд дорад. На ҳар як PIN-и FPGA метавонад ҳамчун вуруди соат истифода шавад. Танҳо якчанд пинҳои махсус мавҷуданд, ки метавонанд барои ин мақсад истифода шаванд. Ҳамин тавр, дар ин ҷо маълум шуд, ки сигнали GPIO_0 CLK ба вуруди FPGA намеояд, ки онро ҳамчун вуруди соати FPGA истифода бурдан мумкин аст. Ҳамин тавр, ба ҳар ҳол, ман маҷбур будам, ки як постро ба рӯймол партоям. Ман сигнали GPIO_0 ва KEY[1]-и тахтаро пайваст мекунам:

Монитори дуюми HDMI ба Raspberry Pi3 тавассути интерфейси DPI ва тахтаи FPGA

Ҳоло ман ба шумо каме дар бораи лоиҳа дар FPGA нақл мекунам. Мушкилоти асосӣ дар ташаккули сигналҳои HDMI басомадҳои хеле баланд аст. Ба pinout-и пайвасткунаки HDMI нигоҳ карда, шумо мебинед, ки сигналҳои RGB ҳоло сигналҳои дифференсиалии пайдарпай мебошанд:

Монитори дуюми HDMI ба Raspberry Pi3 тавассути интерфейси DPI ва тахтаи FPGA

Истифодаи сигнали дифференсиалӣ ба шумо имкон медиҳад, ки бо садои ҳолати умумӣ дар хати интиқол мубориза баред. Дар ин ҳолат, рамзи аслии ҳашт-битии ҳар як сигнали ранг ба TMDS-и 10-битӣ (сигнализатсияи дифференсиалии гузариши ҳадди ақалл) табдил дода мешавад. Ин як усули махсуси рамзгузорӣ барои хориҷ кардани ҷузъи DC аз сигнал ва кам кардани гузариши сигнал дар хати дифференсиалӣ мебошад. Азбаски ҳоло 10 бит барои интиқоли як байт ранг аз хати силсилавӣ мавҷуд аст, маълум мешавад, ки басомади соати сериализатор бояд аз басомади соати пикселҳо 10 маротиба зиёдтар бошад. Агар мо барои мисол ҳолати видеоии 1280x720 60Гцро гирем, пас басомади пикселии ин режим 74,25 МГц аст. Сериализатор бояд 742,5 МГс бошад.

Умуман, мутаассифона, FPGA-ҳои анъанавӣ ба ин қодир нестанд. Аммо, ба бахти мо, FPGA-ҳо пинҳои дарунсохт DDIO доранд. Инҳо хулосаҳое мебошанд, ки аллакай 2 ба 1 сериализатор мебошанд. Ин аст, ки онҳо метавонанд ду битро пайдарпай дар баробари басомадҳои баландшавӣ ва пастшавии соатҳо баровард. Ин маънои онро дорад, ки дар лоиҳаи FPGA шумо метавонед на 740 МГс, балки 370 МГс истифода баред, аммо шумо бояд элементҳои баромади DDIO-ро дар FPGA истифода баред. Дар ин ҷо 370 МГс аллакай басомади қобили дастрас аст. Мутаассифона, режими 1280 × 720 маҳдудият аст. Дар FPGA Cyclone IV мо, ки дар тахтаи Rover2rpi насб шудааст, ҳалли баландтарро ба даст овардан мумкин нест.

Ҳамин тариқ, дар лоиҳа басомади пикселҳои вурудии CLK ба PLL дода мешавад, ки он ба 5 зарб мешавад. Дар ин басомад байтҳои R, G, B ба ҷуфтҳои бит табдил меёбанд. Ин аст он чизе ки рамзгузори TMDS мекунад. Рамзи сарчашма дар Verilog HDL чунин менамояд:

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

Сипас ҷуфтҳои баромад ба баромади DDIO дода мешаванд, ки пай дар пай дар баландшавӣ ва пастшавӣ сигнали як-бит истеҳсол мекунад.

Худи DDIO-ро метавон бо рамзи Verilog чунин тавсиф кард:

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

Аммо шояд ин тавр кор накунад. Шумо бояд мегафунксияи Altera-ро ALTDDIO_OUT истифода баред, то ки унсурҳои баромади DDIO-ро воқеан истифода баред. Дар лоиҳаи ман ҷузъи китобхонаи ALTDDIO_OUT истифода мешавад.

Ин ҳама метавонад каме душвор ба назар расад, аммо он кор мекунад.

Шумо метавонед тамоми рамзи сарчашмаеро, ки дар Verilog HDL навишта шудааст, бубинед дар ин ҷо дар github.

Нармафзори таҳияшуда барои FPGA ба чипи EPCS дар тахтаи Mars Rover2rpi насб карда шудааст. Ҳамин тариқ, вақте ки қувва ба тахтаи FPGA дода мешавад, FPGA аз хотираи флешдор оғоз мешавад ва оғоз меёбад.

Ҳоло мо бояд каме дар бораи конфигуратсияи худи Raspberry сӯҳбат кунем.

Ман дар Raspberry PI OS (32 бит) дар асоси Debian Buster таҷрибаҳо мегузаронам, Версия: Августи соли 2020,
Санаи нашр: 2020-08-20, Версияи ядро: 5.4.

Шумо бояд ду чизро иҷро кунед:

  • файли config.txt -ро таҳрир кунед;
  • сохтани конфигуратсияи сервери X барои кор бо ду монитор.

Ҳангоми таҳрири файли /boot/config.txt, шумо бояд:

  1. хомӯш кардани истифодаи i2c, i2s, spi;
  2. режими DPI бо overlay dtoverlay = dpi24 фаъол созед;
  3. танзим ҳолати видео 1280 × 720 60Hz, 24 бит дар як нуқта дар як DPI;
  4. миқдори зарурии фреймбуферҳои 2-ро муайян кунед (max_framebuffers=2, танҳо он вақт дастгоҳи дуюм /dev/fb1 пайдо мешавад)

Матни пурраи файли config.txt чунин менамояд.

# 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

Пас аз ин, шумо бояд файли конфигуратсияро барои сервери X эҷод кунед, то ду мониторро дар ду фреймбуфер /dev/fb0 ва /dev/fb1 истифода барад:

Файли танзимоти ман /usr/share/x11/xorg.conf.d/60-dualscreen.conf чунин аст

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

Хуб, агар аллакай насб нашуда бошад, пас шумо бояд Xinerama-ро насб кунед. Он гоҳ фазои мизи корӣ пурра ба ду монитор васеъ карда мешавад, тавре ки дар видеои намоишии боло нишон дода шудааст.

Шояд ҳамааш ҳамин бошад. Акнун соҳибони Raspberry Pi3 метавонанд аз ду монитор истифода баранд.

Тавсиф ва диаграммаи Шӯрои Mars Rover2rpi метавонад бошад инҷо бубинед.

Манбаъ: will.com