Fanaraha-maso HDMI faharoa amin'ny Raspberry Pi3 amin'ny alΓ lan'ny DPI interface sy FPGA board


Ity horonantsary ity dia mampiseho: board Raspberry Pi3, mifandray amin'izany amin'ny alΓ lan'ny connector GPIO dia board FPGA Mars Rover2rpi (Cyclone IV), izay misy monitor HDMI mifandray. Ny monitor faharoa dia mifandray amin'ny alalan'ny connector HDMI mahazatra an'ny Raspberry Pi3. Miara-miasa toy ny rafitra fanaraha-maso roa ny zava-drehetra.

Manaraka izany dia holazaiko aminao ny fomba fampiharana izany.

Ny board Raspberry Pi3 malaza dia manana mpampitohy GPIO izay ahafahanao mampifandray karatra fanitarana isan-karazany: sensor, LED, mpamily motera stepper ary maro hafa. Ny fiasan'ny pin tsirairay amin'ny mpampitohy dia miankina amin'ny fandrindrana ny seranana. Ny fanamafisam-peo GPIO ALT2 dia ahafahanao manova ny mpampitohy amin'ny maodely DPI interface, Display Parallel Interface. Misy karatra fanitarana hampifandray ny mpanara-maso VGA amin'ny DPI. Na izany aza, voalohany, tsy mahazatra toy ny HDMI intsony ny mpanara-maso VGA, ary faharoa, ny interface nomerika dia tsara kokoa noho ny analogue. Ankoatr'izay, ny DAC amin'ny takelaka fanitarana VGA toy izany dia matetika atao amin'ny endrika rojo R-2-R ary matetika tsy mihoatra ny 6 bit isaky ny loko.

Ao amin'ny fomba ALT2, ny pin connector GPIO dia manana dikany manaraka:

Fanaraha-maso HDMI faharoa amin'ny Raspberry Pi3 amin'ny alΓ lan'ny DPI interface sy FPGA board

Eto aho dia nandoko ny tsipika RGB amin'ny mpampitohy mena, maitso ary manga. Ny famantarana manan-danja hafa dia ny famantarana V-SYNC sy H-SYNC, ary koa ny CLK. Ny famantaran'ny famantaranandro CLK dia ny fatran'ny sandan'ny piksela mivoaka amin'ny mpampitohy; miankina amin'ny fomba video voafantina izany.

Mba hampifandraisana monitor HDMI nomerika dia mila maka ny famantarana DPI amin'ny interface ianao ary manova azy ireo ho famantarana HDMI. Azo atao izany, ohatra, mampiasa karazana board FPGA. Raha ny fantatra dia mety amin'ireo tanjona ireo ny board Mars Rover2rpi. Raha ny marina, ny safidy lehibe amin'ny fampifandraisana ity board ity amin'ny adaptatera manokana dia toa izao:

Fanaraha-maso HDMI faharoa amin'ny Raspberry Pi3 amin'ny alΓ lan'ny DPI interface sy FPGA board

Ity birao ity dia ampiasaina hampitomboana ny isan'ny seranan-tsambo GPIO ary hampifandray ireo fitaovana periferika kokoa amin'ny voaroy. Amin'izany fotoana izany, ny famantarana 4 GPIO miaraka amin'io fifandraisana io dia ampiasaina amin'ny famantarana JTAG, mba hahafahan'ny programa avy amin'ny Raspberry hampiditra ny firmware FPGA ao amin'ny FPGA. Noho izany, ity fifandraisana mahazatra ity dia tsy mety amiko; 4 DPI famantarana dia miala. Soa ihany fa ny tohotra fanampiny eo amin'ny solaitrabe dia manana pinout mifanentana amin'ny Raspberry. Noho izany dia afaka manodina ny solaitrabe 90 degre aho ary mbola mampifandray azy amin'ny raspberry-ko:

Fanaraha-maso HDMI faharoa amin'ny Raspberry Pi3 amin'ny alΓ lan'ny DPI interface sy FPGA board

Mazava ho azy fa tsy maintsy mampiasa programa JTAG ivelany ianao, saingy tsy olana izany.

Mbola misy olana kely. Tsy ny pin FPGA rehetra dia azo ampiasaina ho fampidirana famantaranandro. Misy tsimatra natokana vitsivitsy ihany azo ampiasaina amin'ireo tanjona ireo. Dia hita teto fa ny famantarana GPIO_0 CLK dia tsy mahatratra ny fidirana FPGA, izay azo ampiasaina ho famantarana famantaranandro FPGA. Mbola tsy maintsy nametraka tariby iray teo amin’ilay saron-tava aho. Mampifandray ny GPIO_0 sy ny famantarana KEY[1] an'ny birao aho:

Fanaraha-maso HDMI faharoa amin'ny Raspberry Pi3 amin'ny alΓ lan'ny DPI interface sy FPGA board

Ankehitriny dia hilaza aminao kely momba ny tetikasa FPGA aho. Ny fahasarotana lehibe indrindra amin'ny famokarana famantarana HDMI dia matetika avo be. Raha mijery ny pinout mpampitohy HDMI ianao, dia ho hitanao fa ny famantarana RGB dia mari-pamantarana samihafa amin'izao fotoana izao:

Fanaraha-maso HDMI faharoa amin'ny Raspberry Pi3 amin'ny alΓ lan'ny DPI interface sy FPGA board

