---------------------------------------------------------------------------------------------------
-- COMMAND_MODULE.VHD
-- (C) 2025 JAPAN LOGIC DESIGN 日本ロジック設計
-- No unauthorized reproduction or AI training allowed.
-- Unauthorized reproduction prohibited.
---------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------
-- Ver : Date		: Description
-- 0.1 : 2026.01.16	: 1st Version
---------------------------------------------------------------------------------------------------
-- 概要：
-- ・UARTからのキーコード受信によりコマンド処理
-- 
---------------------------------------------------------------------------------------------------

-- Use IEEE library -------------------------------------------------------------------------------
library	IEEE;
use		IEEE.STD_LOGIC_1164.ALL;
use		IEEE.STD_LOGIC_ARITH.ALL;
use		IEEE.STD_LOGIC_UNSIGNED.ALL;

-- エンティティ宣言 -------------------------------------------------------------------------------

entity COMMAND_MODULE is
port (
	-- システム
	nRESET				: in	std_logic;						-- nRESET
	CLK_IN				: in	std_logic;						-- CLOCK 12MHz
	-- UART信号
	RX_DATA				: in	std_logic_vector(7 downto 0);	-- 受信データ
	RX_PARITY_ODD_EVEN	: in	std_logic;						-- 受信データから計算したパリティの値 0:偶数、1:奇数
	RX_RECIEVE_END		: in	std_logic;						-- 受信終了信号 (1-CLOCK)
	-- コマンド信号
	MENU_TRIG_CH		: out	std_logic_vector(3 downto 0);	-- トリガーCH番号 : 0h-Fh
	MENU_TRIG_EDGE		: out	std_logic;						-- トリガーエッジ : 0:RISE,1:FALL
	START_ENTER_KEY		: out	std_logic;						-- ENTERキーフラグ
	SAMPLING_DIV		: out	std_logic_vector(7 downto 0);	-- サンプリング分周比
	SIG_DISP_OFFSET		: out	std_logic_vector(7 downto 0);	-- トリガー前オフセット
	SCALE_OFFSET		: out	std_logic_vector(7 downto 0);	-- 目盛りの10個単位マーカーオフセット
	TRIG_TYPE_1			: out	std_logic_vector(1 downto 0);	-- トリガーモード
	TRIG_TYPE_2			: in	std_logic_vector(1 downto 0);	-- トリガーモード、画面表示同期後
	TRIG_DETECT_F		: in	std_logic						-- トリガー検出フラグ
);
end COMMAND_MODULE;

architecture RTL of COMMAND_MODULE is -------------------------------------------------------------

-- 固定値定義 -------------------------------------------------------------------------------------

-- 信号定義 ---------------------------------------------------------------------------------------

-- キー入力コード -------------------------------
-- 一般信号 -------------------------------------
signal KEY_CODE				: std_logic_vector(7 downto 0);
signal RECIEVE_ACTIVE		: std_logic;
signal MENU_TRIG_CH_f		: std_logic_vector(3 downto 0);
signal MENU_TRIG_EDGE_f		: std_logic;
signal START_ENTER_KEY_f	: std_logic;
signal SAMPLING_DIV_f		: std_logic_vector(7 downto 0);
signal SIG_DISP_OFFSET_f	: std_logic_vector(7 downto 0);
signal SCALE_OFFSET_f		: std_logic_vector(7 downto 0);
signal SAMPLING_UP			: std_logic_vector(7 downto 0);
signal SAMPLING_DN			: std_logic_vector(7 downto 0);
signal TEMP_TRIG_L			: std_logic;
signal TEMP_TRIG_R			: std_logic;
signal TRIG_TYPE_1_f		: std_logic_vector(1 downto 0);

-- 使用モジュール宣言 -----------------------------------------------------------------------------

begin ---------------------------------------------------------------------------------------------

-- モジュール読み出し -----------------------------------------------------------------------------

