Nyochaa HDMI nke abụọ na Raspberry Pi3 site na interface DPI na bọọdụ FPGA


Vidiyo a na-egosi: bọọdụ Raspberry Pi3, ejikọrọ na ya site na njikọ GPIO bụ bọọdụ FPGA Mars Rover2rpi (Cyclone IV), nke ejikọrọ ihe nleba anya HDMI. Ejikọtara ihe nleba anya nke abụọ site na ọkọlọtọ HDMI njikọ nke Raspberry Pi3. Ihe niile na-arụkọ ọrụ ọnụ dị ka sistemụ nleba anya abụọ.

Ọzọ, m ga-agwa gị ka esi eme nke a.

Bọdụ Raspberry Pi3 na-ewu ewu nwere njikọ GPIO nke ị nwere ike ijikọ kaadị mgbasawanye dị iche iche: sensọ, LEDs, ndị ọkwọ ụgbọ ala stepper na ọtụtụ ndị ọzọ. Ọrụ ziri ezi nke ntụtụ ọ bụla na njikọ njikọ dabere na nhazi ọdụ ụgbọ mmiri. Nhazi GPIO ALT2 na-enye gị ohere ịgbanwe njikọ na ọnọdụ interface DPI, Ngosipụta Parallel Interface. Enwere kaadị mgbasawanye maka ijikọ ndị nlekota VGA site na DPI. Otú ọ dị, nke mbụ, VGA Monitors anaghịzi adị ka HDMI, na nke abụọ, interface dijitalụ na-akawanye mma karịa nke analog. Ọzọkwa, DAC na bọọdụ mgbasawanye VGA dị otú ahụ na-emekarị n'ụdị nke agbụ R-2-R na mgbe mgbe ọ dịghị ihe karịrị 6 ibe n'ibe kwa agba.

Na ọnọdụ ALT2, ntụtụ njikọ GPIO nwere ihe ndị a:

Nyochaa HDMI nke abụọ na Raspberry Pi3 site na interface DPI na bọọdụ FPGA

N'ebe a, agbagoro m ntụtụ RGB nke njikọ ahụ uhie, akwụkwọ ndụ akwụkwọ ndụ na acha anụnụ anụnụ n'otu n'otu. Ihe mgbaàmà ndị ọzọ dị mkpa bụ akara V-SYNC na H-SYNC, yana CLK. Ugboro elekere CLK bụ ugboro nke ụkpụrụ pikselụ na-arụpụta na njikọ; ọ dabere na ọnọdụ vidiyo ahọpụtara.

Iji jikọọ ihe nleba anya HDMI dijitalụ, ịkwesịrị ijide akara ngosi DPI nke interface wee gbanwee ha na akara HDMI. Enwere ike ime nke a, dịka ọmụmaatụ, iji ụfọdụ ụdị bọọdụ FPGA. Dịka ọ siri pụta, bọọdụ Mars Rover2rpi dabara maka ebumnuche ndị a. N'ezie, nhọrọ bụ isi maka ijikọ bọọdụ a site na nkwụnye pụrụ iche dị ka nke a:

Nyochaa HDMI nke abụọ na Raspberry Pi3 site na interface DPI na bọọdụ FPGA

A na-eji bọọdụ a na-amụba ọnụ ọgụgụ ọdụ ụgbọ mmiri GPIO yana ijikọ ngwaọrụ ndị ọzọ na mpụta na utu. N'otu oge ahụ, a na-eji akara GPIO 4 nwere njikọ a maka akara JTAG, nke mere na mmemme sitere na Raspberry nwere ike ibunye FPGA firmware n'ime FPGA. N'ihi nke a, njikọ ọkọlọtọ a adabaghị m; 4 DPI akara adapụ. Ọ dabara nke ọma, combs ndị ọzọ dị na bọọdụ nwere pinout dakọtara na Raspberry. Yabụ enwere m ike ịtụgharị bọọdụ ahụ 90 ogo ma ka jikọọ ya na utu m:

Nyochaa HDMI nke abụọ na Raspberry Pi3 site na interface DPI na bọọdụ FPGA

N'ezie, ị ga-eji ihe mmemme JTAG mpụga, mana nke a abụghị nsogbu.

A ka nwere obere nsogbu. Ọ bụghị ntụtụ FPGA ọ bụla enwere ike iji dị ka ntinye elekere. Enwere naanị ntụtụ raara onwe ya nye enwere ike iji maka ebumnuche ndị a. Ya mere ọ tụgharịrị na ebe a na akara GPIO_0 CLK adịghị eru ntinye FPGA, nke enwere ike iji dị ka ntinye elekere FPGA. Ya mere, m ka ga-etinye otu waya na ịchafụ. Ana m ejikọta GPIO_0 na mgbama KEY[1] bọọdụ:

Nyochaa HDMI nke abụọ na Raspberry Pi3 site na interface DPI na bọọdụ FPGA

Ugbu a, m ga-agwa gị ntakịrị gbasara ọrụ FPGA. Isi ihe isi ike n'ịmepụta akara ngosi HDMI bụ ugboro dị elu. Ọ bụrụ na ị lelee pinout njikọ HDMI, ị ga-ahụ na akara RGB bụ akara ngosi dị iche ugbu a:

Nyochaa HDMI nke abụọ na Raspberry Pi3 site na interface DPI na bọọdụ FPGA

