Jump to content
  • 0

Displaying character on PmodOLED2


ElectronicsBeginner

Question

`timescale 1ns / 1ps


`define Idle 4'b0000
`define Character 4'b0001
`define Done 4'b0010
`define UpdateScreen 4'b0011
`define ClearDC 4'b0100
`define SetPage 4'b0101
`define PageNum 4'b0110
`define LeftColumn1 4'b1111
`define LeftColumn2 4'b1000
`define SetDC 4'b1001
`define SendChar 4'b1010
`define Transition1 4'b1011
`define Transition2 4'b1100
`define Transition3 4'b1101
`define ReadMem 4'b1110
`define ReadMem2 4'b1111
module OledEX(
    CLK,
    RST,
    EN,
    CS,
    SDO,
    SCLK,
    DC,
    FIN
    );

	
    input CLK;
    input RST;
    input EN;
    output CS;
    output SDO;
    output SCLK;
    output DC;
    output FIN;

	
	wire CS, SDO, SCLK, DC, FIN;
	
   
   reg [7:0]        current_screen;  
	reg [7:0] screen;
	initial 
	screen=8'h41;

   
   reg [3:0] current_state;
   
   reg [3:0] after_state;
  
   reg [3:0] after_page_state;
   
   reg [3:0] after_char_state;
  
   reg [3:0] after_update_state;


	
	
   reg temp_dc;
   
   
   
   
   reg temp_spi_en;					
   reg [7:0] temp_spi_data;		
   wire temp_spi_fin;				
   
   reg [7:0] temp_char;				
   reg [10:0] temp_addr;			
   wire [7:0] temp_dout;			
   reg [1:0] temp_page;				
   reg [3:0] temp_index;			

	

   assign DC = temp_dc;
   
   assign FIN = (current_state == `Done) ? 1'b1 : 1'b0;


   
   SpiCtrl SPI_COMP(
			.CLK(CLK),
			.RST(RST),
			.SPI_EN(temp_spi_en),
			.SPI_DATA(temp_spi_data),
			.CS(CS),
			.SDO(SDO),
			.SCLK(SCLK),
			.SPI_FIN(temp_spi_fin)
	);

  
   charLib CHAR_LIB_COMP(
			.clka(CLK),
			.addra(temp_addr),
			.douta(temp_dout)
	);
	
	always @(posedge CLK) begin
			
		case(current_state)

			
			`Idle : begin
					if(EN == 1'b1) begin
						current_state <= `ClearDC;
						after_page_state <= `Character;
						temp_page <= 2'b00;
					end
			end			
			`Character : begin
					
					current_screen <= screen;					
					current_state <= `UpdateScreen;
					after_update_state <= `Done;
			end
			`Done : begin
					if(EN == 1'b0) begin
						current_state <= `Idle;
					end
			end			
			`UpdateScreen : begin

					temp_char <= current_screen;

					if(temp_index == 'd15) begin

						temp_index <= 'd0;
						temp_page <= temp_page + 1'b1;
						after_char_state <= `ClearDC;

						if(temp_page == 2'b11) begin
							after_page_state <= after_update_state;
						end
						else	begin
							after_page_state <= `UpdateScreen;
						end
					end
					else begin

						temp_index <= temp_index + 1'b1;
						after_char_state <= `UpdateScreen;

					end
					
					current_state <= `SendChar;

			end
			`ClearDC : begin
					temp_dc <= 1'b0;
					current_state <= `SetPage;
			end
			
			`SetPage : begin
					temp_spi_data <= 8'b00100010;
					after_state <= `PageNum;
					current_state <= `Transition1;
			end
			
			`PageNum : begin
					temp_spi_data <= {6'b000000,temp_page};
					after_state <= `LeftColumn1;
					current_state <= `Transition1;
			end
			
			`LeftColumn1 : begin
					temp_spi_data <= 8'b00000000;
					after_state <= `LeftColumn2;
					current_state <= `Transition1;
			end
			
			`LeftColumn2 : begin
					temp_spi_data <= 8'b00010000;
					after_state <= `SetDC;
					current_state <= `Transition1;
			end
			
			`SetDC : begin
					temp_dc <= 1'b1;
					current_state <= after_page_state;
			end
			
			`SendChar : begin
					temp_addr <= {temp_char, 3'b111};
					after_state <= after_char_state;
					current_state <= `ReadMem;
			end
			
			`ReadMem : begin
					current_state <= `ReadMem2;
			end

			`ReadMem2 : begin
					temp_spi_data <= temp_dout;
					current_state <= `Transition1;
			end
			`Transition1 : begin
					temp_spi_en <= 1'b1;
					current_state <= `Transition2;
			end

			`Transition2 : begin
					if(temp_spi_fin == 1'b1) begin
						current_state <= `Transition3;
					end
			end

			`Transition3 : begin
					temp_spi_en <= 1'b0;
					current_state <= after_state;
			end
			

			default : current_state <= `Idle;

		endcase
	end



endmodule

Hi.

I need help. I am using that code to display just one character on PmodOLED2 display. I saw there is no projects for that display, only for pmod oled. Code is similar as code from site, but it is not working. It  doesn't have any error. I am using ISE DESIGN SUIT 14.7 and Spartan 3E Starter Kit. 

Code from site not working too. 

Any tip would be appreciated.

Link to comment
Share on other sites

13 answers to this question

Recommended Posts

Hello @ElectronicsBeginner,

Unfortunately, any code that you find for the Pmod OLED will not not work with the Pmod OLED2 (which became a retired product about 5 years ago), primarily because SPI is used to work with the Pmod OLED, but the Pmod OLED2 only works with data sent in parallel. I do not believe we have any pre-existing FPGA code for the display, though we did find a github project here that uses verilog and some python scripts to work with the Pmod OLED2 with a non-Digilent (Lattice Semiconductor) FPGA.

Good luck,
JColvin

Link to comment
Share on other sites

Hello @JColvin,

Thank you for answer. I didn't pay attention to that detail. That explains why it doesn't work on PmodOLED2 display, but I have also tried it on Pmod OLED display, because there I found this code, but still not working. I draw FSM that is used here, but all seems okay. I am still beginner so maybe it is something I don't see. I know it is hard to analyze my code cause I didn't write comments (rookie mistake), but does exist some project, cause one I found on site doesn't work. I know it was for Nexys3, not Spartan 3E Starter Kit, but I have changed constraints file, matrix (which is not supported), names of states (were strings), but logic seems okay. All I found is for Vivado which doesn't support this board.

Best regards. 

Link to comment
Share on other sites

Hi @ElectronicsBeginner,

I would first try getting the verilog/vhdl code to work on the Spartan 3e starter kit and then alter it to meet your needs. To get the project working on the Spartan 3e starter kit you should open a project for the Spartan 3e Starter kit and add the VHDL/Verilog code from the Nexys 3 project to your new project. Then add the ucf for the Spartant 3e starter kit to your project. You should use the Nexys 3 ucf as a reference for the Spartan 3e starter kit's ucf file. 

thank you,

Jon

 

 

 

Link to comment
Share on other sites

Thank you for tips @jpeyron.

I have done all like you said, but literally. 

For example this constraints I used in my project:

NET "CS" LOC = "B4" | IOSTANDARD = LVTTL | SLEW = SLOW | DRIVE = 6 ;
NET "SDIN" LOC = "A4" | IOSTANDARD = LVTTL | SLEW = SLOW | DRIVE = 6 ;

And this is how it is used in project:

Net "CS" LOC = T12 | IOSTANDARD = LVCMOS33; #Bank = 2, pin name = IO_L19P, Sch name = JA1
Net "SDIN" LOC = V12 | IOSTANDARD = LVCMOS33; #Bank = 2, pin name = IO_L19N, Sch name = JA2  

Difference is in IOSTANDARD, is that important and could that damage display?

Best regards.

Link to comment
Share on other sites

Hi @jpeyron,

Is this way okay? 

Best regards.

NET "CLK" LOC = "C9" | IOSTANDARD = LVCMOS33;
NET "CLK" TNM_NET = sys_clk_pin;
TIMESPEC TS_sys_clk_pin = PERIOD sys_clk_pin 100000 kHz;

NET "CS" LOC = "B4" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
NET "SDIN" LOC = "A4" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
#NET "J<2>" LOC = "D5" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
NET "SCLK" LOC = "C5" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;

NET "DC" LOC = "A6" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
NET "RES" LOC = "B6" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
NET "VBAT" LOC = "E7" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
NET "VDD" LOC = "F7" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;

NET "RST" LOC = "H13" |  IOSTANDARD = LVTTL | PULLDOWN ; 

 

project.7z

ss.jpg

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...