mirror of https://github.com/marqs85/ossc.git
570 lines
25 KiB
VHDL
570 lines
25 KiB
VHDL
-- (C) 2001-2015 Altera Corporation. All rights reserved.
|
|
-- Your use of Altera Corporation's design tools, logic functions and other
|
|
-- software and tools, and its AMPP partner logic functions, and any output
|
|
-- files any of the foregoing (including device programming or simulation
|
|
-- files), and any associated documentation or information are expressly subject
|
|
-- to the terms and conditions of the Altera Program License Subscription
|
|
-- Agreement, Altera MegaCore Function License Agreement, or other applicable
|
|
-- license agreement, including, without limitation, that your use is for the
|
|
-- sole purpose of programming logic devices manufactured by Altera and sold by
|
|
-- Altera or its authorized distributors. Please refer to the applicable
|
|
-- agreement for further details.
|
|
|
|
|
|
-------------------------------------------------------------------------------------
|
|
-- This module takes a command ID and data, and generates a 48-bit message for it.
|
|
-- It will first check if the command is a valid 48-bit command and produce the
|
|
-- following outputs:
|
|
-- 1. o_dataout -> a single bit output that produces the message to be sent to the
|
|
-- SD card one bit at a time. Every time the i_message_bit_out input
|
|
-- is high and the i_clock has a positive edge, a new bit is produced.
|
|
-- 2. o_message_done -> a signal that is asserted high when the entire message has been
|
|
-- produced through the o_dataout output.
|
|
-- 3. o_valid -> is a signal that is asserted high if the specified message is valid.
|
|
-- 4. o_response_type -> indicates the command response type.
|
|
-- 5. o_returning_ocr -> the response from the SD card will contain the OCR register
|
|
-- 6. o_returning_cid -> the response from the SD card will contain the CID register
|
|
-- 7. o_returning_rca -> the response from the SD card will contain the RCA register
|
|
-- 8. o_returning_csd -> the response from the SD card will contain the CSD register
|
|
-- 9. o_data_read -> asserted when the command being sent is a data read command.
|
|
-- 10. o_data_write -> asserted when the command being sent is a data write command.
|
|
-- 11. o_wait_cmd_busy -> is set high when the response to this command will be
|
|
-- followed by a busy signal.
|
|
--
|
|
-- NOTES/REVISIONS:
|
|
-------------------------------------------------------------------------------------
|
|
library ieee;
|
|
use ieee.std_logic_1164.all;
|
|
use ieee.std_logic_arith.all;
|
|
use ieee.std_logic_unsigned.all;
|
|
|
|
entity Altera_UP_SD_Card_48_bit_Command_Generator is
|
|
generic (
|
|
-- Basic commands
|
|
COMMAND_0_GO_IDLE : STD_LOGIC_VECTOR(5 downto 0) := "000000";
|
|
COMMAND_2_ALL_SEND_CID : STD_LOGIC_VECTOR(5 downto 0) := "000010";
|
|
COMMAND_3_SEND_RCA : STD_LOGIC_VECTOR(5 downto 0) := "000011";
|
|
COMMAND_4_SET_DSR : STD_LOGIC_VECTOR(5 downto 0) := "000100";
|
|
COMMAND_6_SWITCH_FUNCTION : STD_LOGIC_VECTOR(5 downto 0) := "000110";
|
|
COMMAND_7_SELECT_CARD : STD_LOGIC_VECTOR(5 downto 0) := "000111";
|
|
COMMAND_9_SEND_CSD : STD_LOGIC_VECTOR(5 downto 0) := "001001";
|
|
COMMAND_10_SEND_CID : STD_LOGIC_VECTOR(5 downto 0) := "001010";
|
|
COMMAND_12_STOP_TRANSMISSION : STD_LOGIC_VECTOR(5 downto 0) := "001100";
|
|
COMMAND_13_SEND_STATUS : STD_LOGIC_VECTOR(5 downto 0) := "001101";
|
|
COMMAND_15_GO_INACTIVE : STD_LOGIC_VECTOR(5 downto 0) := "001111";
|
|
-- Block oriented read/write/lock commands
|
|
COMMAND_16_SET_BLOCK_LENGTH : STD_LOGIC_VECTOR(5 downto 0) := "010000";
|
|
-- Block oriented read commands
|
|
COMMAND_17_READ_BLOCK : STD_LOGIC_VECTOR(5 downto 0) := "010001";
|
|
COMMAND_18_READ_MULTIPLE_BLOCKS : STD_LOGIC_VECTOR(5 downto 0) := "010010";
|
|
-- Block oriented write commands
|
|
COMMAND_24_WRITE_BLOCK : STD_LOGIC_VECTOR(5 downto 0) := "011000";
|
|
COMMAND_25_WRITE_MULTIPLE_BLOCKS : STD_LOGIC_VECTOR(5 downto 0) := "011001";
|
|
COMMAND_27_PROGRAM_CSD : STD_LOGIC_VECTOR(5 downto 0) := "011011";
|
|
-- Block oriented write-protection commands
|
|
COMMAND_28_SET_WRITE_PROTECT : STD_LOGIC_VECTOR(5 downto 0) := "011100";
|
|
COMMAND_29_CLEAR_WRITE_PROTECT : STD_LOGIC_VECTOR(5 downto 0) := "011101";
|
|
COMMAND_30_SEND_PROTECTED_GROUPS : STD_LOGIC_VECTOR(5 downto 0) := "011110";
|
|
-- Erase commands
|
|
COMMAND_32_ERASE_BLOCK_START : STD_LOGIC_VECTOR(5 downto 0) := "100000";
|
|
COMMAND_33_ERASE_BLOCK_END : STD_LOGIC_VECTOR(5 downto 0) := "100001";
|
|
COMMAND_38_ERASE_SELECTED_GROUPS: STD_LOGIC_VECTOR(5 downto 0) := "100110";
|
|
-- Block lock commands
|
|
COMMAND_42_LOCK_UNLOCK : STD_LOGIC_VECTOR(5 downto 0) := "101010";
|
|
-- Command Type Settings
|
|
COMMAND_55_APP_CMD : STD_LOGIC_VECTOR(5 downto 0) := "110111";
|
|
COMMAND_56_GEN_CMD : STD_LOGIC_VECTOR(5 downto 0) := "111000";
|
|
-- Application Specific commands - must be preceeded with command 55.
|
|
ACOMMAND_6_SET_BUS_WIDTH : STD_LOGIC_VECTOR(5 downto 0) := "000110";
|
|
ACOMMAND_13_SD_STATUS : STD_LOGIC_VECTOR(5 downto 0) := "001101";
|
|
ACOMMAND_22_SEND_NUM_WR_BLOCKS : STD_LOGIC_VECTOR(5 downto 0) := "010100";
|
|
ACOMMAND_23_SET_BLK_ERASE_COUNT : STD_LOGIC_VECTOR(5 downto 0) := "010101";
|
|
ACOMMAND_41_SEND_OP_CONDITION : STD_LOGIC_VECTOR(5 downto 0) := "101001";
|
|
ACOMMAND_42_SET_CLR_CARD_DETECT : STD_LOGIC_VECTOR(5 downto 0) := "101010";
|
|
ACOMMAND_51_SEND_SCR : STD_LOGIC_VECTOR(5 downto 0) := "110011";
|
|
-- First custom_command
|
|
FIRST_NON_PREDEFINED_COMMAND : STD_LOGIC_VECTOR(3 downto 0) := "1010"
|
|
);
|
|
port
|
|
(
|
|
i_clock : in std_logic;
|
|
i_reset_n : in std_logic;
|
|
i_message_bit_out : in std_logic;
|
|
i_command_ID : in std_logic_vector(5 downto 0);
|
|
i_argument : in std_logic_vector(31 downto 0);
|
|
i_predefined_message : in std_logic_vector(3 downto 0);
|
|
i_generate : in std_logic;
|
|
i_DSR : in std_logic_vector(15 downto 0);
|
|
i_OCR : in std_logic_vector(31 downto 0);
|
|
i_RCA : in std_logic_vector(15 downto 0);
|
|
o_dataout : out std_logic;
|
|
o_message_done : out std_logic;
|
|
o_valid : out std_logic;
|
|
o_returning_ocr : out std_logic;
|
|
o_returning_cid : out std_logic;
|
|
o_returning_rca : out std_logic;
|
|
o_returning_csd : out std_logic;
|
|
o_returning_status : out std_logic;
|
|
o_data_read : out std_logic;
|
|
o_data_write : out std_logic;
|
|
o_wait_cmd_busy : out std_logic;
|
|
o_last_cmd_was_55 : out std_logic;
|
|
o_response_type : out std_logic_vector(2 downto 0)
|
|
);
|
|
|
|
end entity;
|
|
|
|
architecture rtl of Altera_UP_SD_Card_48_bit_Command_Generator is
|
|
|
|
component Altera_UP_SD_CRC7_Generator
|
|
port
|
|
(
|
|
i_clock : in std_logic;
|
|
i_enable : in std_logic;
|
|
i_reset_n : in std_logic;
|
|
i_shift : in std_logic;
|
|
i_datain : in std_logic;
|
|
o_dataout : out std_logic;
|
|
o_crcout : out std_logic_vector(6 downto 0)
|
|
);
|
|
end component;
|
|
|
|
-- Local wires
|
|
-- REGISTERED
|
|
signal counter : std_logic_vector(6 downto 0);
|
|
signal last_command_id : std_logic_vector(5 downto 0);
|
|
signal message_bits : std_logic_vector(39 downto 0);
|
|
signal last_command_sent_was_CMD55, valid : std_logic;
|
|
signal bit_to_send, sending_CRC, command_valid : std_logic;
|
|
signal returning_cid_reg, returning_rca_reg, returning_csd_reg, returning_dsr_reg, returning_ocr_reg, returning_status_reg : std_logic;
|
|
-- UNREGISTERED
|
|
signal temp_4_bits : std_logic_vector(3 downto 0);
|
|
signal message_done, CRC_generator_out, produce_next_bit : std_logic;
|
|
signal app_specific_valid, regular_command_valid : std_logic;
|
|
signal response_type, response_type_reg : std_logic_vector(2 downto 0);
|
|
signal cmd_argument : std_logic_vector(31 downto 0);
|
|
begin
|
|
-- This set of bits is necessary to allow the SD card to accept a VDD level for communication.
|
|
temp_4_bits <= "1111" when ((i_OCR(23) = '1') or (i_OCR(22) = '1') or (i_OCR(21) = '1') or (i_OCR(20) = '1')) else "0000";
|
|
-- Generate the bits to be sent to the SD card. These bits must pass through the CRC generator
|
|
-- to produce error checking code. The error checking code will follow the message. The message terminates with
|
|
-- a logic '1'. Total message length is 48 bits.
|
|
message_data_generator: process(i_clock, i_reset_n)
|
|
begin
|
|
if (i_reset_n = '0') then
|
|
message_bits <= (OTHERS => '0');
|
|
else
|
|
if (rising_edge(i_clock)) then
|
|
if (i_generate = '1') then
|
|
-- Store type of a response.
|
|
response_type_reg <= response_type;
|
|
-- Generate a message. Please note that the predefined messages are used for initialization.
|
|
-- If executed in sequence, they will initialize the SD card to work correctly. Only once these
|
|
-- instructions are completed can the data transfer begin.
|
|
case (i_predefined_message) is
|
|
when "0000" =>
|
|
-- Generate a predefined message - CMD0.
|
|
message_bits <= ("01" & COMMAND_0_GO_IDLE & "00000000000000000000000000000000");
|
|
when "0001" =>
|
|
-- Generate a predefined message - CMD55.
|
|
message_bits <= ("01" & COMMAND_55_APP_CMD & "0000000000000000" & "0000000000000000");
|
|
when "0010" =>
|
|
-- Generate a predefined message - ACMD41.
|
|
message_bits <= ("01" & ACOMMAND_41_SEND_OP_CONDITION & "0000" & temp_4_bits & "000" & i_OCR(20) & "00000000000000000000");
|
|
when "0011" =>
|
|
-- Generate a predefined message - CMD2.
|
|
message_bits <= ("01" & COMMAND_2_ALL_SEND_CID & "00000000000000000000000000000000");
|
|
when "0100" =>
|
|
-- Generate a predefined message - CMD3.
|
|
message_bits <= ("01" & COMMAND_3_SEND_RCA & "00000000000000000000000000000000");
|
|
when "0101" =>
|
|
-- Generate a predefined message - CMD9.
|
|
message_bits <= ("01" & COMMAND_9_SEND_CSD & i_RCA & "0000000000000000");
|
|
when "0110" =>
|
|
-- Generate a predefined message - CMD4.
|
|
message_bits <= ("01" & COMMAND_4_SET_DSR & i_DSR & "0000000000000000");
|
|
when "0111" =>
|
|
-- Generate a predefined message - CMD16. Set block length to 512.
|
|
message_bits <= ("01" & COMMAND_16_SET_BLOCK_LENGTH & "0000000000000000" & "0000001000000000" );
|
|
when "1000" =>
|
|
-- Generate a predefined message - CMD7. Select the card so we can access it's data.
|
|
message_bits <= ("01" & COMMAND_7_SELECT_CARD & i_RCA & "0000001000000000" );
|
|
when "1001" =>
|
|
-- Generate a predefined message - CMD13. Send SD card status.
|
|
message_bits <= ("01" & COMMAND_13_SEND_STATUS & i_RCA & "0000000000000000");
|
|
|
|
when others =>
|
|
-- Generate a custom message
|
|
message_bits <= ("01" & i_command_ID & cmd_argument);
|
|
end case;
|
|
else
|
|
-- Shift bits out as needed
|
|
if (produce_next_bit = '1') then
|
|
-- Shift message bits.
|
|
message_bits(39 downto 1) <= message_bits(38 downto 0);
|
|
message_bits(0) <= '0';
|
|
end if;
|
|
end if;
|
|
end if;
|
|
end if;
|
|
end process;
|
|
|
|
-- Generate command argument based on the command_ID. For most commands, the argument is user specified.
|
|
-- For some commands, it is necessary to send a particular SD Card register contents. Hence, these contents are
|
|
-- sent instead of the user data.
|
|
argument_generator: process (i_command_ID, last_command_sent_was_CMD55, i_generate, i_RCA, i_DSR, i_OCR, i_argument)
|
|
begin
|
|
cmd_argument <= i_argument;
|
|
if (i_generate = '1') then
|
|
case (i_command_ID) is
|
|
when COMMAND_4_SET_DSR =>
|
|
cmd_argument <= i_DSR & i_argument(15 downto 0);
|
|
when COMMAND_7_SELECT_CARD =>
|
|
cmd_argument <= i_RCA & i_argument(15 downto 0);
|
|
when COMMAND_9_SEND_CSD =>
|
|
cmd_argument <= i_RCA & i_argument(15 downto 0);
|
|
when COMMAND_10_SEND_CID =>
|
|
cmd_argument <= i_RCA & i_argument(15 downto 0);
|
|
when COMMAND_13_SEND_STATUS =>
|
|
cmd_argument <= i_RCA & i_argument(15 downto 0);
|
|
when COMMAND_15_GO_INACTIVE =>
|
|
cmd_argument <= i_RCA & i_argument(15 downto 0);
|
|
when COMMAND_55_APP_CMD =>
|
|
cmd_argument <= i_RCA & i_argument(15 downto 0);
|
|
when ACOMMAND_41_SEND_OP_CONDITION =>
|
|
if (last_command_sent_was_CMD55 = '1') then
|
|
cmd_argument <= i_OCR;
|
|
end if;
|
|
when others =>
|
|
cmd_argument <= i_argument;
|
|
end case;
|
|
end if;
|
|
end process;
|
|
|
|
-- Validate the message ID before sending it out.
|
|
command_validator: process(i_clock, i_reset_n)
|
|
begin
|
|
if (i_reset_n = '0') then
|
|
command_valid <= '0';
|
|
else
|
|
if (rising_edge(i_clock)) then
|
|
if (i_generate = '1') then
|
|
if (("0" & i_predefined_message) >= ("0" & FIRST_NON_PREDEFINED_COMMAND)) then
|
|
-- Check the custom message
|
|
if (last_command_sent_was_CMD55 = '1') then
|
|
-- Check the application specific messages
|
|
command_valid <= app_specific_valid;
|
|
else
|
|
-- Check the default messages.
|
|
command_valid <= regular_command_valid;
|
|
end if;
|
|
else
|
|
-- A command is valid if the message is predefined.
|
|
command_valid <= '1';
|
|
end if;
|
|
end if;
|
|
end if;
|
|
end if;
|
|
end process;
|
|
|
|
-- Registers that indicate that the command sent will return contents of a control register.
|
|
-- The contents of the response should therefore be stored in the appropriate register.
|
|
responses_with_control_regs: process(i_clock, i_reset_n, last_command_sent_was_CMD55, last_command_id, message_done)
|
|
begin
|
|
if (i_reset_n = '0') then
|
|
returning_ocr_reg <= '0';
|
|
returning_cid_reg <= '0';
|
|
returning_rca_reg <= '0';
|
|
returning_csd_reg <= '0';
|
|
returning_status_reg <= '0';
|
|
elsif (rising_edge(i_clock)) then
|
|
if (i_generate = '1') then
|
|
returning_ocr_reg <= '0';
|
|
returning_cid_reg <= '0';
|
|
returning_rca_reg <= '0';
|
|
returning_csd_reg <= '0';
|
|
returning_status_reg <= '0';
|
|
elsif (message_done = '1') then
|
|
-- OCR
|
|
if ((last_command_sent_was_CMD55 = '1') and (last_command_id = ACOMMAND_41_SEND_OP_CONDITION)) then
|
|
returning_ocr_reg <= '1';
|
|
end if;
|
|
-- CID
|
|
if (last_command_id = COMMAND_2_ALL_SEND_CID) then
|
|
returning_cid_reg <= '1';
|
|
end if;
|
|
-- RCA
|
|
if (last_command_id = COMMAND_3_SEND_RCA) then
|
|
returning_rca_reg <= '1';
|
|
end if;
|
|
-- CSD
|
|
if (last_command_id = COMMAND_9_SEND_CSD) then
|
|
returning_csd_reg <= '1';
|
|
end if;
|
|
-- Status
|
|
if ((last_command_sent_was_CMD55 = '0') and (last_command_id = COMMAND_13_SEND_STATUS)) then
|
|
returning_status_reg <= '1';
|
|
end if;
|
|
|
|
end if;
|
|
end if;
|
|
end process;
|
|
|
|
-- Count the number of bits sent using a counter.
|
|
sent_bit_counter: process(i_clock, i_reset_n, i_generate, produce_next_bit, counter)
|
|
begin
|
|
if (i_reset_n = '0') then
|
|
counter <= (OTHERS => '0');
|
|
else
|
|
if (rising_edge(i_clock)) then
|
|
if (i_generate = '1') then
|
|
-- Reset the counter indicating the number of bits produced.
|
|
counter <= "0000000";
|
|
else
|
|
if (produce_next_bit = '1') then
|
|
-- Update the number of message bits sent.
|
|
counter <= counter + '1';
|
|
end if;
|
|
end if;
|
|
end if;
|
|
end if;
|
|
end process;
|
|
|
|
-- Select the source for the output data to be either the message data or the CRC bits.
|
|
source_selector: process(i_clock, i_reset_n, i_generate)
|
|
begin
|
|
if (i_reset_n = '0') then
|
|
sending_CRC <= '0';
|
|
else
|
|
if (rising_edge(i_clock)) then
|
|
if (i_generate = '1') then
|
|
-- Set sending CRC flag to 0.
|
|
sending_CRC <= '0';
|
|
else
|
|
-- If this is the last bit being sent, then bits that follow are the CRC bits.
|
|
if (counter = "0101000") then
|
|
sending_CRC <= '1';
|
|
end if;
|
|
end if;
|
|
end if;
|
|
end if;
|
|
end process;
|
|
|
|
-- When the message is sent, store its ID. In a special case when CMD55 is sent, the next command can be an application
|
|
-- specific command. We need to check those command IDs to verify the validity of the message.
|
|
CMD55_recognizer: process(i_clock, i_reset_n, i_generate, produce_next_bit, counter, message_done, last_command_id)
|
|
begin
|
|
if (i_reset_n = '0') then
|
|
last_command_sent_was_CMD55 <= '0';
|
|
else
|
|
if (rising_edge(i_clock)) then
|
|
if (i_generate = '0') then
|
|
-- Store the ID of the current command.
|
|
if (produce_next_bit = '1') then
|
|
if (counter = "0000000") then
|
|
last_command_id <= message_bits(37 downto 32);
|
|
end if;
|
|
end if;
|
|
-- When message has been sent then check if it was CMD55.
|
|
if (message_done = '1') then
|
|
if (last_command_id = COMMAND_55_APP_CMD) then
|
|
last_command_sent_was_CMD55 <= '1';
|
|
else
|
|
last_command_sent_was_CMD55 <= '0';
|
|
end if;
|
|
end if;
|
|
end if;
|
|
end if;
|
|
end if;
|
|
end process;
|
|
|
|
-- Instantiate a CRC7 generator. Message bits will pass through it to create the CRC code for the message.
|
|
CRC7_Gen: Altera_UP_SD_CRC7_Generator PORT MAP
|
|
(
|
|
i_clock => i_clock,
|
|
i_reset_n => i_reset_n,
|
|
i_enable => i_message_bit_out,
|
|
i_shift => sending_CRC,
|
|
i_datain => message_bits(39),
|
|
o_dataout => CRC_generator_out
|
|
);
|
|
|
|
-- Define the source of the data produced by this module, depending on the counter value and the sending_CRC register state.
|
|
data_bit_register: process(i_clock, i_reset_n, i_generate, produce_next_bit, counter)
|
|
begin
|
|
if (i_reset_n = '0') then
|
|
bit_to_send <= '1';
|
|
else
|
|
if (rising_edge(i_clock)) then
|
|
if (i_generate = '1') then
|
|
bit_to_send <= '1';
|
|
elsif (produce_next_bit = '1') then
|
|
-- Send data to output.
|
|
if (sending_CRC = '0') then
|
|
-- Send message bits
|
|
bit_to_send <= message_bits(39);
|
|
else
|
|
-- Send CRC bits
|
|
if ((counter = "0101111") or (counter = "0110000")) then
|
|
-- At the end of CRC bits put a 1.
|
|
bit_to_send <= '1';
|
|
else
|
|
bit_to_send <= CRC_generator_out;
|
|
end if;
|
|
end if;
|
|
end if;
|
|
end if;
|
|
end if;
|
|
end process;
|
|
|
|
-- Define conditions to produce the next message bit on the module output port o_dataout.
|
|
produce_next_bit <= i_message_bit_out and (not message_done);
|
|
-- Message is done when the last bit appears at the output.
|
|
message_done <= '1' when (counter = "0110001") else '0';
|
|
-- Check the application specific messages
|
|
app_specific_valid <= '1' when (
|
|
--(i_command_ID = COMMAND_0_GO_IDLE) or
|
|
(i_command_ID = COMMAND_2_ALL_SEND_CID) or
|
|
(i_command_ID = COMMAND_3_SEND_RCA) or
|
|
(i_command_ID = COMMAND_4_SET_DSR) or
|
|
--(i_command_ID = ACOMMAND_6_SET_BUS_WIDTH) or
|
|
--(i_command_ID = COMMAND_7_SELECT_CARD) or
|
|
(i_command_ID = COMMAND_9_SEND_CSD) or
|
|
(i_command_ID = COMMAND_10_SEND_CID) or
|
|
--(i_command_ID = COMMAND_12_STOP_TRANSMISSION) or
|
|
(i_command_ID = ACOMMAND_13_SD_STATUS) or
|
|
--(i_command_ID = COMMAND_15_GO_INACTIVE) or
|
|
--(i_command_ID = COMMAND_16_SET_BLOCK_LENGTH) or
|
|
(i_command_ID = COMMAND_17_READ_BLOCK) or
|
|
--(i_command_ID = COMMAND_18_READ_MULTIPLE_BLOCKS) or
|
|
(i_command_ID = ACOMMAND_22_SEND_NUM_WR_BLOCKS) or
|
|
(i_command_ID = ACOMMAND_23_SET_BLK_ERASE_COUNT) or
|
|
(i_command_ID = COMMAND_24_WRITE_BLOCK) or
|
|
(i_command_ID = COMMAND_25_WRITE_MULTIPLE_BLOCKS) or
|
|
(i_command_ID = COMMAND_27_PROGRAM_CSD) or
|
|
(i_command_ID = COMMAND_28_SET_WRITE_PROTECT) or
|
|
(i_command_ID = COMMAND_29_CLEAR_WRITE_PROTECT) or
|
|
(i_command_ID = COMMAND_30_SEND_PROTECTED_GROUPS) or
|
|
(i_command_ID = COMMAND_32_ERASE_BLOCK_START) or
|
|
(i_command_ID = COMMAND_33_ERASE_BLOCK_END) or
|
|
(i_command_ID = COMMAND_38_ERASE_SELECTED_GROUPS) or
|
|
(i_command_ID = ACOMMAND_41_SEND_OP_CONDITION) or
|
|
(i_command_ID = ACOMMAND_42_SET_CLR_CARD_DETECT) or
|
|
(i_command_ID = ACOMMAND_51_SEND_SCR) or
|
|
(i_command_ID = COMMAND_55_APP_CMD) or
|
|
(i_command_ID = COMMAND_56_GEN_CMD)
|
|
)
|
|
else '0';
|
|
-- Check the default messages.
|
|
regular_command_valid <= '1' when (
|
|
-------------------------------------------------------
|
|
-- Disabled to prevent malfunction of the core
|
|
-------------------------------------------------------
|
|
--(i_command_ID = COMMAND_0_GO_IDLE) or
|
|
--(i_command_ID = COMMAND_6_SWITCH_FUNCTION) or
|
|
--(i_command_ID = COMMAND_7_SELECT_CARD) or
|
|
--(i_command_ID = COMMAND_15_GO_INACTIVE) or
|
|
--(i_command_ID = COMMAND_27_PROGRAM_CSD) or
|
|
--(i_command_ID = COMMAND_30_SEND_PROTECTED_GROUPS) or
|
|
--(i_command_ID = COMMAND_42_LOCK_UNLOCK) or
|
|
-------------------------------------------------------
|
|
(i_command_ID = COMMAND_2_ALL_SEND_CID) or
|
|
(i_command_ID = COMMAND_3_SEND_RCA) or
|
|
(i_command_ID = COMMAND_4_SET_DSR) or
|
|
(i_command_ID = COMMAND_9_SEND_CSD) or
|
|
(i_command_ID = COMMAND_10_SEND_CID) or
|
|
(i_command_ID = COMMAND_13_SEND_STATUS) or
|
|
-------------------------------------------------------
|
|
-- Disabled to simplify the circuit
|
|
-------------------------------------------------------
|
|
--(i_command_ID = COMMAND_12_STOP_TRANSMISSION) or
|
|
--(i_command_ID = COMMAND_16_SET_BLOCK_LENGTH) or
|
|
--(i_command_ID = COMMAND_18_READ_MULTIPLE_BLOCKS) or
|
|
--(i_command_ID = COMMAND_25_WRITE_MULTIPLE_BLOCKS) or
|
|
-------------------------------------------------------
|
|
(i_command_ID = COMMAND_17_READ_BLOCK) or
|
|
(i_command_ID = COMMAND_24_WRITE_BLOCK) or
|
|
(i_command_ID = COMMAND_28_SET_WRITE_PROTECT) or
|
|
(i_command_ID = COMMAND_29_CLEAR_WRITE_PROTECT) or
|
|
(i_command_ID = COMMAND_32_ERASE_BLOCK_START) or
|
|
(i_command_ID = COMMAND_33_ERASE_BLOCK_END) or
|
|
(i_command_ID = COMMAND_38_ERASE_SELECTED_GROUPS) or
|
|
(i_command_ID = COMMAND_55_APP_CMD) or
|
|
(i_command_ID = COMMAND_56_GEN_CMD)
|
|
)
|
|
else '0';
|
|
|
|
response_type <= "001" when -- Wait for type 1 response when
|
|
(
|
|
(i_predefined_message = "0001") or
|
|
(i_predefined_message = "0111") or
|
|
(i_predefined_message = "1000") or
|
|
(i_predefined_message = "1001") or
|
|
((i_predefined_message = FIRST_NON_PREDEFINED_COMMAND) and
|
|
((i_command_ID = COMMAND_6_SWITCH_FUNCTION) or
|
|
(i_command_ID = COMMAND_7_SELECT_CARD) or
|
|
(i_command_ID = COMMAND_12_STOP_TRANSMISSION) or
|
|
(i_command_ID = COMMAND_13_SEND_STATUS) or
|
|
(i_command_ID = COMMAND_16_SET_BLOCK_LENGTH) or
|
|
(i_command_ID = COMMAND_17_READ_BLOCK) or
|
|
(i_command_ID = COMMAND_18_READ_MULTIPLE_BLOCKS) or
|
|
(i_command_ID = COMMAND_24_WRITE_BLOCK) or
|
|
(i_command_ID = COMMAND_25_WRITE_MULTIPLE_BLOCKS) or
|
|
(i_command_ID = COMMAND_27_PROGRAM_CSD) or
|
|
(i_command_ID = COMMAND_28_SET_WRITE_PROTECT) or
|
|
(i_command_ID = COMMAND_29_CLEAR_WRITE_PROTECT) or
|
|
(i_command_ID = COMMAND_30_SEND_PROTECTED_GROUPS) or
|
|
(i_command_ID = COMMAND_32_ERASE_BLOCK_START) or
|
|
(i_command_ID = COMMAND_33_ERASE_BLOCK_END) or
|
|
(i_command_ID = COMMAND_38_ERASE_SELECTED_GROUPS) or
|
|
(i_command_ID = COMMAND_42_LOCK_UNLOCK) or
|
|
(i_command_ID = COMMAND_55_APP_CMD) or
|
|
(i_command_ID = COMMAND_56_GEN_CMD) or
|
|
((last_command_sent_was_CMD55 = '1') and
|
|
((i_command_ID = ACOMMAND_6_SET_BUS_WIDTH) or
|
|
(i_command_ID = ACOMMAND_13_SD_STATUS) or
|
|
(i_command_ID = ACOMMAND_22_SEND_NUM_WR_BLOCKS) or
|
|
(i_command_ID = ACOMMAND_23_SET_BLK_ERASE_COUNT) or
|
|
(i_command_ID = ACOMMAND_42_SET_CLR_CARD_DETECT) or
|
|
(i_command_ID = ACOMMAND_51_SEND_SCR)))))
|
|
) else
|
|
"010" when -- Wait for type 2 response when
|
|
(
|
|
((i_predefined_message = FIRST_NON_PREDEFINED_COMMAND) and
|
|
((i_command_ID = COMMAND_2_ALL_SEND_CID) or
|
|
(i_command_ID = COMMAND_9_SEND_CSD) or
|
|
(i_command_ID = COMMAND_10_SEND_CID))) or
|
|
(i_predefined_message = "0011") or
|
|
(i_predefined_message = "0101")
|
|
) else
|
|
"011" when -- Wait for type 3 response when
|
|
(
|
|
((i_predefined_message = FIRST_NON_PREDEFINED_COMMAND) and (last_command_sent_was_CMD55 = '1') and (i_command_ID = ACOMMAND_41_SEND_OP_CONDITION)) or
|
|
(i_predefined_message = "0010")
|
|
) else
|
|
"110" when -- Wait for type 6 response when
|
|
(((i_predefined_message = FIRST_NON_PREDEFINED_COMMAND) and (i_command_ID = COMMAND_3_SEND_RCA)) or
|
|
(i_predefined_message = "0100"))
|
|
else "000"; -- Otherwise there is no response pending.
|
|
|
|
-- Define circuit outputs
|
|
o_message_done <= message_done;
|
|
o_response_type <= response_type_reg;
|
|
o_valid <= command_valid;
|
|
o_dataout <= bit_to_send;
|
|
o_returning_ocr <= returning_ocr_reg;
|
|
o_returning_cid <= returning_cid_reg;
|
|
o_returning_rca <= returning_rca_reg;
|
|
o_returning_csd <= returning_csd_reg;
|
|
o_returning_status <= returning_status_reg;
|
|
o_data_read <= '1' when (last_command_id = COMMAND_17_READ_BLOCK) else '0';
|
|
o_data_write <= '1' when (last_command_id = COMMAND_24_WRITE_BLOCK) else '0';
|
|
o_last_cmd_was_55 <= last_command_sent_was_CMD55;
|
|
o_wait_cmd_busy <= '1' when (
|
|
(last_command_id = COMMAND_7_SELECT_CARD) or
|
|
(last_command_id = COMMAND_12_STOP_TRANSMISSION) or
|
|
(last_command_id = COMMAND_28_SET_WRITE_PROTECT) or
|
|
(last_command_id = COMMAND_29_CLEAR_WRITE_PROTECT) or
|
|
(last_command_id = COMMAND_38_ERASE_SELECTED_GROUPS))
|
|
else '0';
|
|
end rtl; |