Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- library ieee;
- use ieee.std_logic_1164.all;
- use ieee.numeric_std.all; -- Worlds longest and most stupid oled controller
- entity OLED_DISPLAY is
- Port (
- reset_n : in std_logic;
- clk_50 : in std_logic;
- ascii_valid : in std_logic;
- v_ascii_tdata : in std_logic_vector(24 downto 0); -- 8bits of ascii code contaning temp
- v_ascii_hdata : in std_logic_vector(23 downto 0); -- 8bits of ascii code contaning humidity
- RW : out std_logic; -- Read/Write select signal, R/W=1: Read R/W: =0: Write
- Strobe : out std_logic; -- Same as E, name used from the ARM course (Operation enable signal. Falling edge triggered.)
- RS : out std_logic; -- Register select signal. RS=0: Command, RS=1: Data
- Data_OLED : out std_logic_vector(7 downto 0));
- end OLED_DISPLAY;
- architecture rtl of OLED_DISPLAY is
- type t_oled_init_state is (S_idle,
- S_function_set, -- Function Set: 001110xx
- S_display_off, -- Display OFF: 000010xx
- S_display_clear, -- Display Clear: 00000001
- S_entry_mode_set, -- Entry Mode Set: 00000110
- S_home_command, -- Home Command: 00000010
- S_display_on, -- Display ON: 000011xx
- S_toggle_strobe);
- type t_text_print_state is (S_idle, -- Prints the static text
- S_upper_colon_address,
- S_upper_colon_data,
- S_lower_colon_address,
- S_lower_colon_data,
- S_numb_celsius_sign_adress,
- S_numb_celsius_sign_data,
- S_numb_c_address,
- S_numb_c_data,
- S_numb_procent_address,
- S_numb_procent_data,
- S_toggle_strobe);
- type t_oled_control_state is (S_idle, -- Updates the ascii values
- S_temp_address_tens,
- S_temp_data_tens,
- S_temp_address_ones,
- S_temp_data_ones,
- S_temp_address_fraction,
- S_temp_data_fraction,
- S_humid_address_tens,
- S_humid_data_tens,
- S_humid_address_ones,
- S_humid_data_ones,
- S_humid_address_fraction,
- S_humid_data_fraction,
- S_numb_negative_address,
- S_numb_negative_data,
- S_toggle_strobe);
- constant c_cnt_delay600us : integer := 30000-1;
- constant c_cnt_delay2ms : integer := 100000-1;
- constant c_cnt_delayStrobe : integer := 43-1; -- A bit longer E signal then needed
- constant c_cnt_delay100ms : integer := 5000000;
- signal long_counter : integer range 0 to c_cnt_delay100ms;
- signal counter : integer range 0 to c_cnt_delay2ms;
- signal flag_init_busy : std_logic; -- Flag for "init phase", including the static text printing phase
- signal flag_print_start : std_logic; -- Short flag for starting the "print phase"
- signal print_state : t_text_print_state;
- signal next_print_state : t_text_print_state;
- signal next_state : t_oled_init_state;
- signal init_state : t_oled_init_state;
- signal next_ctr_state : t_oled_control_state;
- signal control_state : t_oled_control_state;
- signal tick600us : std_logic; -- Mainly used for overview in sim
- signal tick2ms : std_logic; -- Mainly used for overview in sim
- begin
- p_oled_state : process(clk_50)
- begin
- if rising_edge(clk_50) then
- tick600us <= '0';
- tick2ms <= '0';
- case init_state is
- when S_idle =>
- if flag_init_busy = '1' then
- if counter = c_cnt_delay2ms then
- tick2ms <= '1';
- counter <= 0;
- init_state <= S_toggle_strobe;
- next_state <= S_function_set;
- else
- counter <= counter + 1;
- end if;
- end if;
- when S_function_set => -- Function Set: Western European font
- if counter = c_cnt_delay600us then
- counter <= 0;
- RS <= '0';
- RW <= '0';
- tick600us <= '1';
- counter <= 0;
- Strobe <= '1';
- Data_OLED <= "00111001";
- init_state <= S_toggle_strobe;
- next_state <= S_display_off;
- else
- counter <= counter + 1;
- end if;
- when S_display_off => -- Display OFF: No cursor, no blinking
- if counter = c_cnt_delay600us then
- tick600us <= '1';
- counter <= 0;
- Strobe <= '1';
- Data_OLED <= "00001000";
- init_state <= S_toggle_strobe;
- next_state <= S_display_clear;
- else
- counter <= counter + 1;
- end if;
- when S_display_clear =>
- if counter = c_cnt_delay600us then
- tick600us <= '1';
- counter <= 0;
- Strobe <= '1';
- Data_OLED <= "00000001";
- init_state <= S_toggle_strobe;
- next_state <= S_entry_mode_set;
- else
- counter <= counter + 1;
- end if;
- when S_entry_mode_set =>
- if counter = c_cnt_delay2ms then
- tick2ms <= '1';
- counter <= 0;
- Strobe <= '1';
- Data_OLED <= "00000110";
- init_state <= S_toggle_strobe;
- next_state <= S_home_command;
- else
- counter <= counter + 1;
- end if;
- when S_home_command =>
- if counter = c_cnt_delay600us then
- tick600us <= '1';
- counter <= 0;
- Strobe <= '1';
- Data_OLED <= "00000010";
- init_state <= S_toggle_strobe;
- next_state <= S_display_on;
- else
- counter <= counter + 1;
- end if;
- when S_display_on => -- Display ON: No cursor, no blinking
- if counter = c_cnt_delay600us then
- tick600us <= '1';
- counter <= 0;
- Strobe <= '1';
- Data_OLED <= "00001100";
- flag_print_start <= '1';
- init_state <= S_toggle_strobe;
- next_state <= S_idle;
- else
- counter <= counter + 1;
- end if;
- when S_toggle_strobe =>
- if counter = c_cnt_delayStrobe then
- Strobe <= '0';
- counter <= 0;
- init_state <= next_state;
- else
- counter <= counter + 1;
- end if;
- when others =>
- init_state <= S_idle;
- end case;
- ---------------------------------------------------------------------- Starts printing the "static" chars
- case print_state is
- when S_idle =>
- if flag_print_start = '1' then
- flag_print_start <= '0';
- print_state <= S_upper_colon_address;
- end if;
- when S_upper_colon_address =>
- if counter = c_cnt_delay600us then
- tick600us <= '1';
- counter <= 0;
- RS <= '0';
- Strobe <= '1';
- Data_OLED <= "10000011"; --ADDRESS 03
- print_state <= S_toggle_strobe;
- next_print_state <= S_upper_colon_data;
- else
- counter <= counter + 1;
- end if;
- when S_upper_colon_data =>
- if counter = c_cnt_delay600us then
- tick600us <= '1';
- counter <= 0;
- RS <= '1';
- Strobe <= '1';
- Data_OLED <= "00101110"; --ASCII code for ","
- print_state <= S_toggle_strobe;
- next_print_state <= S_lower_colon_address;
- else
- counter <= counter + 1;
- end if;
- when S_lower_colon_address =>
- if counter = c_cnt_delay600us then
- tick600us <= '1';
- counter <= 0;
- RS <= '0';
- Strobe <= '1';
- Data_OLED <= "11000011"; --ADDRESS 03
- print_state <= S_toggle_strobe;
- next_print_state <= S_lower_colon_data;
- else
- counter <= counter + 1;
- end if;
- when S_lower_colon_data =>
- if counter = c_cnt_delay600us then
- tick600us <= '1';
- counter <= 0;
- RS <= '1';
- Strobe <= '1';
- Data_OLED <= "00101110"; --ASCII code for ","
- print_state <= S_toggle_strobe;
- next_print_state <= S_numb_celsius_sign_adress;
- else
- counter <= counter + 1;
- end if;
- when S_numb_celsius_sign_adress =>
- if counter = c_cnt_delay600us then
- tick600us <= '1';
- counter <= 0;
- RS <= '0';
- Strobe <= '1';
- Data_OLED <= "11000101"; --ADDRESS 44
- print_state <= S_toggle_strobe;
- next_print_state <= S_numb_celsius_sign_data;
- else
- counter <= counter + 1;
- end if;
- when S_numb_celsius_sign_data =>
- if counter = c_cnt_delay600us then
- tick600us <= '1';
- counter <= 0;
- RS <= '1';
- Strobe <= '1';
- Data_OLED <= "11010010"; --ASCII code for "*"
- print_state <= S_toggle_strobe;
- next_print_state <= S_numb_c_address;
- else
- counter <= counter + 1;
- end if;
- when S_numb_c_address =>
- if counter = c_cnt_delay600us then
- tick600us <= '1';
- counter <= 0;
- RS <= '0';
- Strobe <= '1';
- Data_OLED <= "10000101"; --ADDRESS 05
- print_state <= S_toggle_strobe;
- next_print_state <= S_numb_c_data;
- else
- counter <= counter + 1;
- end if;
- when S_numb_c_data =>
- if counter = c_cnt_delay600us then
- tick600us <= '1';
- counter <= 0;
- RS <= '1';
- Strobe <= '1';
- Data_OLED <= "01000011"; --ASCII code for "C"
- print_state <= S_toggle_strobe;
- next_print_state <= S_numb_procent_address;
- else
- counter <= counter + 1;
- end if;
- when S_numb_procent_address =>
- if counter = c_cnt_delay600us then
- tick600us <= '1';
- counter <= 0;
- RS <= '0';
- Strobe <= '1';
- Data_OLED <= "11000101"; --ADDRESS 45
- print_state <= S_toggle_strobe;
- next_print_state <= S_numb_procent_data;
- else
- counter <= counter + 1;
- end if;
- when S_numb_procent_data =>
- if counter = c_cnt_delay600us then
- tick600us <= '1';
- counter <= 0;
- RS <= '1';
- Strobe <= '1';
- Data_OLED <= "00100101"; --Data for "%" sign
- flag_init_busy <= '0';
- print_state <= S_toggle_strobe;
- next_print_state <= S_idle;
- else
- counter <= counter + 1;
- end if;
- when S_toggle_strobe =>
- if counter = c_cnt_delayStrobe then
- Strobe <= '0';
- counter <= 0;
- print_state <= next_print_state;
- else
- counter <= counter + 1;
- end if;
- when others =>
- init_state <= S_idle;
- end case;
- ------------------------------------------------------------------- Update state for the humidity and temp data
- case control_state is
- when S_idle =>
- if flag_init_busy = '0' then
- if long_counter = c_cnt_delay100ms then
- control_state <= S_temp_address_tens;
- else
- long_counter <= long_counter + 1;
- end if;
- end if;
- when S_temp_address_tens =>
- if counter = c_cnt_delay600us then
- tick600us <= '1';
- counter <= 0;
- RS <= '0';
- Strobe <= '1';
- Data_OLED <= "10000001"; --ADDRESS 01 on the oled
- control_state <= S_toggle_strobe;
- next_ctr_state <= S_temp_data_tens;
- else
- counter <= counter + 1;
- end if;
- when S_temp_data_tens =>
- if counter = c_cnt_delay600us then
- tick600us <= '1';
- counter <= 0;
- if ascii_valid = '1' then
- RS <= '1';
- Strobe <= '1';
- Data_OLED <= v_ascii_tdata(23 downto 16); --Data for the "tens" off the temp data
- control_state <= S_toggle_strobe;
- next_ctr_state <= S_temp_address_ones;
- end if;
- else
- counter <= counter + 1;
- end if;
- when S_temp_address_ones =>
- if counter = c_cnt_delay600us then
- tick600us <= '1';
- counter <= 0;
- RS <= '0';
- Strobe <= '1';
- Data_OLED <= "10000010"; --ADDRESS 02 on the oled
- control_state <= S_toggle_strobe;
- next_ctr_state <= S_temp_data_ones;
- else
- counter <= counter + 1;
- end if;
- when S_temp_data_ones =>
- if counter = c_cnt_delay600us then
- tick600us <= '1';
- counter <= 0;
- if ascii_valid = '1' then
- RS <= '1';
- Strobe <= '1';
- Data_OLED <= v_ascii_tdata(15 downto 8); --Data for the "ones" off temp data
- control_state <= S_toggle_strobe;
- next_ctr_state <= S_temp_address_fraction;
- end if;
- else
- counter <= counter + 1;
- end if;
- when S_temp_address_fraction =>
- if counter = c_cnt_delay600us then
- tick600us <= '1';
- counter <= 0;
- RS <= '0';
- Strobe <= '1';
- Data_OLED <= "10000100"; --ADDRESS 04 on the oled
- control_state <= S_toggle_strobe;
- next_ctr_state <= S_temp_data_fraction;
- else
- counter <= counter + 1;
- end if;
- when S_temp_data_fraction =>
- if counter = c_cnt_delay600us then
- tick600us <= '1';
- counter <= 0;
- if ascii_valid = '1' then
- RS <= '1';
- Strobe <= '1';
- Data_OLED <= v_ascii_tdata(7 downto 0); --Data for the "fraction" off the temp data
- control_state <= S_toggle_strobe;
- next_ctr_state <= S_humid_address_tens;
- end if;
- else
- counter <= counter + 1;
- end if;
- when S_humid_address_tens =>
- if counter = c_cnt_delay600us then
- tick600us <= '1';
- counter <= 0;
- RS <= '0';
- Strobe <= '1';
- Data_OLED <= "11000001"; --ADDRESS 41 on the oled
- control_state <= S_toggle_strobe;
- next_ctr_state <= S_humid_data_tens;
- else
- counter <= counter + 1;
- end if;
- when S_humid_data_tens =>
- if counter = c_cnt_delay600us then
- tick600us <= '1';
- counter <= 0;
- if ascii_valid = '1' then
- RS <= '1';
- Strobe <= '1';
- Data_OLED <= v_ascii_hdata(23 downto 16); --Data for the "tens" off the humidity data
- control_state <= S_toggle_strobe;
- next_ctr_state <= S_humid_address_ones;
- end if;
- else
- counter <= counter + 1;
- end if;
- when S_humid_address_ones =>
- if counter = c_cnt_delay600us then
- tick600us <= '1';
- counter <= 0;
- RS <= '0';
- Strobe <= '1';
- Data_OLED <= "11000011"; --ADDRESS 43 on the oled
- control_state <= S_toggle_strobe;
- next_ctr_state <= S_humid_data_ones;
- else
- counter <= counter + 1;
- end if;
- when S_humid_data_ones =>
- if counter = c_cnt_delay600us then
- tick600us <= '1';
- counter <= 0;
- if ascii_valid = '1' then
- RS <= '1';
- Strobe <= '1';
- Data_OLED <= v_ascii_hdata(15 downto 8); --Data for the "ones" off the humidity data
- control_state <= S_toggle_strobe;
- next_ctr_state <= S_humid_address_fraction;
- end if;
- else
- counter <= counter + 1;
- end if;
- when S_humid_address_fraction =>
- if counter = c_cnt_delay600us then
- tick600us <= '1';
- counter <= 0;
- RS <= '0';
- Strobe <= '1';
- Data_OLED <= "11000100"; --ADDRESS 44 on the oled
- control_state <= S_toggle_strobe;
- next_ctr_state <= S_humid_data_fraction;
- else
- counter <= counter + 1;
- end if;
- when S_humid_data_fraction =>
- if counter = c_cnt_delay600us then
- tick600us <= '1';
- counter <= 0;
- if ascii_valid = '1' then
- RS <= '1';
- Strobe <= '1';
- Data_OLED <= v_ascii_hdata(7 downto 0); --Data for the "fraction" off the humidity data
- control_state <= S_toggle_strobe;
- next_ctr_state <= S_numb_negative_address;
- end if;
- else
- counter <= counter + 1;
- end if;
- when S_numb_negative_address =>
- if counter = c_cnt_delay600us then
- tick600us <= '1';
- counter <= 0;
- RS <= '0';
- Strobe <= '1';
- Data_OLED <= "10000000"; --ADDRESS 00 on the oled
- control_state <= S_toggle_strobe;
- next_ctr_state <= S_numb_negative_data;
- else
- counter <= counter + 1;
- end if;
- when S_numb_negative_data =>
- if counter = c_cnt_delay600us then
- tick600us <= '1';
- counter <= 0;
- if ascii_valid = '1' then
- RS <= '1';
- Strobe <= '1';
- Data_OLED <= "00101101"; --negative sign
- else
- RS <= '1';
- Strobe <= '1';
- Data_OLED <= "11111110"; -- empty sign
- end if;
- control_state <= S_toggle_strobe;
- next_ctr_state <= S_temp_address_tens;
- else
- counter <= counter + 1;
- end if;
- when S_toggle_strobe =>
- if counter = c_cnt_delayStrobe then
- Strobe <= '0';
- counter <= 0;
- control_state <= next_ctr_state;
- else
- counter <= counter + 1;
- end if;
- when others =>
- control_state <= S_idle;
- end case;
- end if;
- if reset_n = '0' then
- Data_OLED <= (others => '0');
- RS <= '0';
- RW <= '0';
- Strobe <= '0';
- flag_print_start <= '0';
- flag_init_busy <= '1';
- print_state <= S_idle;
- control_state <= S_idle;
- init_state <= S_idle;
- end if;
- end process p_oled_state;
- end architecture rtl;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement