verilog core for Sharp LJ320U21 320x240 EL pannel - Page 1
Forum section: electronics / general

author: ealex
author_rank: Frequent Contributor
timestamp: April 16, 2017, 03:56:18 pm
content: hellorecently i've got one of the displays sold by "dexters_lab" here:https://www.eevblog.com/forum/buysellwanted/(fs-world)-sharp-lj320u21-electroluminescent-320x240-matrix-displays/i've managed to make some simple verilog code that will drive the display, and draw a basic test pattern:(sorry about the reflections, the display is like a mirror, i peeled of the touch layer, it was cloudy)the FPGA is clocked from a 50MHz oscillator.the code is separated in the following modules:reset_generator.v- it gets the main clock and raw reset button- it generates 2 long reset pulses, positive and negativepixel_timing.v- receives reset and main clock- it generates a sequence of 8 pulses - basically a shift register that loops back at the end- the pulse rate is 50MHz/8 = 6.25MHz- the first pulse output is used as an enable signal for horizontal and vertical modules- the last for outpust are OR'ed to generate the pixel clockhorizontal.v- receives reset, main clock and enable pulse from the timing generator- outputs- out_h_sync : H_SYNC pulse, proper logic level- out_h_active : 1 in active line area, 0 otherwise- out_h_line_start : a pulse at the start of the active area, not used- out_h_reset_pulse : a pulse at the start of a new H_SYNC period- out_h_index[8:0] : current pixel line index, 0 to 319, valid only when out_h_active is 1vertical.v- receives reset, main clock, enable- receives in_h_sync from out_h_reset_pulse- outputs:- out_v_sync : proper level V_SYNC signal- out_v_active : 1 if the current line is display-able, 0 otherwise- out_v_start : a pulse of the start of the active screen area- out_v_index[7:0] : line number, from 0 to 239, valid only when out_v_active is 1sample_video.v- simple logic that generates the lines from the picture abovesharp_lj320u21.v- main block, ties everything togetherCompilation report:Flow Status Successful - Sun Apr 16 18:41:17 2017Quartus II 64-Bit Version 13.0.1 Build 232 06/12/2013 SP 1 SJ Web EditionRevision Name sharp_lj320u21Top-level Entity Name sharp_lj320u21Family Cyclone IIDevice EP2C8Q208C8Timing Models FinalTotal logic elements 88 / 8,256 ( 1 % )Total combinational functions 87 / 8,256 ( 1 % )Dedicated logic registers 40 / 8,256 ( < 1 % )Total registers 40Total pins 9 / 138 ( 7 % )Total virtual pins 0Total memory bits 0 / 165,888 ( 0 % )Embedded Multiplier 9-bit elements 0 / 36 ( 0 % )Total PLLs 0 / 2 ( 0 % )( can be clocked up to 230MHz )feel free to criticize the way i wrote it - i've learned verilog by myself, so any comment is useful.the final scope will be to make a text based status display for my headless servers.currently i've got it working with an 8x8 font - i will make another thread when i populate the font ROM and i can show a demo.maybe add a Z80 so i can connect the servers via serial lines and format the data.

author: dexters_lab
author_rank: Unknown
timestamp: April 16, 2017, 04:02:38 pm
content: top work

author: Buriedcode
author_rank: Super Contributor
timestamp: April 17, 2017, 09:42:49 pm
content: Thanks for thisI am still working on my Planar EL display controller using an old Cyclone II (the only FPGA board I got with SRAM). Thats 640x480 dual scan. I have the timing down, and using a FIFO, but I still haven't managed to get the read/write timing to allow it to appear to a microcontroller as just a block of memory. It's my first proper FPGA project, also in verilog.I'm sure you've got it all sorted, but if you want to swap notes, pm me. Or if you want my code used (I'm assuming its a similar interface) let me know.

author: ale500
author_rank: Frequent Contributor
timestamp: April 18, 2017, 09:23:50 am
content: Dual scan, 640x480, I made a controller for a dual scan LCD some years ago. It is based on a Parallax propeller. Sadly the propeller only has 32 kbytes RAM, instead of the 38 k that would be needed, 640x400 works then. The timing was a bit tight but if you think that one processor only has to refresh the display... it is not that important.Using a FPGA makes the whole process easier, but only the biggest members of the cyclone II family have enough embedded RAM blocks, for an "easy" dual-port interface. Getting a processor and LCD interface to read/write "simultaneously" to RAM needs some arbitration work (only easy to say).The easiest is to say you have a two states state machine, state 0 allow LCD read for refresh (that needs kind of 2 accesses due to dual scan) and state 1 allows for uP access. You may have to save what the processor writes in a buffer to save it on state 1, reading needs either a faster than the processor read cycle state machine or an asynchronous interface. Maybe if you give us a bit more info how the uP access should be, we could devise a scheme. I find these arbitration problems difficult but exciting to solve(not that I had had that much success...)

author: mikeselectricstuff
author_rank: Super Contributor
timestamp: April 18, 2017, 09:42:46 am
content: Quote from: ale500 on April 18, 2017, 09:23:50 amOr just use two clock phases at 2x the refresh read clock rate, so on every cycle you have a refresh and CPU read/write write opportunity.

author: ealex
author_rank: Frequent Contributor
timestamp: April 18, 2017, 10:45:18 am
content: depending on the display's interface you could use the external memory interface of a STM32 micro - some of them have more than enough RAM for that.look in this application note:http://www.st.com/content/ccc/resource/technical/document/application_note/85/ad/ef/0f/a3/a6/49/9a/CD00201397.pdf/files/CD00201397.pdf/jcr:content/translations/en.CD00201397.pdfthey show you how to use FSMC (flexible static memory controller) to drive a raw graphical lcd.if i'm not mistaken, that display has a 4 bit interface instead of 1 bit -> you will not waste too much memory.

author: marshallh
author_rank: Unknown
timestamp: April 22, 2017, 05:08:09 am
content: Good job.I have attached code I wrote 5 years ago for a 512x256 planar display.Code:module top(clk_50,el_tvid,el_vs,el_hs,el_vclk,el_vid);inputwireclk_50;outputregel_vid;outputregel_tvid;outputwireel_vs = (y_count == 0);outputwireel_hs = x_count < 512;outputregel_vclk;reg [9:0]x_count;reg [8:0]y_count;reg [1:0]cnt;reg[13:0]front_porch;regpoop;initial beginel_tvid <= 0;el_vclk <= 0;endalways @(posedge clk_50)begincnt <= cnt + 1;if(cnt == 1) el_vclk <= ~el_vclk;poop <= el_vclk;// 100uS front porchif(front_porch > 0) beginfront_porch <= front_porch + 1;if(front_porch == 10000 ) beginfront_porch <= 0;x_count <= 0;y_count <= 0;endendif(~el_vclk && poop) beginx_count <= x_count + 1;if(x_count == 520) beginx_count <= 0;y_count <= y_count + 1;endif(y_count == 256) front_porch <= 1;endel_vid <= ~img_data;endwire [511:0] img_data;imgimg_inst (.address( y_count ),.clock( clk_50 ),.q( img_data ));endmodule

author: ealex
author_rank: Frequent Contributor
timestamp: April 22, 2017, 05:30:31 am
content: that code looks so clean, at least compared to the spaghetti monster i added in the first post