mirror of
https://github.com/eried/portapack-mayhem.git
synced 2024-10-01 01:26:06 -04:00
171 lines
4.9 KiB
VHDL
171 lines
4.9 KiB
VHDL
|
--
|
||
|
-- Copyright (C) 2012 Jared Boone, ShareBrained Technology, Inc.
|
||
|
--
|
||
|
-- This file is part of PortaPack.
|
||
|
--
|
||
|
-- This program is free software; you can redistribute it and/or modify
|
||
|
-- it under the terms of the GNU General Public License as published by
|
||
|
-- the Free Software Foundation; either version 2, or (at your option)
|
||
|
-- any later version.
|
||
|
--
|
||
|
-- This program is distributed in the hope that it will be useful,
|
||
|
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
-- GNU General Public License for more details.
|
||
|
--
|
||
|
-- You should have received a copy of the GNU General Public License
|
||
|
-- along with this program; see the file COPYING. If not, write to
|
||
|
-- the Free Software Foundation, Inc., 51 Franklin Street,
|
||
|
-- Boston, MA 02110-1301, USA.
|
||
|
|
||
|
library ieee;
|
||
|
use ieee.std_logic_1164.all;
|
||
|
|
||
|
entity top is
|
||
|
port (
|
||
|
MCU_D : inout std_logic_vector(7 downto 0);
|
||
|
MCU_DIR : in std_logic;
|
||
|
MCU_IO_STBX : in std_logic;
|
||
|
MCU_LCD_WR : in std_logic;
|
||
|
MCU_ADDR : in std_logic;
|
||
|
MCU_ROT_A : out std_logic;
|
||
|
MCU_ROT_B : out std_logic;
|
||
|
MCU_LCD_RD : in std_logic;
|
||
|
|
||
|
TP_U : out std_logic;
|
||
|
TP_D : out std_logic;
|
||
|
TP_L : out std_logic;
|
||
|
TP_R : out std_logic;
|
||
|
|
||
|
SW_SEL : in std_logic;
|
||
|
SW_ROT_A : in std_logic;
|
||
|
SW_ROT_B : in std_logic;
|
||
|
SW_U : in std_logic;
|
||
|
SW_D : in std_logic;
|
||
|
SW_L : in std_logic;
|
||
|
SW_R : in std_logic;
|
||
|
|
||
|
LCD_RESETX : out std_logic;
|
||
|
LCD_RS : out std_logic;
|
||
|
LCD_WRX : out std_logic;
|
||
|
LCD_RDX : out std_logic;
|
||
|
LCD_DB : inout std_logic_vector(15 downto 0);
|
||
|
LCD_TE : in std_logic;
|
||
|
LCD_BACKLIGHT : out std_logic
|
||
|
);
|
||
|
end top;
|
||
|
|
||
|
architecture rtl of top is
|
||
|
|
||
|
signal switches : std_logic_vector(7 downto 0);
|
||
|
|
||
|
type data_direction_t is (from_mcu, to_mcu);
|
||
|
signal data_dir : data_direction_t;
|
||
|
|
||
|
signal mcu_data_out_lcd : std_logic_vector(7 downto 0);
|
||
|
signal mcu_data_out_io : std_logic_vector(7 downto 0);
|
||
|
signal mcu_data_out : std_logic_vector(7 downto 0);
|
||
|
signal mcu_data_in : std_logic_vector(7 downto 0);
|
||
|
|
||
|
signal lcd_data_in : std_logic_vector(15 downto 0);
|
||
|
signal lcd_data_in_mux : std_logic_vector(7 downto 0);
|
||
|
signal lcd_data_out : std_logic_vector(15 downto 0);
|
||
|
|
||
|
signal lcd_data_in_q : std_logic_vector(7 downto 0) := (others => '0');
|
||
|
signal lcd_data_out_q : std_logic_vector(7 downto 0) := (others => '0');
|
||
|
|
||
|
signal tp_q : std_logic_vector(7 downto 0) := (others => '0');
|
||
|
|
||
|
signal lcd_reset_q : std_logic := '1';
|
||
|
signal lcd_backlight_q : std_logic := '0';
|
||
|
|
||
|
signal dir_read : boolean;
|
||
|
signal dir_write : boolean;
|
||
|
|
||
|
signal lcd_read_strobe : boolean;
|
||
|
signal lcd_write_strobe : boolean;
|
||
|
signal lcd_write : boolean;
|
||
|
|
||
|
signal io_strobe : boolean;
|
||
|
signal io_read_strobe : boolean;
|
||
|
signal io_write_strobe : boolean;
|
||
|
|
||
|
begin
|
||
|
|
||
|
-- I/O data
|
||
|
switches <= LCD_TE & not SW_ROT_B & not SW_ROT_A & not SW_SEL & not SW_U & not SW_D & not SW_L & not SW_R;
|
||
|
|
||
|
TP_U <= tp_q(3) when tp_q(7) = '1' else 'Z';
|
||
|
TP_D <= tp_q(2) when tp_q(6) = '1' else 'Z';
|
||
|
TP_L <= tp_q(1) when tp_q(5) = '1' else 'Z';
|
||
|
TP_R <= tp_q(0) when tp_q(4) = '1' else 'Z';
|
||
|
|
||
|
LCD_BACKLIGHT <= lcd_backlight_q;
|
||
|
|
||
|
MCU_ROT_A <= LCD_TE; -- not SW_ROT_A;
|
||
|
MCU_ROT_B <= '0'; -- not SW_ROT_B;
|
||
|
|
||
|
-- State management
|
||
|
data_dir <= to_mcu when MCU_DIR = '1' else from_mcu;
|
||
|
dir_read <= (data_dir = to_mcu);
|
||
|
dir_write <= (data_dir = from_mcu);
|
||
|
|
||
|
io_strobe <= (MCU_IO_STBX = '0');
|
||
|
io_read_strobe <= io_strobe and dir_read;
|
||
|
io_write_strobe <= io_strobe and dir_write;
|
||
|
|
||
|
lcd_read_strobe <= (MCU_LCD_RD = '1');
|
||
|
lcd_write_strobe <= (MCU_LCD_WR = '1');
|
||
|
lcd_write <= not lcd_read_strobe;
|
||
|
|
||
|
-- LCD interface
|
||
|
LCD_RS <= MCU_ADDR;
|
||
|
LCD_RDX <= not MCU_LCD_RD;
|
||
|
LCD_WRX <= not MCU_LCD_WR;
|
||
|
|
||
|
lcd_data_out <= lcd_data_out_q & mcu_data_in;
|
||
|
lcd_data_in <= LCD_DB;
|
||
|
LCD_DB <= lcd_data_out when lcd_write else (others => 'Z');
|
||
|
|
||
|
LCD_RESETX <= not lcd_reset_q;
|
||
|
|
||
|
-- MCU interface
|
||
|
mcu_data_out_lcd <= lcd_data_in(15 downto 8) when lcd_read_strobe else lcd_data_in_q;
|
||
|
mcu_data_out_io <= switches;
|
||
|
mcu_data_out <= mcu_data_out_io when io_read_strobe else mcu_data_out_lcd;
|
||
|
|
||
|
mcu_data_in <= MCU_D;
|
||
|
MCU_D <= mcu_data_out when dir_read else (others => 'Z');
|
||
|
|
||
|
-- Synchronous behaviors:
|
||
|
-- LCD write: Capture LCD high byte on LCD_WRX falling edge.
|
||
|
process(MCU_LCD_WR, mcu_data_in)
|
||
|
begin
|
||
|
if rising_edge(MCU_LCD_WR) then
|
||
|
lcd_data_out_q <= mcu_data_in;
|
||
|
end if;
|
||
|
end process;
|
||
|
|
||
|
-- LCD read: Capture LCD low byte on LCD_RD falling edge.
|
||
|
process(MCU_LCD_RD, lcd_data_in)
|
||
|
begin
|
||
|
if falling_edge(MCU_LCD_RD) then
|
||
|
lcd_data_in_q <= lcd_data_in(7 downto 0);
|
||
|
end if;
|
||
|
end process;
|
||
|
|
||
|
-- I/O write (to resistive touch panel): Capture data from
|
||
|
-- MCU and hold on TP pins until further notice.
|
||
|
process(MCU_IO_STBX, dir_write, mcu_data_in, MCU_ADDR)
|
||
|
begin
|
||
|
if rising_edge(MCU_IO_STBX) and dir_write then
|
||
|
if MCU_ADDR = '0' then
|
||
|
tp_q <= mcu_data_in;
|
||
|
else
|
||
|
lcd_reset_q <= mcu_data_in(0);
|
||
|
lcd_backlight_q <= mcu_data_in(7);
|
||
|
end if;
|
||
|
end if;
|
||
|
end process;
|
||
|
end rtl;
|