د DPI انٹرفیس او FPGA بورډ له لارې راسبیري Pi3 ته دوهم HDMI نظارت


دا ویډیو ښیې: د Raspberry Pi3 بورډ چې د GPIO نښلونکي له لارې ورسره تړل شوی د FPGA بورډ Mars Rover2rpi (سایکلون IV) دی، کوم چې د HDMI مانیټر سره وصل دی. دوهم مانیټر د Raspberry Pi3 معیاري HDMI نښلونکي له لارې وصل دی. هرڅه د دوه ګوني نظارت سیسټم په څیر یوځای کار کوي.

بیا به زه تاسو ته ووایم چې دا څنګه پلي کیږي.

مشهور Raspberry Pi3 بورډ د GPIO نښلونکی لري چې له لارې تاسو کولی شئ مختلف توسیع کارتونه وصل کړئ: سینسرونه، LEDs، د سټیپر موټرو چلوونکي او نور ډیر څه. په نښلونکي کې د هر پن دقیق فعالیت د پورټ ترتیب پورې اړه لري. د GPIO ALT2 ترتیب تاسو ته اجازه درکوي چې نښلونکی د DPI انٹرفیس حالت ته واړوئ، موازي انٹرفیس ښکاره کړئ. د DPI له لارې د VGA مانیټرونو سره وصل کولو لپاره د توسیع کارتونه شتون لري. په هرصورت، لومړی، د VGA مانیټرونه نور د HDMI په څیر عام ندي، او دویم، ډیجیټل انٹرفیس د انلاګ څخه په زیاتیدونکي توګه ښه دی. برسېره پردې، د دې ډول VGA توسیع بورډونو DAC معمولا د R-2-R زنځیرونو په بڼه جوړ شوی او ډیری وختونه په هر رنګ کې له 6 بټونو څخه ډیر نه وي.

په ALT2 حالت کې، د GPIO نښلونکي پنونه لاندې معنی لري:

د DPI انٹرفیس او FPGA بورډ له لارې راسبیري Pi3 ته دوهم HDMI نظارت

دلته ما د نښلونکي RGB پنونه په ترتیب سره سور، شنه او نیلي رنګ کړي دي. نور مهم سیګنالونه د V-SYNC او H-SYNC سیګنالونه او همدارنګه CLK دي. د CLK ساعت فریکونسۍ هغه فریکونسۍ ده چې په کوم کې د پکسل ارزښتونه نښلونکي ته تولید کیږي؛ دا په ټاکل شوي ویډیو حالت پورې اړه لري.

د ډیجیټل HDMI مانیټر سره وصل کولو لپاره ، تاسو اړتیا لرئ د انٹرفیس DPI سیګنالونه ونیسئ او HDMI سیګنالونو ته یې واړوئ. دا ترسره کیدی شي، د بیلګې په توګه، د FPGA بورډ ځینې ډول کارول. لکه څنګه چې دا معلومه شوه، د مریخ Rover2rpi بورډ د دې موخو لپاره مناسب دی. په حقیقت کې، د ځانګړي اډاپټر له لارې د دې بورډ سره نښلولو اصلي اختیار داسې ښکاري:

د DPI انٹرفیس او FPGA بورډ له لارې راسبیري Pi3 ته دوهم HDMI نظارت

دا بورډ د GPIO بندرونو شمیر زیاتولو او راسبیري ته د نورو پردیو وسایلو د نښلولو لپاره کارول کیږي. په ورته وخت کې ، د دې اړیکې سره 4 GPIO سیګنالونه د JTAG سیګنالونو لپاره کارول کیږي ، نو د راسبیري برنامه کولی شي FPGA فرم ویئر په FPGA کې بار کړي. د دې له امله ، دا معیاري اړیکه زما سره مناسب نه ده؛ د 4 DPI سیګنالونه له مینځه ځي. خوشبختانه ، په تخته کې اضافي کمبونه د راسبیري سره مطابقت لرونکي پن آوټ لري. نو زه کولی شم تخته 90 درجې وګرځوم او بیا هم دا زما راسبیري سره وصل کړم:

د DPI انٹرفیس او FPGA بورډ له لارې راسبیري Pi3 ته دوهم HDMI نظارت

البته، تاسو باید یو بهرنی JTAG پروګرامر وکاروئ، مګر دا کومه ستونزه نده.

لاهم یوه کوچنۍ ستونزه شتون لري. هر FPGA پن د ساعت ان پټ په توګه نشي کارول کیدی. یوازې یو څو وقف شوي پنونه شتون لري چې د دې موخو لپاره کارول کیدی شي. نو دلته معلومه شوه چې د GPIO_0 CLK سیګنال د FPGA ان پټ ته نه رسیږي، کوم چې د FPGA ساعت ان پټ په توګه کارول کیدی شي. نو زه لاهم باید په سکارف کې یو تار واچوم. زه GPIO_0 او د بورډ KEY[1] سیګنال سره نښلوم:

د DPI انٹرفیس او FPGA بورډ له لارې راسبیري Pi3 ته دوهم HDMI نظارت