-- ロジック本体 -----------------------------------------------------------------------------------

	---------------------------------------------
	-- UART受信処理
	---------------------------------------------
	-- 受信データ有効
	RECIEVE_ACTIVE	<= '1' when (( RX_RECIEVE_END = '1' ) and ( RX_PARITY_ODD_EVEN = '0' )) else '0';
	-- 1-CLOCK のみ有効
	process ( CLK_IN ) begin
		if ( CLK_IN'event and CLK_IN = '1' ) then	-- '
			if ( nRESET = '0' ) then			KEY_CODE <= X"00";
			-- 受信 and パリティ偶数 判定
			elsif ( RECIEVE_ACTIVE = '1' ) then	KEY_CODE <= RX_DATA;
			else								KEY_CODE <= X"00";
			end if;
		end if;
	end process;

	---------------------------------------------
	-- ENTERキーフラグ
	---------------------------------------------
	process ( CLK_IN ) begin
		if ( CLK_IN'event and CLK_IN = '1' ) then	-- '
			if ( nRESET = '0' ) then		START_ENTER_KEY_f <= '0';
			elsif( KEY_CODE = X"0D" )  then	START_ENTER_KEY_f <= '1';
			else							START_ENTER_KEY_f <= START_ENTER_KEY_f;
			end if;
		end if;
	end process;

	---------------------------------------------
	-- メニュー操作
	---------------------------------------------
	-- トリガーCH番号 ---------------------------
	process ( CLK_IN ) begin
		if ( CLK_IN'event and CLK_IN = '1' ) then	-- '
			if ( nRESET = '0' ) then			MENU_TRIG_CH_f <= (others => '0');
			elsif( KEY_CODE = X"31" )  then		MENU_TRIG_CH_f <= MENU_TRIG_CH_f - 1 ;	-- '1'
			elsif( KEY_CODE = X"32" )  then		MENU_TRIG_CH_f <= MENU_TRIG_CH_f + 1 ;	-- '2'
			else								MENU_TRIG_CH_f <= MENU_TRIG_CH_f;		-- KEEP
			end if;
		end if;
	end process;
	-- トリガーエッジ(立上り／立下り) -----------
	process ( CLK_IN ) begin
		if ( CLK_IN'event and CLK_IN = '1' ) then	-- '
			if ( nRESET = '0' ) then		MENU_TRIG_EDGE_f <= '0';
			elsif( KEY_CODE = X"33" )  then	MENU_TRIG_EDGE_f <= not MENU_TRIG_EDGE_f;	-- '3'
			else							MENU_TRIG_EDGE_f <= MENU_TRIG_EDGE_f;		-- KEEP
			end if;
		end if;
	end process;
	-- サンプリング分周比 -----------------------
	--	表示上では横方向の波形拡大/縮小
	-- UP/DOWN 定義
	SAMPLING_UP	<=	X"00" when ( SAMPLING_DIV_f = X"00" )	-- KEEP
			else	X"00" when ( SAMPLING_DIV_f = X"01" )	-- 50MHz:  " 20nS"
			else	X"01" when ( SAMPLING_DIV_f = X"04" )	-- 25MHz:  " 40nS
			else	X"04" when ( SAMPLING_DIV_f = X"09" )	-- 10MHz:  "100nS
			else	X"09" when ( SAMPLING_DIV_f = X"13" )	-- 5MHz:   "200nS
			else	X"13" when ( SAMPLING_DIV_f = X"31" )	-- 2.5MHz: "400nS
			else	X"31" when ( SAMPLING_DIV_f = X"63" )	-- 1MHz:   "  1uS
			else	X"63" when ( SAMPLING_DIV_f = X"C7" )	-- 0.5MHz: "  2uS
			else	X"00";									-- OTHER
	SAMPLING_DN	<=	X"01" when ( SAMPLING_DIV_f = X"00" )	-- 25MHz:  " 40nS
			else	X"04" when ( SAMPLING_DIV_f = X"01" )	-- 10MHz:  "100nS
			else	X"09" when ( SAMPLING_DIV_f = X"04" )	-- 5MHz:   "200nS
			else	X"13" when ( SAMPLING_DIV_f = X"09" )	-- 2.5MHz: "400nS
			else	X"31" when ( SAMPLING_DIV_f = X"13" )	-- 1MHz:   "  1uS
			else	X"63" when ( SAMPLING_DIV_f = X"31" )	-- 0.5MHz: "  2uS
			else	X"C7" when ( SAMPLING_DIV_f = X"63" )	-- 0.25MHz:"  4uS
			else	X"C7" when ( SAMPLING_DIV_f = X"C7" )	-- KEEP
			else	X"00";									-- OTHER
	-- UP/DOWN 処理
	process ( CLK_IN ) begin
		if ( CLK_IN'event and CLK_IN = '1' ) then	-- '
			if ( nRESET = '0' ) then			SAMPLING_DIV_f <= (others => '0');
			elsif ( TRIG_TYPE_2 = "10" ) then	SAMPLING_DIV_f <= SAMPLING_DIV_f;	-- KEEP:トリガーモード停止中
			elsif ( KEY_CODE = X"35" ) then		SAMPLING_DIV_f <= SAMPLING_UP;		-- '5' UP (1/2)
			elsif ( KEY_CODE = X"34" ) then		SAMPLING_DIV_f <= SAMPLING_DN;		-- '4' DOWN (x2)
			else								SAMPLING_DIV_f <= SAMPLING_DIV_f;	-- KEEP
			end if;
		end if;
	end process;
	-- トリガー位置 -----------------------------
	--	トリガー位置、目盛り位置を左右に移動させる
	TEMP_TRIG_L	<= '1' when (( KEY_CODE = X"36" ) and ( SIG_DISP_OFFSET_f > X"04" )) else '0'; -- '6'
	TEMP_TRIG_R	<= '1' when (( KEY_CODE = X"37" ) and ( SIG_DISP_OFFSET_f < X"5A" )) else '0'; -- '7'
	process ( CLK_IN ) begin
		if ( CLK_IN'event and CLK_IN = '1' ) then	-- '
			if ( nRESET = '0' ) then
				SIG_DISP_OFFSET_f	<= X"20";
				SCALE_OFFSET_f		<= X"06";
			elsif ( TRIG_TYPE_2 = "10" ) then				-- KEEP:トリガーモード停止中
				SIG_DISP_OFFSET_f	<= SIG_DISP_OFFSET_f;
				SCALE_OFFSET_f		<= SCALE_OFFSET_f;
			-- 左移動
			elsif ( TEMP_TRIG_L = '1' ) then
				SIG_DISP_OFFSET_f	<= SIG_DISP_OFFSET_f - 1 ;
				if ( SCALE_OFFSET_f = X"09" ) then	SCALE_OFFSET_f <= X"00";
				else								SCALE_OFFSET_f <= SCALE_OFFSET_f + 1 ;
				end if;
			-- 右移動
			elsif ( TEMP_TRIG_R = '1' ) then
				SIG_DISP_OFFSET_f	<= SIG_DISP_OFFSET_f + 1 ;
				if ( SCALE_OFFSET_f = X"00" ) then	SCALE_OFFSET_f <= X"09";
				else								SCALE_OFFSET_f <= SCALE_OFFSET_f - 1 ;
				end if;
			-- KEEP
			else
				SIG_DISP_OFFSET_f	<= SIG_DISP_OFFSET_f;
				SCALE_OFFSET_f		<= SCALE_OFFSET_f;
			end if;
		end if;
	end process;
	-- トリガーモード ---------------------------
	--	00:コンティニュアス、01:シングルトリガー待ち、10:シングルトリガー停止
	process ( CLK_IN ) begin
		if ( CLK_IN'event and CLK_IN = '1' ) then	-- '
			if ( nRESET = '0' ) then			TRIG_TYPE_1_f <= "00";
			-- シングルモード中にトリガー検出したら停止
			elsif (( TRIG_DETECT_F = '1' ) and ( TRIG_TYPE_2 = "01" )) then		TRIG_TYPE_1_f <= "10";	-- 停止
			-- キー操作
			elsif ( ( KEY_CODE = X"38" ) and ( TRIG_TYPE_1_f = "10" ) ) then	TRIG_TYPE_1_f <= "00";
			elsif ( ( KEY_CODE = X"38" ) and ( TRIG_TYPE_1_f /= "10" ) ) then	TRIG_TYPE_1_f <= TRIG_TYPE_1_f + 1 ;
			-- KEEP	
			else																TRIG_TYPE_1_f <= TRIG_TYPE_1_f;
			end if;
		end if;
	end process;

-- 出力 -------------------------------------------------------------------------------------------
	MENU_TRIG_CH	<= MENU_TRIG_CH_f;
	MENU_TRIG_EDGE	<= MENU_TRIG_EDGE_f;
	START_ENTER_KEY <= START_ENTER_KEY_f;
	SAMPLING_DIV	<= SAMPLING_DIV_f;
	SIG_DISP_OFFSET	<= SIG_DISP_OFFSET_f;
	SCALE_OFFSET	<= SCALE_OFFSET_f;
	TRIG_TYPE_1		<= TRIG_TYPE_1_f;

-- END --------------------------------------------------------------------------------------------
-- (C) 2025 JAPAN LOGIC DESIGN 日本ロジック設計
-- No unauthorized reproduction or AI training allowed.
-- Unauthorized reproduction prohibited.
end RTL;