Ny fampiasana mari-pamantarana samihafa dia ahafahanao miady amin'ny fitsabahana mahazatra amin'ny tsipika fampitaovana. Amin'ity tranga ity dia avadika ho TMDS 10-bit (Transition-minimized differential signaling) ny kaody valo-bit voalohany amin'ny famantarana loko tsirairay. Ity dia fomba famandrihana manokana hanesorana ny singa DC amin'ny famantarana ary hanamaivanana ny fifindran'ny famantarana amin'ny tsipika samihafa. Satria 10 bits izao dia mila ampitaina amin'ny tsipika serial ho an'ny loko iray, dia hita fa ny hafainganam-pandehan'ny famantaranandro serializer dia tokony ho avo 10 heny noho ny hafainganam-pandehan'ny famantaranandro piksel. Raha raisintsika ohatra ny maodely video 1280x720 60Hz, dia 74,25 MHz ny fatran'ity fomba ity. Ny serializer dia tokony ho 742,5 MHz.

Ny FPGA mahazatra, indrisy, tsy mahavita izany. Na izany aza, soa ihany ho antsika, ny FPGA dia manana tsipika DDIO naorina. Ireo dia fehin-kevitra izay efa, toy ny hoe, serializers 2-to-1. Izany hoe, afaka mamoaka bitika roa misesy amin'ny sisiny miakatra sy midina amin'ny fatran'ny famantaranandro izy ireo. Midika izany fa amin'ny tetikasa FPGA dia tsy afaka mampiasa 740 MHz ianao, fa 370 MHz, fa mila mampiasa singa famoahana DDIO ao amin'ny FPGA ianao. Ankehitriny ny 370 MHz dia efa tena azo tanterahina tanteraka. Indrisy anefa fa ny maody 1280x720 no fetra. Tsy azo atao ny manapa-kevitra ambony kokoa amin'ny Cyclone IV FPGA napetraka amin'ny board Mars Rover2rpi.

Noho izany, ao amin'ny famolavolana, ny fatran'ny pixel input CLK dia mankany amin'ny PLL, izay ampitomboina amin'ny 5. Amin'io matetika io, ny R, G, B bytes dia miova ho bitika. Izany no ataon'ny TMDS encoder. Toy izao ny kaody loharano ao amin'ny 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

Avy eo dia alefa any amin'ny fivoahana DDIO ny mpivady vokatra, izay mamokatra famantarana kely iray amin'ny sisiny miakatra sy midina.

Ny DDIO mihitsy dia azo faritana miaraka amin'ity kaody Verilog manaraka ity:

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

Saingy azo inoana fa tsy hahomby amin'izany fomba izany. Mila mampiasa Alter's megafunction ALTDIO_OUT ianao mba ahafahana mampifanaraka ny singa famoahana DDIO. Ny tetikasako dia mampiasa ny singa famakiam-boky ALTDIO_OUT.

Mety ho sarotra ihany izany rehetra izany, saingy mahomby.

Azonao jerena ny kaody loharano rehetra voasoratra ao amin'ny Verilog HDL eto amin'ny github.

Ny firmware natambatra ho an'ny FPGA dia alefa ao amin'ny chip EPCS napetraka ao amin'ny board Mars Rover2rpi. Noho izany, rehefa ampiharina amin'ny biraon'ny FPGA ny hery, dia hanomboka amin'ny fahatsiarovana tselatra ny FPGA ary hanomboka.

Ankehitriny dia mila miresaka kely momba ny fanamafisana ny Raspberry isika.

Manao andrana amin'ny Raspberry PI OS (32 bit) miorina amin'ny Debian Buster aho, Version:Aogositra 2020,
Daty famoahana:2020-08-20, Kernel version:5.4.

Mila manao zavatra roa ianao:

  • amboary ny rakitra config.txt;
  • Mamorona fikirakirana mpizara X hiasa miaraka amin'ny mpanara-maso roa.

Rehefa manova ny rakitra /boot/config.txt ianao dia mila:

  1. esory ny fampiasana i2c, i2s, spi;
  2. avelao ny fomba DPI amin'ny fampiasana overlay dtoverlay=dpi24;
  3. amboary ny maody video 1280 Γ— 720 60Hz, 24 bit isaky ny piksel amin'ny DPI;
  4. mariho ny isan'ny framebuffers 2 ilaina (max_framebuffers=2, vao hiseho ny fitaovana faharoa /dev/fb1)

Toy izao ny lahatsoratra feno amin'ny rakitra 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

Aorian'izany dia mila mamorona rakitra fikirakirana ho an'ny mpizara X ianao hampiasa mpanara-maso roa amin'ny framebuffers roa / dev / fb0 sy / dev / fb1:

Toy izao ny fichier configuration-ko /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

Eny ary, raha mbola tsy napetraka izany, dia mila mametraka Xinerama ianao. Avy eo ny habaka desktop dia hanitatra tanteraka amin'ny fanaraha-maso roa, araka ny aseho amin'ny horonan-tsary demo etsy ambony.

Izay ihany angamba. Ankehitriny, ny tompon'ny Raspberry Pi3 dia afaka mampiasa mpanara-maso roa.

Ny famaritana sy ny diagram ny faritra misy ny board Mars Rover2rpi dia azo jerena jereo eto.

Source: www.habr.com