اوس زه به تاسو ته د FPGA پروژې په اړه لږ څه ووایم. د HDMI سیګنالونو په تولید کې اصلي ستونزه خورا لوړه فریکونسۍ ده. که تاسو د HDMI نښلونکي پن آوټ وګورئ، تاسو کولی شئ وګورئ چې د RGB سیګنالونه اوس د سیریل توپیر سیګنالونه دي:

د DPI انٹرفیس او FPGA بورډ له لارې راسبیري Pi3 ته دوهم HDMI نظارت

د توپیر سیګنال کارول تاسو ته اجازه درکوي د لیږد لین کې د عام حالت مداخلې سره مبارزه وکړئ. په دې حالت کې، د هر رنګ سیګنال اصلي اته بټ کوډ په 10-bit TMDS کې بدلیږي (د لیږد لږ تر لږه توپیر سیګنال). دا د کوډ کولو ځانګړی میتود دی چې د سیګنال څخه د DC اجزا لرې کړي او په توپیري کرښه کې د سیګنال سویچنګ کم کړي. څرنګه چې 10 بټونه اوس اړتیا لري د یو بایټ رنګ لپاره د سریال لاین ته لیږدول شي، نو دا معلومه شوه چې د سیریلائزر ساعت سرعت باید د پکسل ساعت سرعت څخه 10 ځله لوړ وي. که موږ د مثال په توګه د ویډیو حالت 1280x720 60Hz واخلو، نو د دې حالت د پکسل فریکونسۍ 74,25 MHz ده. سیریلائزر باید 742,5 MHz وي.

منظم FPGAs، له بده مرغه، د دې توان نلري. په هرصورت، خوشبختانه زموږ لپاره، FPGA د DDIO پنونه جوړ کړي دي. دا هغه پایلې دي چې لا دمخه دي، لکه څنګه چې دا وې، د 2-to-1 سیریلرز. دا دی، دوی کولی شي دوه بټونه په ترتیب سره د ساعت فریکونسۍ په لوړیدو او راټیټ څنډو کې تولید کړي. دا پدې مانا ده چې د FPGA پروژه کې تاسو کولی شئ 740 MHz نه، مګر 370 MHz وکاروئ، مګر تاسو اړتیا لرئ په FPGA کې د DDIO محصول عناصر وکاروئ. اوس 370 MHz لا دمخه په بشپړ ډول د لاسته راوړلو وړ فریکونسۍ ده. له بده مرغه، د 1280x720 حالت حد دی. زموږ په سایکلون IV FPGA کې د مریخ Rover2rpi بورډ نصب شوي لوړ ریزولوشن نشي ترلاسه کیدی.

نو، په ډیزاین کې، د ان پټ پکسل فریکونسۍ CLK PLL ته ځي، چیرته چې دا په 5 سره ضرب کیږي. په دې فریکونسۍ کې، R، G، B بایټونه په بټ جوړه بدلیږي. دا هغه څه دي چې د TMDS انکوډر یې کوي. په ویریلوګ 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 پخپله د لاندې ویریلوګ کوډ سره تشریح کیدی شي:

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

مګر ډیری احتمال به دا کار ونکړي. تاسو اړتیا لرئ د الټر میګا فنکشن ALTDIO_OUT وکاروئ ترڅو واقعیا د DDIO محصول عناصر فعال کړئ. زما پروژه د ALTDIO_OUT کتابتون برخه کاروي.

دا ټول ممکن یو څه ستونزمن ښکاري، مګر دا کار کوي.

تاسو کولی شئ د ویریلوګ HDL کې لیکل شوي ټول سرچینې کوډ وګورئ دلته په ګیتوب کې.

د FPGA لپاره ترتیب شوی فرم ویئر د مریخ Rover2rpi بورډ کې نصب شوي EPCS چپ کې فلش شوی. په دې توګه، کله چې بریښنا د FPGA بورډ ته تطبیق شي، FPGA به د فلش حافظې څخه پیل شي او پیل شي.

اوس موږ باید د Raspberry د تشکیلاتو په اړه لږ څه خبرې وکړو.

زه د ډیبیان بسټر پراساس د راسبیري PI OS (32 بټ) تجربې ترسره کوم ، نسخه: اګست 2020 ،
د خپریدو نیټه: 2020-08-20, د کرنل نسخه: 5.4.

تاسو باید دوه شیان ترسره کړئ:

  • د config.txt فایل سم کړئ؛
  • د دوه مانیټرونو سره کار کولو لپاره د ایکس سرور ترتیب رامینځته کړئ.

کله چې د /boot/config.txt فایل سمول تاسو ورته اړتیا لرئ:

  1. د i2c، i2s، spi کارول غیر فعال کړئ؛
  2. د پوښښ په کارولو سره د DPI حالت فعال کړئ dtoverlay=dpi24؛
  3. د ویډیو حالت ترتیب کړئ 1280 × 720 60Hz، په DPI کې 24 بټونه فی پکسل؛
  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 مالکین به وکوالی شي دوه مانیټرونه وکاروي.

د مریخ Rover2rpi بورډ توضیحات او سرکټ ډیاګرام موندل کیدی شي دلته وګوره.

سرچینه: www.habr.com