Ojiji nke mgbama dị iche na-enye gị ohere ịlụso nnyonye anya nkịtị ọgụ na ahịrị nnyefe. N'okwu a, a na-atụgharị koodu mbụ nke asatọ-bit nke mgbama agba ọ bụla ka ọ bụrụ 10-bit TMDS (mgbaama dị iche iche nke obere mgbanwe). Nke a bụ usoro nzuzo pụrụ iche iji wepụ akụkụ DC na mgbama ma belata ngbanwe mgbaàmà na ahịrị dị iche. Ebe ọ bụ na a ga-ebunye bits 10 ugbu a n'elu ahịrị serial maka otu byte nke agba, ọ na-atụgharị na ọsọ elekere serializer ga-abụrịrị ugboro 10 karịa ọsọ elekere pixel. Ọ bụrụ na anyị na-ewere ihe atụ na video mode 1280x720 60Hz, mgbe pixel ugboro nke a mode bụ 74,25 MHz. Ihe serializer kwesịrị ịbụ 742,5 MHz.

FPGA oge niile, ọ dị nwute, enweghị ike ime nke a. Agbanyeghị, ọ dabara nke ọma maka anyị, FPGA arụnyere ntụtụ DDIO. Ndị a bụ nkwubi okwu ndị dịlarị, dị ka a pụrụ isi kwuo ya, serializers 2-na-1. Ya bụ, ha nwere ike wepụta nkeji abụọ n'usoro n'usoro n'akụkụ ịrị elu na ọdịda nke ugboro elekere. Nke a pụtara na n'ime ọrụ FPGA ị nwere ike iji ọ bụghị 740 MHz, mana 370 MHz, mana ịkwesịrị iji ihe nrụpụta DDIO na FPGA. Ugbu a 370 MHz abụrụlarị ugboro ole enwere ike nweta ya. Ọ dị nwute, ọnọdụ 1280x720 bụ oke. Enweghị ike nweta mkpebi dị elu na Cyclone IV FPGA anyị etinyere na bọọdụ Mars Rover2rpi.

Ya mere, n'ime imewe, ntinye pikselụ ugboro CLK na-aga na PLL, ebe a na-amụba ya na 5. N'oge a, R, G, B bytes na-atụgharị n'ime ụzọ abụọ. Nke a bụ ihe TMDS koodu na-eme. Koodu isi mmalite dị na Verilog HDL dị ka nke a:

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

Mgbe ahụ, a na-enye ụzọ abụọ mmepụta nri na mmepụta DDIO, nke na-emepụta akara otu-bit n'akụkụ ọnụ na-ebili na ọdịda.

Enwere ike iji koodu Verilog kọwaa DDIO n'onwe ya:

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

Ma o yikarịrị ka ọ gaghị arụ ọrụ otú ahụ. Ịkwesịrị iji Alter's megafunction ALTDDIO_OUT iji mee ka ihe nrụpụta DDIO nwee ike. Ọrụ m na-eji akụrụngwa ọba akwụkwọ ALTDDIO_OUT.

Ihe a niile nwere ike ịdị ntakịrị aghụghọ, mana ọ na-arụ ọrụ.

Ị nwere ike ịlele koodu isi mmalite niile edere na Verilog HDL ebe a na github.

A na-agbanye ngwa ngwa achịkọtara maka FPGA n'ime mgbawa EPCS arụnyere na bọọdụ Mars Rover2rpi. Ya mere, mgbe etinyere ike na bọọdụ FPGA, FPGA ga-amalite site na ebe nchekwa flash wee malite.

Ugbu a, anyị kwesịrị ikwu ntakịrị banyere nhazi nke Raspberry n'onwe ya.

Ana m eme nnwale na Raspberry PI OS (32 bit) dabere na Debian Buster, Ụdị: Ọgọst 2020,
Ụbọchị mwepụta: 2020-08-20, ụdị kernel: 5.4.

Ịkwesịrị ịme ihe abụọ:

  • dezie faịlụ config.txt;
  • mepụta nhazi ihe nkesa X iji rụọ ọrụ na nlekota abụọ.

Mgbe ị na-edezi faịlụ /boot/config.txt ị chọrọ:

  1. gbanyụọ iji i2c, i2s, spi;
  2. mee ka ọnọdụ DPI nwee ike iji overlay dtoverlay=dpi24;
  3. hazie ọnọdụ vidiyo 1280 × 720 60Hz, 24 ibe n'ibe kwa pixel na DPI;
  4. ezipụta nọmba achọrọ nke framebuffers 2 (max_framebuffers=2, naanị mgbe ahụ ka ngwaọrụ nke abụọ / dev/fb1 ga-apụta)

Ederede zuru oke nke faịlụ config.txt dị ka nke a.

# 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

Mgbe nke a gasịrị, ịkwesịrị ịmepụta faịlụ nhazi maka ihe nkesa X iji jiri ihe nlele abụọ na framebuffers abụọ / dev / fb0 na / dev / fb1:

Faịlụ nhazi m /usr/share/x11/xorg.conf.d/60-dualscreen.conf dị ka nke a

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

Ọfọn, ọ bụrụ na etinyebeghị ya, mgbe ahụ ịkwesịrị ịwụnye Xinerama. Mgbe ahụ, oghere desktọpụ ahụ ga-agbasawanye nke ọma na nyocha abụọ, dị ka egosiri na vidiyo ngosi dị n'elu.

Nke ahụ bụ eleghị anya naanị. Ugbu a, ndị nwe Raspberry Pi3 ga-enwe ike iji nyocha abụọ.

Enwere ike ịchọta nkọwa na eserese sekit nke bọọdụ Mars Rover2rpi lee ebe a.

isi: www.habr.com