remove old SD interface files from project.

This commit is contained in:
marqs 2016-10-27 01:11:33 +03:00
parent 611c8763c2
commit 5d3e3bbe33
16 changed files with 0 additions and 5520 deletions

View File

@ -1,159 +0,0 @@
# (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.
# TCL File Generated by Component Editor 8.0
# Mon Dec 22 17:22:07 EST 2008
# DO NOT MODIFY
set aup_version 15.1
# +-----------------------------------
# |
# | Altera_UP_SD_Card_Avalon_Interface "Altera_UP_SD_Card_Avalon_Interface" v1.0
# | null 2008.12.22.17:22:07
# | A module that allows communication with an SD Card
# |
# | ./hdl/Altera_UP_SD_Card_Avalon_Interface.vhd syn
# | ./hdl/Altera_UP_SD_Card_48_bit_Command_Generator.vhd syn
# | ./hdl/Altera_UP_SD_Card_Buffer.vhd syn
# | ./hdl/Altera_UP_SD_Card_Clock.vhd syn
# | ./hdl/Altera_UP_SD_Card_Control_FSM.vhd syn
# | ./hdl/Altera_UP_SD_Card_Interface.vhd syn
# | ./hdl/Altera_UP_SD_Card_Memory_Block.qip syn
# | ./hdl/Altera_UP_SD_Card_Response_Receiver.vhd syn
# | ./hdl/Altera_UP_SD_CRC16_Generator.vhd syn
# | ./hdl/Altera_UP_SD_CRC7_Generator.vhd syn
# | ./hdl/Altera_UP_SD_Signal_Trigger.vhd syn
# |
# +-----------------------------------
# +-----------------------------------
# | module Altera_UP_SD_Card_Avalon_Interface
# |
set_module_property DESCRIPTION "A module that allows communication with an SD Card"
set_module_property NAME Altera_UP_SD_Card_Avalon_Interface_mod
set_module_property VERSION $aup_version
set_module_property GROUP "Memory"
set_module_property DISPLAY_NAME "SD Card Interface"
set_module_property DATASHEET_URL "[pwd]/doc/SD_Card_Interface_for_SoPC_Builder.pdf"
set_module_property LIBRARIES {ieee.std_logic_1164.all ieee.std_logic_arith.all ieee.std_logic_unsigned.all std.standard.all}
set_module_property TOP_LEVEL_HDL_FILE "hdl/Altera_UP_SD_Card_Avalon_Interface.vhd"
set_module_property TOP_LEVEL_HDL_MODULE Altera_UP_SD_Card_Avalon_Interface
set_module_property INSTANTIATE_IN_SYSTEM_MODULE true
set_module_property EDITABLE false
#set_module_property ANALYZE_HDL false
set_module_property SIMULATION_MODEL_IN_VERILOG false
set_module_property SIMULATION_MODEL_IN_VHDL false
set_module_property SIMULATION_MODEL_HAS_TULIPS false
set_module_property SIMULATION_MODEL_IS_OBFUSCATED false
# |
# +-----------------------------------
# +-----------------------------------
# | files
# |
add_file hdl/Altera_UP_SD_Card_Avalon_Interface.vhd {SYNTHESIS}
add_file hdl/Altera_UP_SD_Card_48_bit_Command_Generator.vhd {SYNTHESIS}
add_file hdl/Altera_UP_SD_Card_Buffer.vhd {SYNTHESIS}
add_file hdl/Altera_UP_SD_Card_Clock.vhd {SYNTHESIS}
add_file hdl/Altera_UP_SD_Card_Control_FSM.vhd {SYNTHESIS}
add_file hdl/Altera_UP_SD_Card_Interface.vhd {SYNTHESIS}
add_file hdl/Altera_UP_SD_Card_Response_Receiver.vhd {SYNTHESIS}
add_file hdl/Altera_UP_SD_CRC16_Generator.vhd {SYNTHESIS}
add_file hdl/Altera_UP_SD_CRC7_Generator.vhd {SYNTHESIS}
add_file hdl/Altera_UP_SD_Signal_Trigger.vhd {SYNTHESIS}
add_file hdl/Altera_UP_SD_Card_Memory_Block.vhd {SYNTHESIS}
# |
# +-----------------------------------
# +-----------------------------------
# | parameters
# |
# |
# +-----------------------------------
# +-----------------------------------
# | connection point avalon_sdcard_slave
# |
add_interface avalon_sdcard_slave avalon end
set_interface_property avalon_sdcard_slave holdTime 0
set_interface_property avalon_sdcard_slave linewrapBursts false
set_interface_property avalon_sdcard_slave minimumUninterruptedRunLength 1
set_interface_property avalon_sdcard_slave bridgesToMaster ""
set_interface_property avalon_sdcard_slave isMemoryDevice false
set_interface_property avalon_sdcard_slave burstOnBurstBoundariesOnly false
set_interface_property avalon_sdcard_slave addressSpan 1024
set_interface_property avalon_sdcard_slave timingUnits Cycles
set_interface_property avalon_sdcard_slave setupTime 0
set_interface_property avalon_sdcard_slave writeWaitTime 0
set_interface_property avalon_sdcard_slave isNonVolatileStorage false
set_interface_property avalon_sdcard_slave addressAlignment DYNAMIC
set_interface_property avalon_sdcard_slave maximumPendingReadTransactions 0
set_interface_property avalon_sdcard_slave readWaitTime 1
set_interface_property avalon_sdcard_slave readLatency 0
set_interface_property avalon_sdcard_slave printableDevice false
set_interface_property avalon_sdcard_slave associatedClock clk
set_interface_property avalon_sdcard_slave associatedReset reset
add_interface_port avalon_sdcard_slave i_avalon_chip_select chipselect Input 1
add_interface_port avalon_sdcard_slave i_avalon_address address Input 8
add_interface_port avalon_sdcard_slave i_avalon_read read Input 1
add_interface_port avalon_sdcard_slave i_avalon_write write Input 1
add_interface_port avalon_sdcard_slave i_avalon_byteenable byteenable Input 4
add_interface_port avalon_sdcard_slave i_avalon_writedata writedata Input 32
add_interface_port avalon_sdcard_slave o_avalon_readdata readdata Output 32
add_interface_port avalon_sdcard_slave o_avalon_waitrequest waitrequest Output 1
# |
# +-----------------------------------
# +-----------------------------------
# | connection point clk
# |
add_interface clk clock end
set_interface_property clk enabled true
add_interface_port clk i_clock clk Input 1
# |
# +-----------------------------------
# +-----------------------------------
# | connection point reset
# |
add_interface reset reset end
set_interface_property reset associatedClock clk
set_interface_property reset enabled true
set_interface_property reset synchronousEdges DEASSERT
add_interface_port reset i_reset_n reset_n Input 1
# |
# +-----------------------------------
# +-----------------------------------
# | connection point conduit_end
# |
add_interface conduit_end conduit end
add_interface_port conduit_end b_SD_cmd export Bidir 1
add_interface_port conduit_end b_SD_dat export Bidir 1
add_interface_port conduit_end b_SD_dat3 export Bidir 1
add_interface_port conduit_end o_SD_clock export Output 1
# |
# +-----------------------------------
## Add documentation links for user guide and/or release notes
add_documentation_link "User Guide" file:///ip/altera/university_program/memory/altera_up_sd_card_avalon_interface/doc/SD_Card_Interface_for_SoPC_Builder.pdf
add_documentation_link "Release Notes" https://documentation.altera.com/#/link/hco1421698042087/hco1421698013408

View File

@ -1,56 +0,0 @@
# (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.
# TCL File Generated by Altera University Program
# DO NOT MODIFY
set aup_version 15.1
# Create a new driver - this name must be different than the
# hardware component name
create_driver Altera_UP_SD_Card_Avalon_Interface_mod_driver
# Associate it with some hardware
set_sw_property hw_class_name Altera_UP_SD_Card_Avalon_Interface_mod
# The version of this driver
set_sw_property version $aup_version
# This driver is proclaimed to be compatible with 'component'
# as old as version "1.0". The component hardware version is set in the
# _hw.tcl file - If the hardware component version number is not equal
# or greater than the min_compatable_hw_version number, the driver
# source files will not be copied over to the BSP driver directory
set_sw_property min_compatible_hw_version 15.1
# Initialize the driver in alt_sys_init()
set_sw_property auto_initialize true
# Location in generated BSP that sources will be copied into
set_sw_property bsp_subdirectory drivers
#
# Source file listings...
#
# C/C++ source files
add_sw_property c_source HAL/src/Altera_UP_SD_Card_Avalon_Interface_mod.c
# Include files
add_sw_property include_source HAL/inc/Altera_UP_SD_Card_Avalon_Interface_mod.h
# This driver supports HAL type
add_sw_property supported_bsp_type HAL
# End of file

View File

@ -1,166 +0,0 @@
#ifndef __ALTERA_UP_SD_CARD_AVALON_INTERFACE_H__
#define __ALTERA_UP_SD_CARD_AVALON_INTERFACE_H__
#include <stddef.h>
#include <alt_types.h>
#include <sys/alt_dev.h>
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
#define SD_RAW_IFACE
/*
* Device structure definition. Each instance of the driver uses one
* of these structures to hold its associated state.
*/
typedef struct alt_up_sd_card_dev {
/// @brief character mode device structure
/// @sa Developing Device Drivers for the HAL in Nios II Software Developer's Handbook
alt_dev dev;
/// @brief the base address of the device
unsigned int base;
} alt_up_sd_card_dev;
#ifndef bool
typedef enum e_bool { false = 0, true = 1 } bool;
#endif
//////////////////////////////////////////////////////////////////////////
// HAL system functions
alt_up_sd_card_dev* alt_up_sd_card_open_dev(const char *name);
/* Open an SD Card Interface if it is connected to the system. */
bool alt_up_sd_card_is_Present(void);
/* Check if there is an SD Card insterted into the SD Card socket.
*/
#ifndef SD_RAW_IFACE
bool alt_up_sd_card_is_FAT16(void);
/* This function reads the SD card data in an effort to determine if the card is formated as a FAT16
* volume. Please note that FAT12 has a similar format, but will not be supported by this driver.
*/
short int alt_up_sd_card_fopen(char *name, bool create);
/* This function reads the SD card data in an effort to determine if the card is formated as a FAT16
* volume. Please note that FAT12 has a similar format, but will not be supported by this driver.
*
* Inputs:
* name - a file name including a directory, relative to the root directory
* create - a flag set to true to create a file if it does not already exist
* Output:
* An index to the file record assigned to the specified file. -1 is returned if the file could not be opened.
*/
short int alt_up_sd_card_find_first(char *directory_to_search_through, char *file_name);
/* This function sets up a search algorithm to go through a given directory looking for files.
* If the search directory is valid, then the function searches for the first file it finds.
* Inputs:
* directory_to_search_through - name of the directory to search through
* file_name - an array to store a name of the file found. Must be 13 bytes long (12 bytes for file name and 1 byte of NULL termination).
* Outputs:
* 0 - success
* 1 - invalid directory
* 2 - No card or incorrect card format.
*
* To specify a directory give the name in a format consistent with the following regular expression:
* [{[valid_chars]+}/]*.
*
* In other words, give a path name starting at the root directory, where each directory name is followed by a '/'.
* Then, append a '.' to the directory name. Examples:
* "." - look through the root directory
* "first/." - look through a directory named "first" that is located in the root directory.
* "first/sub/." - look through a directory named "sub", that is located within the subdirectory named "first". "first" is located in the root directory.
* Invalid examples include:
* "/.", "/////." - this is not the root directory.
* "/first/." - the first character may not be a '/'.
*/
short int alt_up_sd_card_find_next(char *file_name);
/* This function searches for the next file in a given directory, as specified by the find_first function.
* Inputs:
* file_name - an array to store a name of the file found. Must be 13 bytes long (12 bytes for file name and 1 byte of NULL termination).
* Outputs:
* -1 - end of directory.
* 0 - success
* 2 - No card or incorrect card format.
* 4 - find_first has not been called successfully.
*/
void alt_up_sd_card_set_attributes(short int file_handle, short int attributes);
/* Set file attributes as needed.
*/
short int alt_up_sd_card_get_attributes(short int file_handle);
/* Return file attributes, or -1 if the file_handle is invalid.
*/
short int alt_up_sd_card_read(short int file_handle);
/* Read a single character from the given file. Return -1 if at the end of a file. Any other negative number
* means that the file could not be read. A number between 0 and 255 is an ASCII character read from the SD Card. */
bool alt_up_sd_card_write(short int file_handle, char byte_of_data);
/* Write a single character to a given file. Return true if successful, and false otherwise. */
bool alt_up_sd_card_fclose(short int file_handle);
// This function closes an opened file and saves data to SD Card if necessary.
#else
bool Write_Sector_Data(int sector_index, int partition_offset);
bool Save_Modified_Sector();
bool Read_Sector_Data(int sector_index, int partition_offset);
#endif //SD_RAW_IFACE
//////////////////////////////////////////////////////////////////////////
// file-like operation functions
//////////////////////////////////////////////////////////////////////////
// direct operation functions
/*
* Macros used by alt_sys_init
*/
#define ALTERA_UP_SD_CARD_AVALON_INTERFACE_MOD_INSTANCE(name, device) \
static alt_up_sd_card_dev device = \
{ \
{ \
ALT_LLIST_ENTRY, \
name##_NAME, \
NULL , /* open */ \
NULL , /* close */ \
NULL, /* read */ \
NULL, /* write */ \
NULL , /* lseek */ \
NULL , /* fstat */ \
NULL , /* ioctl */ \
}, \
name##_BASE, \
}
#define ALTERA_UP_SD_CARD_AVALON_INTERFACE_MOD_INIT(name, device) \
{ \
alt_dev_reg(&device.dev); \
}
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __ALTERA_UP_SD_CARD_AVALON_INTERFACE_H__ */

View File

@ -1,79 +0,0 @@
-- (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 generates the necessary 16-CRC for Command and Response
-- Implementation: serial input/parallel output
-- When input stream ends, the crcout output is the CRC checksum for them
--
-- NOTES/REVISIONS:
----------------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity Altera_UP_SD_CRC16_Generator is
port
(
i_clock : in std_logic;
i_enable : in std_logic;
i_reset_n : in std_logic;
i_sync_reset : in std_logic;
i_shift : in std_logic;
i_datain : in std_logic;
o_dataout : out std_logic;
o_crcout : out std_logic_vector(15 downto 0)
);
end entity;
architecture rtl of Altera_UP_SD_CRC16_Generator is
-- Local wires
-- REGISTERED
signal shift_register : std_logic_vector(15 downto 0);
begin
process (i_clock, i_reset_n)
begin
if (i_reset_n = '0') then
shift_register <= (OTHERS => '0');
else
if (rising_edge(i_clock)) then
if (i_sync_reset = '1') then
shift_register <= (OTHERS => '0');
elsif (i_enable = '1') then
if (i_shift = '0') then
shift_register(0) <= i_datain XOR shift_register(15);
shift_register(4 downto 1) <= shift_register(3 downto 0);
shift_register(5) <= shift_register(4) XOR i_datain XOR shift_register(15);
shift_register(11 downto 6) <= shift_register(10 downto 5);
shift_register(12) <= shift_register(11) XOR i_datain XOR shift_register(15);
shift_register(15 downto 13) <= shift_register(14 downto 12);
else -- shift CRC out (no more calculation now)
shift_register(15 downto 1) <= shift_register(14 downto 0);
shift_register(0) <= '0';
end if;
end if;
end if;
end if;
end process;
o_dataout <= shift_register(15);
o_crcout <= shift_register;
end rtl;

View File

@ -1,76 +0,0 @@
-- (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 generates the necessary 7-CRC for Command and Response
-- Implementation: serial input/parallel output
--
-- When input stream ends, the crcout output is the CRC checksum for the input stream.
--
-- NOTES/REVISIONS:
---------------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity Altera_UP_SD_CRC7_Generator is
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 entity;
architecture rtl of Altera_UP_SD_CRC7_Generator is
-- Local wires
-- REGISTERED
signal shift_register : std_logic_vector(6 downto 0);
begin
process (i_clock, i_reset_n)
begin
if (i_reset_n = '0') then
shift_register <= (OTHERS => '0');
else
if (rising_edge(i_clock)) then
if (i_enable = '1') then
if (i_shift = '0') then
shift_register(0) <= i_datain XOR shift_register(6);
shift_register(1) <= shift_register(0);
shift_register(2) <= shift_register(1);
shift_register(3) <= shift_register(2) XOR i_datain XOR shift_register(6);
shift_register(4) <= shift_register(3);
shift_register(5) <= shift_register(4);
shift_register(6) <= shift_register(5);
else -- shift CRC out (no more calculation now)
shift_register(0) <= '0';
shift_register(6 downto 1) <= shift_register(5 downto 0);
end if;
end if;
end if;
end if;
end process;
o_dataout <= shift_register(6);
o_crcout <= shift_register;
end rtl;

View File

@ -1,570 +0,0 @@
-- (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;

View File

@ -1,518 +0,0 @@
-- (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 is an FSM that allows access to the SD Card IP core via the Avalon Interconnect.
--
-- This module takes a range of addresses on the Avalon Interconnect. Specifically:
-- - 0x00000000 to 0x000001ff
-- word addressable buffer space. The data to be written to the SD card as well
-- as data read from the SD card can be accessed here.
--
-- - 0x00000200 to 0x0000020f
-- 128-bit containing the Card Identification Number. The meaning of each bit is described in the
-- SD Card Physical Layer Specification Document.
--
-- - 0x00000210 to 0x0000021f
-- 128-bit register containing Card Specific Data. The meaning of each bit is described in the
-- SD Card Physical Layer Specification Document.
--
-- - 0x00000220 to 0x00000223
-- 32-bit register containing Operating Conditions Register. The meaning of each bit is described
-- in the SD Card Physical Layer Specification Document.
--
-- - 0x00000224 to 0x00000227
-- 32-bit register containing the Status Register. The meaning of each bit is described
-- in the SD Card Physical Layer Specification Document. However, if the card is not connected or the
-- status register could not be read from the SD card, this register will contain invalid data. In such
-- a case, wait for a card to be connected by checking the Auxiliary Status Register (UP Core Specific), and
-- a command 13 (SEND_STATUS) to update the contents of this register when possible. If a card is connected then
-- the Auxiliary Status Register can be polled until such a time that Status Register is valid, as the SD Card
-- interface circuit updates the status register approximately every 0.1 of a second, and after every command
-- is executed.
--
-- - 0x00000228 to 0x000000229
-- 16-bit register containing the Relative Card Address. This address uniquely identifies a card
-- connected to the SD Card slot.
--
-- - 0x0000022C to 0x00000022F
-- 32-bit register used to set the argument for a command to be sent to the SD Card.
--
-- - 0x00000230 to 0x000000231
-- 16-bit register used to send a command to an SD card. Once written, the interface will issue the
-- specified command. The meaning of each bit in this register is as follows:
-- - 0-5 - command index. This is a command index as per SD Card Physical Layer specification document.
-- - 6 - use most recent RCA. If this bit is set, the command argument will be replaced with the contents of
-- the Relative Card Address register, followed by 16 0s. For commands that require RCA to be sent as
-- an argument, this bit should be set and users will not need to specify RCA themselves.
-- - 7-15 - currently unused bits. They will be ignored.
-- NOTE: If a specified command is determined to be invalid, or the card is not connected to the SD Card socket,
-- then the SD Card interface circuit will not issue the command.
--
-- - 0x00000234 to 0x00000235
-- 16-bit register with Auxiliary Status Register. This is the Altera UP SD Card Interface status. The meaning of
-- the bits is as follows:
-- - 0 - last command valid - Set to '1' if the most recently user issued command was valid.
-- - 1 - card connected - Set to '1' if at present an SD card
-- - 2 - execution in progress - Set to '1' if the command recently issued is currently being executed. If true,
-- then the current state of SD Card registers should be ignored.
-- - 3 - status register valid - Set to '1' if the status register is valid.
-- - 4 - command timed out - Set to '1' if the last command timed out.
-- - 5 - crc failed - Set to '1' if the last command failed a CRC check.
-- - 6-15 - unused.
--
-- - 0x00000238 to 0x0000023B
-- 32-bit register containing the 32-bit R1 response message. Use it to test validity of the response. This register
-- will not store the response to SEND_STATUS command. Insteand, read the SD_status register at location 0x00000224.
--
-- Date: December 8, 2008
-- NOTES/REVISIONS:
-- December 17, 2008 - added R1 response register to the core. It is now available at 0x00000238.
----------------------------------------------------------------------------------------------------------------
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_Avalon_Interface is
generic (
ADDRESS_BUFFER : std_logic_vector(7 downto 0) := "00000000";
ADDRESS_CID : std_logic_vector(7 downto 0) := "10000000";
ADDRESS_CSD : std_logic_vector(7 downto 0) := "10000100";
ADDRESS_OCR : std_logic_vector(7 downto 0) := "10001000";
ADDRESS_SR : std_logic_vector(7 downto 0) := "10001001";
ADDRESS_RCA : std_logic_vector(7 downto 0) := "10001010";
ADDRESS_ARGUMENT : std_logic_vector(7 downto 0) := "10001011";
ADDRESS_COMMAND : std_logic_vector(7 downto 0) := "10001100";
ADDRESS_ASR : std_logic_vector(7 downto 0) := "10001101";
ADDRESS_R1 : std_logic_vector(7 downto 0) := "10001110"
);
port
(
-- Clock and Reset signals
i_clock : in STD_LOGIC;
i_reset_n : in STD_LOGIC; -- Asynchronous reset
-- Avalon Interconnect Signals
i_avalon_address : in STD_LOGIC_VECTOR(7 downto 0);
i_avalon_chip_select : in STD_LOGIC;
i_avalon_read : in STD_LOGIC;
i_avalon_write : in STD_LOGIC;
i_avalon_byteenable : in STD_LOGIC_VECTOR(3 downto 0);
i_avalon_writedata : in STD_LOGIC_VECTOR(31 downto 0);
o_avalon_readdata : out STD_LOGIC_VECTOR(31 downto 0);
o_avalon_waitrequest : out STD_LOGIC;
-- SD Card interface ports
b_SD_cmd : inout STD_LOGIC;
b_SD_dat : inout STD_LOGIC;
b_SD_dat3 : inout STD_LOGIC;
o_SD_clock : out STD_LOGIC
);
end entity;
architecture rtl of Altera_UP_SD_Card_Avalon_Interface is
component Altera_UP_SD_Card_Interface is
port
(
i_clock : in std_logic;
i_reset_n : in std_logic;
-- Command interface
b_SD_cmd : inout std_logic;
b_SD_dat : inout std_logic;
b_SD_dat3 : inout std_logic;
i_command_ID : in std_logic_vector(5 downto 0);
i_argument : in std_logic_vector(31 downto 0);
i_user_command_ready : in std_logic;
o_SD_clock : out std_logic;
o_card_connected : out std_logic;
o_command_completed : out std_logic;
o_command_valid : out std_logic;
o_command_timed_out : out std_logic;
o_command_crc_failed : out std_logic;
-- Buffer access
i_buffer_enable : in std_logic;
i_buffer_address : in std_logic_vector(7 downto 0);
i_buffer_write : in std_logic;
i_buffer_data_in : in std_logic_vector(15 downto 0);
o_buffer_data_out : out std_logic_vector(15 downto 0);
-- Show SD Card registers as outputs
o_SD_REG_card_identification_number : out std_logic_vector(127 downto 0);
o_SD_REG_relative_card_address : out std_logic_vector(15 downto 0);
o_SD_REG_operating_conditions_register : out std_logic_vector(31 downto 0);
o_SD_REG_card_specific_data : out std_logic_vector(127 downto 0);
o_SD_REG_status_register : out std_logic_vector(31 downto 0);
o_SD_REG_response_R1 : out std_logic_vector(31 downto 0);
o_SD_REG_status_register_valid : out std_logic
);
end component;
-- Build an enumerated type for the state machine. On reset always reset the DE2 and read the state
-- of the switches.
type buffer_state_type is ( s_RESET, s_WAIT_REQUEST, s_READ_FIRST_WORD, s_READ_SECOND_WORD, s_RECEIVE_FIRST_WORD,
s_RECEIVE_SECOND_WORD, s_WR_READ_FIRST_WORD, s_WR_READ_FIRST_WORD_DELAY, s_WRITE_FIRST_BYTE, s_WRITE_FIRST_WORD,
s_WR_READ_SECOND_WORD, s_WR_READ_SECOND_WORD_DELAY, s_WRITE_SECOND_BYTE, s_WRITE_SECOND_WORD, s_WAIT_RELEASE);
type command_state_type is (s_RESET_CMD, s_WAIT_COMMAND, s_WAIT_RESPONSE, s_UPDATE_AUX_SR);
-- Register to hold the current state
signal current_state : buffer_state_type;
signal next_state : buffer_state_type;
signal current_cmd_state : command_state_type;
signal next_cmd_state : command_state_type;
-------------------
-- Local signals
-------------------
-- REGISTERED
signal auxiliary_status_reg : std_logic_vector(5 downto 0);
signal buffer_data_out_reg : std_logic_vector(31 downto 0);
signal buffer_data_in_reg : std_logic_vector(31 downto 0);
signal buffer_data_out : std_logic_vector(15 downto 0);
signal command_ID_reg : std_logic_vector( 5 downto 0);
signal argument_reg : std_logic_vector(31 downto 0);
signal avalon_address : std_logic_vector(7 downto 0);
signal avalon_byteenable : std_logic_vector(3 downto 0);
-- UNREGISTERED
signal buffer_address : std_logic_vector(7 downto 0);
signal buffer_data_in : std_logic_vector(15 downto 0);
signal SD_REG_card_identification_number : std_logic_vector(127 downto 0);
signal SD_REG_relative_card_address : std_logic_vector(15 downto 0);
signal SD_REG_operating_conditions_register : std_logic_vector(31 downto 0);
signal SD_REG_card_specific_data : std_logic_vector(127 downto 0);
signal SD_REG_status_register : std_logic_vector(31 downto 0);
signal SD_REG_response_R1 : std_logic_vector(31 downto 0);
signal command_ready, send_command_ready,
command_valid, command_completed, card_connected : std_logic;
signal status_reg_valid, argument_write : std_logic;
signal read_buffer_request, write_buffer_request, buffer_enable, buffer_write : std_logic;
signal command_timed_out, command_crc_failed : std_logic;
begin
-- Define state transitions for buffer interface.
state_transitions_buffer: process (current_state, read_buffer_request, write_buffer_request, i_avalon_byteenable, avalon_byteenable)
begin
case current_state is
when s_RESET =>
-- Reset local registers.
next_state <= s_WAIT_REQUEST;
when s_WAIT_REQUEST =>
-- Wait for a user command.
if (read_buffer_request = '1') then
next_state <= s_READ_FIRST_WORD;
elsif (write_buffer_request = '1') then
if ((i_avalon_byteenable(1) = '1') and (i_avalon_byteenable(0) = '1')) then
next_state <= s_WRITE_FIRST_WORD;
elsif ((i_avalon_byteenable(3) = '1') and (i_avalon_byteenable(2) = '1')) then
next_state <= s_WRITE_SECOND_WORD;
elsif ((i_avalon_byteenable(1) = '1') or (i_avalon_byteenable(0) = '1')) then
next_state <= s_WR_READ_FIRST_WORD;
elsif ((i_avalon_byteenable(3) = '1') or (i_avalon_byteenable(2) = '1')) then
next_state <= s_WR_READ_SECOND_WORD;
else
next_state <= s_WAIT_REQUEST;
end if;
else
next_state <= s_WAIT_REQUEST;
end if;
when s_READ_FIRST_WORD =>
-- Read first 16-bit word from the buffer
next_state <= s_READ_SECOND_WORD;
when s_READ_SECOND_WORD =>
-- Read second 16-bit word from the buffer
next_state <= s_RECEIVE_FIRST_WORD;
when s_RECEIVE_FIRST_WORD =>
-- Store first word read
next_state <= s_RECEIVE_SECOND_WORD;
when s_RECEIVE_SECOND_WORD =>
-- Store second word read
next_state <= s_WAIT_RELEASE;
-- The following states control writing to the buffer. To write a single byte it is necessary to read a
-- word and then write it back, changing only on of its bytes.
when s_WR_READ_FIRST_WORD =>
-- Read first 16-bit word from the buffer
next_state <= s_WR_READ_FIRST_WORD_DELAY;
when s_WR_READ_FIRST_WORD_DELAY =>
-- Wait a cycle
next_state <= s_WRITE_FIRST_BYTE;
when s_WRITE_FIRST_BYTE =>
-- Write one of the bytes in the given word into the memory.
if ((avalon_byteenable(3) = '1') and (avalon_byteenable(2) = '1')) then
next_state <= s_WRITE_SECOND_WORD;
elsif ((avalon_byteenable(3) = '1') or (avalon_byteenable(2) = '1')) then
next_state <= s_WR_READ_SECOND_WORD;
else
next_state <= s_WAIT_RELEASE;
end if;
when s_WR_READ_SECOND_WORD =>
-- Read second 16-bit word from the buffer
next_state <= s_WR_READ_SECOND_WORD_DELAY;
when s_WR_READ_SECOND_WORD_DELAY =>
-- Wait a cycle
next_state <= s_WRITE_SECOND_BYTE;
when s_WRITE_SECOND_BYTE =>
-- Write one of the bytes in the given word into the memory.
next_state <= s_WAIT_RELEASE;
-- Full word writing can be done without reading the word in the first place.
when s_WRITE_FIRST_WORD =>
-- Write the first word into memory
if ((avalon_byteenable(3) = '1') and (avalon_byteenable(2) = '1')) then
next_state <= s_WRITE_SECOND_WORD;
elsif ((avalon_byteenable(3) = '1') or (avalon_byteenable(2) = '1')) then
next_state <= s_WR_READ_SECOND_WORD;
else
next_state <= s_WAIT_RELEASE;
end if;
when s_WRITE_SECOND_WORD =>
-- Write the second word into memory
next_state <= s_WAIT_RELEASE;
when s_WAIT_RELEASE =>
-- if ((read_buffer_request = '1') or (write_buffer_request = '1')) then
-- next_state <= s_WAIT_RELEASE;
-- else
next_state <= s_WAIT_REQUEST;
-- end if;
when others =>
-- Make sure to start in the reset state if the circuit powers up in an odd state.
next_state <= s_RESET;
end case;
end process;
-- State Registers
buffer_state_regs: process(i_clock, i_reset_n)
begin
if (i_reset_n = '0') then
current_state <= s_RESET;
elsif(rising_edge(i_clock)) then
current_state <= next_state;
end if;
end process;
helper_regs: process(i_clock, i_reset_n)
begin
if (i_reset_n = '0') then
avalon_address <= (OTHERS => '0');
buffer_data_out_reg <= (OTHERS => '0');
buffer_data_in_reg <= (OTHERS => '0');
avalon_byteenable <= (OTHERS => '0');
elsif(rising_edge(i_clock)) then
if (current_state = s_WAIT_REQUEST) then
avalon_address <= i_avalon_address;
buffer_data_in_reg <= i_avalon_writedata;
avalon_byteenable <= i_avalon_byteenable;
end if;
if (current_state = s_RECEIVE_FIRST_WORD) then
buffer_data_out_reg(15 downto 0) <= buffer_data_out;
end if;
if (current_state = s_RECEIVE_SECOND_WORD) then
buffer_data_out_reg(31 downto 16) <= buffer_data_out;
end if;
end if;
end process;
-- FSM outputs
o_avalon_waitrequest <= (read_buffer_request or write_buffer_request) when (not (current_state = s_WAIT_RELEASE)) else '0';
buffer_address(7 downto 1) <= avalon_address(6 downto 0);
buffer_address(0) <= '1' when ( (current_state = s_READ_SECOND_WORD) or (current_state = s_WRITE_SECOND_WORD) or
(current_state = s_WR_READ_SECOND_WORD) or (current_state = s_WRITE_SECOND_BYTE)) else
'0';
buffer_enable <= '1' when ( (current_state = s_READ_FIRST_WORD) or (current_state = s_WR_READ_FIRST_WORD) or
(current_state = s_READ_SECOND_WORD) or (current_state = s_WR_READ_SECOND_WORD) or
(current_state = s_WRITE_FIRST_WORD) or (current_state = s_WRITE_FIRST_BYTE) or
(current_state = s_WRITE_SECOND_WORD) or (current_state = s_WRITE_SECOND_BYTE)) else
'0';
buffer_write <= '1' when ( (current_state = s_WRITE_FIRST_WORD) or (current_state = s_WRITE_FIRST_BYTE) or
(current_state = s_WRITE_SECOND_WORD) or (current_state = s_WRITE_SECOND_BYTE)) else
'0';
buffer_data_in <= (buffer_data_out(15 downto 8) & buffer_data_in_reg(7 downto 0)) when ((current_state = s_WRITE_FIRST_BYTE) and (avalon_byteenable(1 downto 0) = "01")) else
(buffer_data_in_reg(15 downto 8) & buffer_data_out(7 downto 0)) when ((current_state = s_WRITE_FIRST_BYTE) and (avalon_byteenable(1 downto 0) = "10")) else
(buffer_data_out(15 downto 8) & buffer_data_in_reg(23 downto 16)) when ((current_state = s_WRITE_SECOND_BYTE) and (avalon_byteenable(3 downto 2) = "01")) else
(buffer_data_in_reg(31 downto 24) & buffer_data_out(7 downto 0)) when ((current_state = s_WRITE_SECOND_BYTE) and (avalon_byteenable(3 downto 2) = "10")) else
buffer_data_in_reg(15 downto 0) when (current_state = s_WRITE_FIRST_WORD) else
buffer_data_in_reg(31 downto 16);
-- Glue Logic
read_buffer_request <= (not i_avalon_address(7)) and (i_avalon_chip_select) and (i_avalon_read);
write_buffer_request <= (not i_avalon_address(7)) and (i_avalon_chip_select) and (i_avalon_write);
-- Define state transitions for command interface.
state_transitions_cmd: process (current_cmd_state, command_completed, command_valid, command_ready)
begin
case current_cmd_state is
when s_RESET_CMD =>
-- Reset local registers.
next_cmd_state <= s_WAIT_COMMAND;
when s_WAIT_COMMAND =>
-- Wait for a user command.
if (command_ready = '1') then
next_cmd_state <= s_WAIT_RESPONSE;
else
next_cmd_state <= s_WAIT_COMMAND;
end if;
when s_WAIT_RESPONSE =>
-- Generate a predefined command to the SD card. This is the identification process for the SD card.
if ((command_completed = '1') or (command_valid = '0')) then
next_cmd_state <= s_UPDATE_AUX_SR;
else
next_cmd_state <= s_WAIT_RESPONSE;
end if;
when s_UPDATE_AUX_SR =>
-- Update the Auxiliary status register.
if (command_ready = '1') then
next_cmd_state <= s_UPDATE_AUX_SR;
else
next_cmd_state <= s_WAIT_COMMAND;
end if;
when others =>
-- Make sure to start in the reset state if the circuit powers up in an odd state.
next_cmd_state <= s_RESET_CMD;
end case;
end process;
-- State registers
cmd_state_regs: process(i_clock, i_reset_n)
begin
if (i_reset_n = '0') then
current_cmd_state <= s_RESET_CMD;
elsif(rising_edge(i_clock)) then
current_cmd_state <= next_cmd_state;
end if;
end process;
-- FSM outputs
send_command_ready <= '1' when ((current_cmd_state = s_WAIT_RESPONSE) or (current_cmd_state = s_UPDATE_AUX_SR)) else '0';
-- Glue logic
command_ready <= '1' when ( (i_avalon_chip_select = '1') and (i_avalon_write = '1') and
(i_avalon_address = ADDRESS_COMMAND)) else '0';
argument_write <= '1' when ((i_avalon_chip_select = '1') and (i_avalon_write = '1') and
(i_avalon_address = ADDRESS_ARGUMENT)) else '0';
-- Local Registers
local_regs: process(i_clock, i_reset_n, current_cmd_state, card_connected, command_valid, i_avalon_writedata, command_completed, command_ready)
begin
if (i_reset_n = '0') then
auxiliary_status_reg <= "000000";
command_ID_reg <= (OTHERS => '0');
elsif(rising_edge(i_clock)) then
-- AUX Status Register
if ((current_cmd_state = s_WAIT_RESPONSE) or (current_cmd_state = s_UPDATE_AUX_SR)) then
auxiliary_status_reg(2) <= not command_completed;
auxiliary_status_reg(4) <= command_timed_out;
auxiliary_status_reg(5) <= command_crc_failed;
end if;
auxiliary_status_reg(0) <= command_valid;
auxiliary_status_reg(1) <= card_connected;
auxiliary_status_reg(3) <= status_reg_valid;
-- Command
if (command_ready = '1') then
command_ID_reg <= i_avalon_writedata(5 downto 0);
end if;
end if;
end process;
argument_regs_processing: process(i_clock, i_reset_n, current_cmd_state, i_avalon_writedata, command_ready)
begin
if (i_reset_n = '0') then
argument_reg <= (OTHERS => '0');
elsif(rising_edge(i_clock)) then
-- Argument register
if ((command_ready = '1') and ( i_avalon_writedata(6) = '1')) then
argument_reg <= SD_REG_relative_card_address & "0000000000000000";
elsif (argument_write = '1') then
argument_reg <= i_avalon_writedata;
end if;
end if;
end process;
o_avalon_readdata <= buffer_data_out_reg when (not (current_state = s_WAIT_REQUEST)) else
SD_REG_card_identification_number(31 downto 0) when (i_avalon_address = ADDRESS_CID) else
SD_REG_card_identification_number(63 downto 32) when (i_avalon_address = ADDRESS_CID(7 downto 2) & "01") else
SD_REG_card_identification_number(95 downto 64) when (i_avalon_address = ADDRESS_CID(7 downto 2) & "10") else
SD_REG_card_identification_number(127 downto 96) when (i_avalon_address = ADDRESS_CID(7 downto 2) & "11") else
SD_REG_card_specific_data(31 downto 0) when (i_avalon_address = ADDRESS_CSD) else
SD_REG_card_specific_data(63 downto 32) when (i_avalon_address = ADDRESS_CSD(7 downto 2) & "01") else
SD_REG_card_specific_data(95 downto 64) when (i_avalon_address = ADDRESS_CSD(7 downto 2) & "10") else
SD_REG_card_specific_data(127 downto 96) when (i_avalon_address = ADDRESS_CSD(7 downto 2) & "11") else
SD_REG_operating_conditions_register when (i_avalon_address = ADDRESS_OCR) else
SD_REG_status_register when (i_avalon_address = ADDRESS_SR) else
("0000000000000000" & SD_REG_relative_card_address)when (i_avalon_address = ADDRESS_RCA) else
argument_reg when (i_avalon_address = ADDRESS_ARGUMENT) else
("00000000000000000000000000" & command_ID_reg) when (i_avalon_address = ADDRESS_COMMAND) else
SD_REG_response_R1 when (i_avalon_address = ADDRESS_R1) else
("00000000000000000000000000" & auxiliary_status_reg);
-- Instantiated Components
SD_Card_Port: Altera_UP_SD_Card_Interface
port map
(
i_clock => i_clock,
i_reset_n => i_reset_n,
-- Command interface
b_SD_cmd => b_SD_cmd,
b_SD_dat => b_SD_dat,
b_SD_dat3 => b_SD_dat3,
i_command_ID => command_ID_reg,
i_argument => argument_reg,
i_user_command_ready => send_command_ready,
o_SD_clock => o_SD_clock,
o_card_connected => card_connected,
o_command_completed => command_completed,
o_command_valid => command_valid,
o_command_timed_out => command_timed_out,
o_command_crc_failed => command_crc_failed,
-- Buffer access
i_buffer_enable => buffer_enable,
i_buffer_address => buffer_address,
i_buffer_write => buffer_write,
i_buffer_data_in => buffer_data_in,
o_buffer_data_out => buffer_data_out,
-- Show SD Card registers as outputs
o_SD_REG_card_identification_number => SD_REG_card_identification_number,
o_SD_REG_relative_card_address => SD_REG_relative_card_address,
o_SD_REG_operating_conditions_register => SD_REG_operating_conditions_register,
o_SD_REG_card_specific_data => SD_REG_card_specific_data,
o_SD_REG_status_register => SD_REG_status_register,
o_SD_REG_response_R1 => SD_REG_response_R1,
o_SD_REG_status_register_valid => status_reg_valid
);
end rtl;

View File

@ -1,382 +0,0 @@
-- (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 is a dual port memory block. It has a 16-bit port and a 1-bit port.
-- The 1-bit port is used to either send or receive data, while the 16-bit port is used
-- by Avalon interconnet to store and retrieve data.
--
-- 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_Buffer is
generic (
TIMEOUT : std_logic_vector(15 downto 0) := "1111111111111111";
BUSY_WAIT : std_logic_vector(15 downto 0) := "0000001111110000"
);
port
(
i_clock : in std_logic;
i_reset_n : in std_logic;
-- 1 bit port to transmit and receive data on the data line.
i_begin : in std_logic;
i_sd_clock_pulse_trigger : in std_logic;
i_transmit : in std_logic;
i_1bit_data_in : in std_logic;
o_1bit_data_out : out std_logic;
o_operation_complete : out std_logic;
o_crc_passed : out std_logic;
o_timed_out : out std_logic;
o_dat_direction : out std_logic; -- set to 1 to send data, set to 0 to receive it.
-- 16 bit port to be accessed by a user circuit.
i_enable_16bit_port : in std_logic;
i_address_16bit_port : in std_logic_vector(7 downto 0);
i_write_16bit : in std_logic;
i_16bit_data_in : in std_logic_vector(15 downto 0);
o_16bit_data_out : out std_logic_vector(15 downto 0)
);
end entity;
architecture rtl of Altera_UP_SD_Card_Buffer is
component Altera_UP_SD_CRC16_Generator
port
(
i_clock : in std_logic;
i_enable : in std_logic;
i_reset_n : in std_logic;
i_sync_reset : in std_logic;
i_shift : in std_logic;
i_datain : in std_logic;
o_dataout : out std_logic;
o_crcout : out std_logic_vector(15 downto 0)
);
end component;
component Altera_UP_SD_Card_Memory_Block
PORT
(
address_a : IN STD_LOGIC_VECTOR (7 DOWNTO 0);
address_b : IN STD_LOGIC_VECTOR (11 DOWNTO 0);
clock_a : IN STD_LOGIC ;
clock_b : IN STD_LOGIC ;
data_a : IN STD_LOGIC_VECTOR (15 DOWNTO 0);
data_b : IN STD_LOGIC_VECTOR (0 DOWNTO 0);
enable_a : IN STD_LOGIC := '1';
enable_b : IN STD_LOGIC := '1';
wren_a : IN STD_LOGIC := '1';
wren_b : IN STD_LOGIC := '1';
q_a : OUT STD_LOGIC_VECTOR (15 DOWNTO 0);
q_b : OUT STD_LOGIC_VECTOR (0 DOWNTO 0)
);
END component;
-- Build an enumerated type for the state machine. On reset always reset the DE2 and read the state
-- of the switches.
type state_type is (s_RESET, s_WAIT_REQUEST, s_SEND_START_BIT, s_SEND_DATA, s_SEND_CRC, s_SEND_STOP, s_WAIT_BUSY, s_WAIT_BUSY_END,
s_WAIT_DATA_START, s_RECEIVING_LEADING_BITS, s_RECEIVING_DATA, s_RECEIVING_STOP_BIT, s_WAIT_DEASSERT);
-- Register to hold the current state
signal current_state : state_type;
signal next_state : state_type;
-- Local wires
-- REGISTERED
signal crc_counter : std_logic_vector(3 downto 0);
signal local_mode : std_logic;
signal dataout_1bit : std_logic;
signal bit_counter : std_logic_vector(2 downto 0);
signal byte_counter : std_logic_vector(8 downto 0);
signal shift_register : std_logic_vector(16 downto 0);
signal timeout_register : std_logic_vector(15 downto 0);
signal data_in_reg : std_logic;
-- UNREGISTERED
signal crc_out : std_logic_vector(15 downto 0);
signal single_bit_conversion, single_bit_out : std_logic_vector( 0 downto 0);
signal packet_mem_addr_b : std_logic_vector(11 downto 0);
signal local_reset, to_crc_generator, from_crc_generator, from_mem_1_bit, shift_crc,
recv_data, crc_generator_enable : std_logic;
begin
-- State transitions
state_transitions: process( current_state, i_begin, i_sd_clock_pulse_trigger, i_transmit, byte_counter,
bit_counter, crc_counter, i_1bit_data_in, timeout_register, data_in_reg)
begin
case (current_state) is
when s_RESET =>
-- Reset local registers and begin waiting for user input.
next_state <= s_WAIT_REQUEST;
when s_WAIT_REQUEST =>
-- Wait for i_begin to be high
if ((i_begin = '1') and (i_sd_clock_pulse_trigger = '1')) then
if (i_transmit = '1') then
next_state <= s_SEND_START_BIT;
else
next_state <= s_WAIT_DATA_START;
end if;
else
next_state <= s_WAIT_REQUEST;
end if;
when s_SEND_START_BIT =>
-- Send a 0 first, followed by 4096 bits of data, 16 CRC bits, and stop bit.
if (i_sd_clock_pulse_trigger = '1') then
next_state <= s_SEND_DATA;
else
next_state <= s_SEND_START_BIT;
end if;
when s_SEND_DATA =>
-- Send 4096 data bits
if ((i_sd_clock_pulse_trigger = '1') and (bit_counter = "000") and (byte_counter = "111111111")) then
next_state <= s_SEND_CRC;
else
next_state <= s_SEND_DATA;
end if;
when s_SEND_CRC =>
-- Send 16 CRC bits
if ((i_sd_clock_pulse_trigger = '1') and (crc_counter = "1111")) then
next_state <= s_SEND_STOP;
else
next_state <= s_SEND_CRC;
end if;
when s_SEND_STOP =>
-- Send stop bit.
if (i_sd_clock_pulse_trigger = '1') then
next_state <= s_WAIT_BUSY;
else
next_state <= s_SEND_STOP;
end if;
when s_WAIT_BUSY =>
-- After a write, wait for the busy signal. Do not return a done signal until you receive a busy signal.
-- If you do not and a long time expires, then the data must have been rejected (due to CRC error maybe).
-- In such a case return failure.
if ((i_sd_clock_pulse_trigger = '1') and (data_in_reg = '0') and (timeout_register = "0000000000010000")) then
next_state <= s_WAIT_BUSY_END;
else
if (timeout_register = BUSY_WAIT) then
next_state <= s_WAIT_DEASSERT;
else
next_state <= s_WAIT_BUSY;
end if;
end if;
when s_WAIT_BUSY_END =>
if (i_sd_clock_pulse_trigger = '1') then
if (data_in_reg = '1') then
next_state <= s_WAIT_DEASSERT;
else
next_state <= s_WAIT_BUSY_END;
end if;
else
next_state <= s_WAIT_BUSY_END;
end if;
when s_WAIT_DATA_START =>
-- Wait for the start bit
if ((i_sd_clock_pulse_trigger = '1') and (data_in_reg = '0')) then
next_state <= s_RECEIVING_LEADING_BITS;
else
if (timeout_register = TIMEOUT) then
next_state <= s_WAIT_DEASSERT;
else
next_state <= s_WAIT_DATA_START;
end if;
end if;
when s_RECEIVING_LEADING_BITS =>
-- shift the start bit in as well as the next 16 bits. Once they are all in you can start putting data into memory.
if ((i_sd_clock_pulse_trigger = '1') and (crc_counter = "1111")) then
next_state <= s_RECEIVING_DATA;
else
next_state <= s_RECEIVING_LEADING_BITS;
end if;
when s_RECEIVING_DATA =>
-- Wait until all bits arrive.
if ((i_sd_clock_pulse_trigger = '1') and (bit_counter = "000") and (byte_counter = "111111111")) then
next_state <= s_RECEIVING_STOP_BIT;
else
next_state <= s_RECEIVING_DATA;
end if;
when s_RECEIVING_STOP_BIT =>
-- Wait until all bits arrive.
if (i_sd_clock_pulse_trigger = '1')then
next_state <= s_WAIT_DEASSERT;
else
next_state <= s_RECEIVING_STOP_BIT;
end if;
when s_WAIT_DEASSERT =>
if (i_begin = '1') then
next_state <= s_WAIT_DEASSERT;
else
next_state <= s_WAIT_REQUEST;
end if;
when others =>
next_state <= s_RESET;
end case;
end process;
-- State registers
state_regs: process(i_clock, i_reset_n, local_reset)
begin
if (i_reset_n = '0') then
current_state <= s_RESET;
elsif (rising_edge(i_clock)) then
current_state <= next_state;
end if;
end process;
-- FSM outputs
to_crc_generator <= shift_register(16) when (current_state = s_RECEIVING_DATA) else
from_mem_1_bit when (current_state = s_SEND_DATA) else
'0';
shift_crc <= '1' when (current_state = s_SEND_CRC) else '0';
local_reset <= '1' when ((current_state = s_RESET) or (current_state = s_WAIT_REQUEST)) else '0';
recv_data <= '1' when (current_state = s_RECEIVING_DATA) else '0';
single_bit_conversion(0) <= shift_register(15);
crc_generator_enable <= '0' when (current_state = s_WAIT_DEASSERT) else i_sd_clock_pulse_trigger;
o_operation_complete <= '1' when (current_state = s_WAIT_DEASSERT) else '0';
o_dat_direction <= '1' when ( (current_state = s_SEND_START_BIT) or
(current_state = s_SEND_DATA) or
(current_state = s_SEND_CRC) or
(current_state = s_SEND_STOP))
else '0';
o_1bit_data_out <= dataout_1bit;
o_crc_passed <= '1' when ((crc_out = shift_register(16 downto 1)) and (shift_register(0) = '1')) else '0';
o_timed_out <= '1' when (timeout_register = TIMEOUT) else '0';
-- Local components
local_regs: process(i_clock, i_reset_n, local_reset)
begin
if (i_reset_n = '0') then
bit_counter <= (OTHERS => '1');
byte_counter <= (OTHERS => '0');
dataout_1bit <= '1';
crc_counter <= (OTHERS => '0');
shift_register <= (OTHERS => '0');
elsif (rising_edge(i_clock)) then
-- counters and serial output
if (local_reset = '1') then
bit_counter <= (OTHERS => '1');
byte_counter <= (OTHERS => '0');
dataout_1bit <= '1';
data_in_reg <= '1';
crc_counter <= (OTHERS => '0');
shift_register <= (OTHERS => '0');
elsif (i_sd_clock_pulse_trigger = '1') then
if ((not (current_state = s_RECEIVING_LEADING_BITS)) and (not (current_state = s_SEND_CRC))) then
crc_counter <= (OTHERS => '0');
else
if (not (crc_counter = "1111")) then
crc_counter <= crc_counter + '1';
end if;
end if;
if ((current_state = s_RECEIVING_DATA) or (current_state = s_SEND_DATA)) then
if (not ((bit_counter = "000") and (byte_counter = "111111111"))) then
if (bit_counter = "000") then
byte_counter <= byte_counter + '1';
bit_counter <= "111";
else
bit_counter <= bit_counter - '1';
end if;
end if;
end if;
-- Output data bit.
if (current_state = s_SEND_START_BIT) then
dataout_1bit <= '0';
elsif (current_state = s_SEND_DATA) then
dataout_1bit <= from_mem_1_bit;
elsif (current_state = s_SEND_CRC) then
dataout_1bit <= from_crc_generator;
else
dataout_1bit <= '1'; -- Stop bit.
end if;
-- Shift register to store the CRC bits once the message is received.
if ((current_state = s_RECEIVING_DATA) or
(current_state = s_RECEIVING_LEADING_BITS) or
(current_state = s_RECEIVING_STOP_BIT)) then
shift_register(16 downto 1) <= shift_register(15 downto 0);
shift_register(0) <= data_in_reg;
end if;
data_in_reg <= i_1bit_data_in;
end if;
end if;
end process;
-- Register holding the timeout value for data transmission.
timeout_reg: process(i_clock, i_reset_n, current_state, i_sd_clock_pulse_trigger)
begin
if (i_reset_n = '0') then
timeout_register <= (OTHERS => '0');
elsif (rising_edge(i_clock)) then
if ((current_state = s_SEND_STOP) or
(current_state = s_WAIT_REQUEST)) then
timeout_register <= (OTHERS => '0');
elsif (i_sd_clock_pulse_trigger = '1') then
-- Increment the timeout counter
if (((current_state = s_WAIT_DATA_START) or
(current_state = s_WAIT_BUSY)) and (not (timeout_register = TIMEOUT))) then
timeout_register <= timeout_register + '1';
end if;
end if;
end if;
end process;
-- Instantiated components.
crc16_checker: Altera_UP_SD_CRC16_Generator
port map
(
i_clock => i_clock,
i_reset_n => i_reset_n,
i_sync_reset => local_reset,
i_enable => crc_generator_enable,
i_shift => shift_crc,
i_datain => to_crc_generator,
o_dataout => from_crc_generator,
o_crcout => crc_out
);
packet_memory: Altera_UP_SD_Card_Memory_Block
PORT MAP
(
address_a => i_address_16bit_port,
address_b => packet_mem_addr_b,
clock_a => i_clock,
clock_b => i_clock,
data_a => i_16bit_data_in,
data_b => single_bit_conversion,
enable_a => i_enable_16bit_port,
enable_b => '1',
wren_a => i_write_16bit,
wren_b => recv_data,
q_a => o_16bit_data_out,
q_b => single_bit_out
);
from_mem_1_bit <= single_bit_out(0);
packet_mem_addr_b <= (byte_counter & bit_counter);
end rtl;

View File

@ -1,80 +0,0 @@
-- (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 is a clock generator for the SD card interface. It takes a 50 MHz
-- clock as input and produces a clock signal that depends on the mode in which the
-- SD card interface is in. For a card identification mode a clock with a frequency of
-- 390.625 kHz is generated. For the data transfer mode, a clock with a frequency of
-- 12.5MHz is generated.
--
-- In addition, the generator produces a clock_mode value that identifies the frequency
-- of the o_SD_clock that is currently being generated.
--
-- 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_Clock is
port
(
i_clock : in std_logic;
i_reset_n : in std_logic;
i_enable : in std_logic;
i_mode : in std_logic; -- 0 for card identification mode, 1 for data transfer mode.
o_SD_clock : out std_logic;
o_clock_mode : out std_logic;
o_trigger_receive : out std_logic;
o_trigger_send : out std_logic
);
end entity;
architecture rtl of Altera_UP_SD_Card_Clock is
-- Local wires
-- REGISTERED
signal counter : std_logic_vector(6 downto 0);
signal local_mode : std_logic;
-- UNREGISTERED
begin
process(i_clock, i_reset_n)
begin
if (i_reset_n = '0') then
counter <= (OTHERS => '0');
local_mode <= '0';
else
if (rising_edge(i_clock)) then
if (i_enable = '1') then
counter <= counter + '1';
end if;
-- Change the clock pulse only when at the positive edge of the clock
if (counter = "1000000") then
local_mode <= i_mode;
end if;
end if;
end if;
end process;
o_clock_mode <= local_mode;
o_SD_clock <= counter(6) when (local_mode = '0') else counter(1);
o_trigger_receive <= '1' when ((local_mode = '0') and (counter = "0111111")) else
((not counter(1)) and (counter(0))) when (local_mode = '1') else '0';
o_trigger_send <= '1' when ((local_mode = '0') and (counter = "0011111")) else
((counter(1)) and (counter(0))) when (local_mode = '1') else '0';
end rtl;

View File

@ -1,347 +0,0 @@
-- (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 is an FSM that controls the SD Card interface circuitry.
--
-- On reset, the FSM will initiate a predefined set of commands in an attempt to connect to the SD Card.
-- When successful, it will allow commands to be issued to the SD Card, otherwise it will return a signal that
-- no card is present in the SD Card slot.
--
-- 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_Control_FSM is
generic (
PREDEFINED_COMMAND_GET_STATUS : STD_LOGIC_VECTOR(3 downto 0) := "1001"
);
port
(
-- Clock and Reset signals
i_clock : in STD_LOGIC;
i_reset_n : in STD_LOGIC;
-- FSM Inputs
i_user_command_ready : in std_logic;
i_response_received : in STD_LOGIC;
i_response_timed_out : in STD_LOGIC;
i_response_crc_passed : in STD_LOGIC;
i_command_sent : in STD_LOGIC;
i_powerup_busy_n : in STD_LOGIC;
i_clocking_pulse_enable : in std_logic;
i_current_clock_mode : in std_logic;
i_user_message_valid : in std_logic;
i_last_cmd_was_55 : in std_logic;
i_allow_partial_rw : in std_logic;
-- FSM Outputs
o_generate_command : out STD_LOGIC;
o_predefined_command_ID : out STD_LOGIC_VECTOR(3 downto 0);
o_receive_response : out STD_LOGIC;
o_drive_CMD_line : out STD_LOGIC;
o_SD_clock_mode : out STD_LOGIC; -- 0 means slow clock for card identification, 1 means fast clock for transfer mode.
o_resetting : out std_logic;
o_card_connected : out STD_LOGIC;
o_command_completed : out std_logic;
o_clear_response_register : out std_logic;
o_enable_clock_generator : out std_logic
);
end entity;
architecture rtl of Altera_UP_SD_Card_Control_FSM is
-- Build an enumerated type for the state machine. On reset always reset the DE2 and read the state
-- of the switches.
type state_type is (s_RESET, s_WAIT_74_CYCLES, s_GENERATE_PREDEFINED_COMMAND, s_WAIT_PREDEFINED_COMMAND_TRANSMITTED, s_WAIT_PREDEFINED_COMMAND_RESPONSE,
s_GO_TO_NEXT_COMMAND, s_TOGGLE_CLOCK_FREQUENCY, s_AWAIT_USER_COMMAND, s_REACTIVATE_CLOCK,
s_GENERATE_COMMAND, s_SEND_COMMAND, s_WAIT_RESPONSE, s_WAIT_FOR_CLOCK_EDGE_BEFORE_DISABLE, s_WAIT_DEASSERT,
s_PERIODIC_STATUS_CHECK);
-- Register to hold the current state
signal current_state : state_type;
signal next_state : state_type;
-------------------
-- Local signals
-------------------
-- REGISTERED
signal SD_clock_mode, waiting_for_vdd_setup : std_logic;
signal id_sequence_step_index : std_logic_vector(3 downto 0);
signal delay_counter : std_logic_vector(6 downto 0);
signal periodic_status_check : std_logic_vector(23 downto 0);
-- UNREGISTERED
begin
-- Define state transitions.
state_transitions: process (current_state, i_command_sent, i_response_received, id_sequence_step_index,
i_response_timed_out, i_response_crc_passed, delay_counter, waiting_for_vdd_setup,
i_user_command_ready, i_clocking_pulse_enable, i_current_clock_mode,
i_user_message_valid, i_last_cmd_was_55, periodic_status_check)
begin
case current_state is
when s_RESET =>
-- Reset local registers and begin identification process.
next_state <= s_WAIT_74_CYCLES;
when s_WAIT_74_CYCLES =>
-- Wait 74 cycles before the card can be sent commands to.
if (delay_counter = "1001010") then
next_state <= s_GENERATE_PREDEFINED_COMMAND;
else
next_state <= s_WAIT_74_CYCLES;
end if;
when s_GENERATE_PREDEFINED_COMMAND =>
-- Generate a predefined command to the SD card. This is the identification process for the SD card.
next_state <= s_WAIT_PREDEFINED_COMMAND_TRANSMITTED;
when s_WAIT_PREDEFINED_COMMAND_TRANSMITTED =>
-- Send a predefined command to the SD card. This is the identification process for the SD card.
if (i_command_sent = '1') then
next_state <= s_WAIT_PREDEFINED_COMMAND_RESPONSE;
else
next_state <= s_WAIT_PREDEFINED_COMMAND_TRANSMITTED;
end if;
when s_WAIT_PREDEFINED_COMMAND_RESPONSE =>
-- Wait for a response from SD card.
if (i_response_received = '1') then
if (i_response_timed_out = '1') then
if (waiting_for_vdd_setup = '1') then
next_state <= s_GO_TO_NEXT_COMMAND;
else
next_state <= s_RESET;
end if;
else
if (i_response_crc_passed = '0') then
next_state <= s_GENERATE_PREDEFINED_COMMAND;
else
next_state <= s_GO_TO_NEXT_COMMAND;
end if;
end if;
else
next_state <= s_WAIT_PREDEFINED_COMMAND_RESPONSE;
end if;
when s_GO_TO_NEXT_COMMAND =>
-- Process the next command in the ID sequence.
if (id_sequence_step_index = PREDEFINED_COMMAND_GET_STATUS) then
next_state <= s_TOGGLE_CLOCK_FREQUENCY;
else
next_state <= s_GENERATE_PREDEFINED_COMMAND;
end if;
when s_TOGGLE_CLOCK_FREQUENCY =>
-- Now that the card has been initialized, increase the SD card clock frequency to 25MHz.
-- Wait for the clock generator to switch operating mode before proceeding further.
if (i_current_clock_mode = '1') then
next_state <= s_AWAIT_USER_COMMAND;
else
next_state <= s_TOGGLE_CLOCK_FREQUENCY;
end if;
when s_AWAIT_USER_COMMAND =>
-- Wait for the user to send a command to the SD card
if (i_user_command_ready = '1') then
next_state <= s_REACTIVATE_CLOCK;
else
-- Every 5 million cycles, or 0.1 of a second.
if (periodic_status_check = "010011000100101101000000") then
next_state <= s_PERIODIC_STATUS_CHECK;
else
next_state <= s_AWAIT_USER_COMMAND;
end if;
end if;
when s_PERIODIC_STATUS_CHECK =>
-- Update status every now and then.
next_state <= s_GENERATE_PREDEFINED_COMMAND;
when s_REACTIVATE_CLOCK =>
-- Activate the clock signal and wait 8 clock cycles.
if (delay_counter = "0001000") then
next_state <= s_GENERATE_COMMAND;
else
next_state <= s_REACTIVATE_CLOCK;
end if;
when s_GENERATE_COMMAND =>
-- Generate user command. If valid, proceed further. Otherwise, indicate that the command is invalid.
if (i_user_message_valid = '0') then
next_state <= s_WAIT_DEASSERT;
else
next_state <= s_SEND_COMMAND;
end if;
when s_SEND_COMMAND =>
-- Wait for the command to be sent.
if (i_command_sent = '1') then
next_state <= s_WAIT_RESPONSE;
else
next_state <= s_SEND_COMMAND;
end if;
when s_WAIT_RESPONSE =>
-- Wait for the SD card to respond.
if (i_response_received = '1') then
if (i_response_timed_out = '1') then
next_state <= s_WAIT_DEASSERT;
else
next_state <= s_WAIT_FOR_CLOCK_EDGE_BEFORE_DISABLE;
end if;
else
next_state <= s_WAIT_RESPONSE;
end if;
when s_WAIT_FOR_CLOCK_EDGE_BEFORE_DISABLE =>
-- Wait for a positive clock edge before you disable the clock.
if (i_clocking_pulse_enable = '1') then
next_state <= s_WAIT_DEASSERT;
else
next_state <= s_WAIT_FOR_CLOCK_EDGE_BEFORE_DISABLE;
end if;
when s_WAIT_DEASSERT =>
-- wait for the user to release command generation request.
if (i_user_command_ready = '1') then
next_state <= s_WAIT_DEASSERT;
else
if (i_last_cmd_was_55 = '1') then
next_state <= s_AWAIT_USER_COMMAND;
else
-- Send a get status command to obtain the result of sending the last command.
next_state <= s_GENERATE_PREDEFINED_COMMAND;
end if;
end if;
when others =>
-- Make sure to start in the reset state if the circuit powers up in an odd state.
next_state <= s_RESET;
end case;
end process;
-- State registers.
state_registers: process (i_clock, i_reset_n)
begin
if (i_reset_n = '0') then
current_state <= s_RESET;
elsif (rising_edge(i_clock)) then
current_state <= next_state;
end if;
end process;
-- Local FFs:
local_ffs:process ( i_clock, i_reset_n, i_powerup_busy_n, current_state,
id_sequence_step_index, i_response_received, i_response_timed_out,
i_allow_partial_rw)
begin
if (i_reset_n = '0') then
SD_clock_mode <= '0';
id_sequence_step_index <= (OTHERS => '0');
periodic_status_check <= (OTHERS => '0');
waiting_for_vdd_setup <= '0';
elsif (rising_edge(i_clock)) then
-- Set SD clock mode to 0 initially, thereby using a clock with frequency between 100 kHz and 400 kHz as
-- per SD card specifications. When the card is initialized change the clock to run at 25 MHz.
if (current_state = s_WAIT_DEASSERT) then
periodic_status_check <= (OTHERS => '0');
elsif (current_state = s_AWAIT_USER_COMMAND) then
periodic_status_check <= periodic_status_check + '1';
end if;
if (current_state = s_RESET) then
SD_clock_mode <= '0';
elsif (current_state = s_TOGGLE_CLOCK_FREQUENCY) then
SD_clock_mode <= '1';
end if;
-- Update the ID sequence step as needed.
if (current_state = s_RESET) then
id_sequence_step_index <= (OTHERS => '0');
elsif (current_state = s_GO_TO_NEXT_COMMAND) then
if ((i_powerup_busy_n = '0') and (id_sequence_step_index = "0010")) then
id_sequence_step_index <= "0001";
else
if (id_sequence_step_index = "0110") then
if (i_allow_partial_rw = '0') then
-- If partial read-write not allowed, then skip SET_BLK_LEN command - it will fail.
id_sequence_step_index <= "1000";
else
id_sequence_step_index <= "0111";
end if;
else
id_sequence_step_index <= id_sequence_step_index + '1';
end if;
end if;
elsif (current_state = s_WAIT_DEASSERT) then
if (i_last_cmd_was_55 = '0') then
-- After each command execute a get status command.
id_sequence_step_index <= PREDEFINED_COMMAND_GET_STATUS;
end if;
elsif (current_state = s_PERIODIC_STATUS_CHECK) then
id_sequence_step_index <= PREDEFINED_COMMAND_GET_STATUS;
end if;
-- Do not reset the card when SD card is having its VDD set up. Wait for it to respond, this may take some time.
if (id_sequence_step_index = "0010") then
waiting_for_vdd_setup <= '1';
elsif ((id_sequence_step_index = "0011") or (current_state = s_RESET)) then
waiting_for_vdd_setup <= '0';
end if;
end if;
end process;
-- Counter that counts to 74 to delay any commands.
initial_delay_counter: process(i_clock, i_reset_n, i_clocking_pulse_enable )
begin
if (i_reset_n = '0') then
delay_counter <= (OTHERS => '0');
elsif (rising_edge(i_clock)) then
if ((current_state = s_RESET) or (current_state = s_AWAIT_USER_COMMAND))then
delay_counter <= (OTHERS => '0');
elsif (((current_state = s_WAIT_74_CYCLES) or (current_state = s_REACTIVATE_CLOCK)) and
(i_clocking_pulse_enable = '1')) then
delay_counter <= delay_counter + '1';
end if;
end if;
end process;
-- FSM outputs.
o_SD_clock_mode <= SD_clock_mode;
o_generate_command <= '1' when ((current_state = s_GENERATE_PREDEFINED_COMMAND) or
(current_state = s_GENERATE_COMMAND))
else '0';
o_receive_response <= '1' when ((current_state = s_WAIT_PREDEFINED_COMMAND_RESPONSE) or
(current_state = s_WAIT_RESPONSE))
else '0';
o_drive_CMD_line <= '1' when ( (current_state = s_WAIT_PREDEFINED_COMMAND_TRANSMITTED) or
(current_state = s_SEND_COMMAND)) else '0';
o_predefined_command_ID <= id_sequence_step_index;
o_card_connected <= '1' when (id_sequence_step_index(3) = '1') and (
(id_sequence_step_index(2) = '1') or
(id_sequence_step_index(1) = '1') or
(id_sequence_step_index(0) = '1'))
else '0';
o_resetting <= '1' when (current_state = s_RESET) else '0';
o_command_completed <= '1' when (current_state = s_WAIT_DEASSERT) else '0';
o_enable_clock_generator <= '0' when (current_state = s_AWAIT_USER_COMMAND) else '1';
o_clear_response_register <= '1' when (current_state = s_REACTIVATE_CLOCK) else '0';
end rtl;

View File

@ -1,518 +0,0 @@
-- (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 is an interface to the Secure Data Card. This module is intended to be
-- used with the DE2 board.
--
-- This version of the interface supports only a 1-bit serial data transfer. This
-- allows the interface to support a MultiMedia card as well.
--
-- NOTES/REVISIONS:
-------------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity Altera_UP_SD_Card_Interface is
port
(
i_clock : in std_logic;
i_reset_n : in std_logic;
-- Command interface
b_SD_cmd : inout std_logic;
b_SD_dat : inout std_logic;
b_SD_dat3 : inout std_logic;
i_command_ID : in std_logic_vector(5 downto 0);
i_argument : in std_logic_vector(31 downto 0);
i_user_command_ready : in std_logic;
o_SD_clock : out std_logic;
o_card_connected : out std_logic;
o_command_completed : out std_logic;
o_command_valid : out std_logic;
o_command_timed_out : out std_logic;
o_command_crc_failed : out std_logic;
-- Buffer access
i_buffer_enable : in std_logic;
i_buffer_address : in std_logic_vector(7 downto 0);
i_buffer_write : in std_logic;
i_buffer_data_in : in std_logic_vector(15 downto 0);
o_buffer_data_out : out std_logic_vector(15 downto 0);
-- Show SD Card registers as outputs
o_SD_REG_card_identification_number : out std_logic_vector(127 downto 0);
o_SD_REG_relative_card_address : out std_logic_vector(15 downto 0);
o_SD_REG_operating_conditions_register : out std_logic_vector(31 downto 0);
o_SD_REG_card_specific_data : out std_logic_vector(127 downto 0);
o_SD_REG_status_register : out std_logic_vector(31 downto 0);
o_SD_REG_response_R1 : out std_logic_vector(31 downto 0);
o_SD_REG_status_register_valid : out std_logic
);
end entity;
architecture rtl of Altera_UP_SD_Card_Interface is
component Altera_UP_SD_Card_Clock
port
(
i_clock : in std_logic;
i_reset_n : in std_logic;
i_enable : in std_logic;
i_mode : in std_logic; -- 0 for card identification mode, 1 for data transfer mode.
o_SD_clock : out std_logic;
o_clock_mode : out std_logic;
o_trigger_receive : out std_logic;
o_trigger_send : out std_logic
);
end component;
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;
component Altera_UP_SD_CRC16_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(15 downto 0)
);
end component;
component Altera_UP_SD_Signal_Trigger
port
(
i_clock : in std_logic;
i_reset_n : in std_logic;
i_signal : in std_logic;
o_trigger : out std_logic
);
end component;
component Altera_UP_SD_Card_48_bit_Command_Generator
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 component;
component Altera_UP_SD_Card_Response_Receiver
generic (
TIMEOUT : std_logic_vector(7 downto 0) := "00111000";
BUSY_WAIT : std_logic_vector(7 downto 0) := "00110000";
PROCESSING_DELAY : std_logic_vector(7 downto 0) := "00001000"
);
port
(
i_clock : in std_logic;
i_reset_n : in std_logic;
i_begin : in std_logic;
i_scan_pulse : in std_logic;
i_datain : in std_logic;
i_wait_cmd_busy : in std_logic;
i_response_type : in std_logic_vector(2 downto 0);
o_data : out std_logic_vector(127 downto 0);
o_CRC_passed : out std_logic;
o_timeout : out std_logic;
o_done : out std_logic
);
end component;
component Altera_UP_SD_Card_Control_FSM
generic (
PREDEFINED_COMMAND_GET_STATUS : STD_LOGIC_VECTOR(3 downto 0) := "1001"
);
port
(
-- Clock and Reset signals
i_clock : in STD_LOGIC;
i_reset_n : in STD_LOGIC;
-- FSM Inputs
i_user_command_ready : in std_logic;
i_response_received : in STD_LOGIC;
i_response_timed_out : in STD_LOGIC;
i_response_crc_passed : in STD_LOGIC;
i_command_sent : in STD_LOGIC;
i_powerup_busy_n : in STD_LOGIC;
i_clocking_pulse_enable : in std_logic;
i_current_clock_mode : in std_logic;
i_user_message_valid : in std_logic;
i_last_cmd_was_55 : in std_logic;
i_allow_partial_rw : in std_logic;
-- FSM Outputs
o_generate_command : out STD_LOGIC;
o_predefined_command_ID : out STD_LOGIC_VECTOR(3 downto 0);
o_receive_response : out STD_LOGIC;
o_drive_CMD_line : out STD_LOGIC;
o_SD_clock_mode : out STD_LOGIC; -- 0 means slow clock for card identification, 1 means fast clock for transfer mode.
o_resetting : out std_logic;
o_card_connected : out STD_LOGIC;
o_command_completed : out std_logic;
o_clear_response_register : out std_logic;
o_enable_clock_generator : out std_logic
);
end component;
component Altera_UP_SD_Card_Buffer
generic (
TIMEOUT : std_logic_vector(15 downto 0) := "1111111111111111";
BUSY_WAIT : std_logic_vector(15 downto 0) := "0000001111110000"
);
port
(
i_clock : in std_logic;
i_reset_n : in std_logic;
-- 1 bit port to transmit and receive data on the data line.
i_begin : in std_logic;
i_sd_clock_pulse_trigger : in std_logic;
i_transmit : in std_logic;
i_1bit_data_in : in std_logic;
o_1bit_data_out : out std_logic;
o_operation_complete : out std_logic;
o_crc_passed : out std_logic;
o_timed_out : out std_logic;
o_dat_direction : out std_logic; -- set to 1 to send data, set to 0 to receive it.
-- 16 bit port to be accessed by a user circuit.
i_enable_16bit_port : in std_logic;
i_address_16bit_port : in std_logic_vector(7 downto 0);
i_write_16bit : in std_logic;
i_16bit_data_in : in std_logic_vector(15 downto 0);
o_16bit_data_out : out std_logic_vector(15 downto 0)
);
end component;
-- Local wires
-- REGISTERED
signal sd_mode : std_logic;
-- SD Card Registers:
signal SD_REG_card_identification_number : std_logic_vector(127 downto 0);
signal SD_REG_response_R1 : std_logic_vector(31 downto 0);
signal SD_REG_relative_card_address : std_logic_vector(15 downto 0);
signal SD_REG_driver_stage_register : std_logic_vector(15 downto 0);
signal SD_REG_card_specific_data : std_logic_vector(127 downto 0);
signal SD_REG_operating_conditions_register : std_logic_vector(31 downto 0);
signal SD_REG_status_register : std_logic_vector(31 downto 0);
signal SD_REG_status_register_valid : std_logic;
-- UNREGISTERED
signal data_from_buffer : std_logic_vector(15 downto 0);
signal clock_generator_mode, enable_generator, SD_clock, create_message : std_logic;
signal send_next_bit, receive_next_bit : std_logic;
signal timed_out, response_done, passed_crc, begin_reading_response, resetting : std_logic;
signal returning_cid, returning_rca, returning_csd, returning_ocr : std_logic;
signal response_type : std_logic_vector(2 downto 0);
signal message_valid, messange_sent, data_to_CMD_line, CMD_tristate_buffer_enable, message_sent : std_logic;
signal predef_message_ID : std_logic_vector(3 downto 0);
signal receive_data_out : std_logic_vector(127 downto 0);
signal data_line_done, data_line_crc, data_line_timeout, data_line_direction, data_line_out : std_logic;
signal data_read, data_write, wait_cmd_busy, clear_response_register : std_logic;
signal response_done_combined : std_logic;
signal timeout_combined : std_logic;
signal crc_combined, allow_partial_rw : std_logic;
signal begin_data_line_operations, last_cmd_was_55, message_sent_trigger, returning_status : std_logic;
signal data_line_sd_clock_pulse_trigger : std_logic;
begin
-- Glue logic
SD_REG_driver_stage_register <= (OTHERS => '0');
response_done_combined <= (response_done and (not data_read) and (not data_write)) or
(response_done and (data_read or data_write) and data_line_done);
timeout_combined <= (timed_out and (not data_read) and (not data_write)) or
(timed_out and (data_read or data_write) and data_line_timeout);
crc_combined <= (passed_crc and (not data_read) and (not data_write)) or
(passed_crc and (data_read or data_write) and data_line_crc);
begin_data_line_operations <= (data_read and message_sent) or (data_write and response_done);
-- Partial read and write are only allowed when both bit 79 (partial read allowed) is high and
-- bit 21 (partial write allowed) is high.
allow_partial_rw <= SD_REG_card_specific_data(79) and SD_REG_card_specific_data(21);
-- SD Card control registers
control_regs: process (i_clock, i_reset_n)
begin
if (i_reset_n = '0') then
SD_REG_operating_conditions_register <= (OTHERS => '0');
SD_REG_card_identification_number <= (OTHERS => '0');
SD_REG_relative_card_address <= (OTHERS => '0');
SD_REG_card_specific_data <= (OTHERS => '0');
SD_REG_status_register <= (OTHERS => '0');
SD_REG_response_R1 <= (OTHERS => '1');
SD_REG_status_register_valid <= '0';
elsif (rising_edge(i_clock)) then
if ((response_type = "001") and (response_done = '1') and (returning_status = '0') and (clear_response_register = '0')) then
SD_REG_response_R1 <= receive_data_out(31 downto 0);
elsif (clear_response_register = '1') then
SD_REG_response_R1 <= (OTHERS => '1');
end if;
if (resetting = '1') then
SD_REG_operating_conditions_register <= (OTHERS => '0');
elsif ((returning_ocr = '1') and (passed_crc = '1') and (response_done = '1') and (timed_out = '0')) then
SD_REG_operating_conditions_register <= receive_data_out(31 downto 0);
end if;
if ((returning_cid = '1') and (passed_crc = '1') and (response_done = '1') and (timed_out = '0')) then
SD_REG_card_identification_number <= receive_data_out;
end if;
if ((returning_rca = '1') and (passed_crc = '1') and (response_done = '1') and (timed_out = '0')) then
SD_REG_relative_card_address <= receive_data_out(31 downto 16);
end if;
if ((returning_csd = '1') and (passed_crc = '1') and (response_done = '1') and (timed_out = '0')) then
SD_REG_card_specific_data <= receive_data_out;
end if;
if (message_sent_trigger = '1') then
SD_REG_status_register_valid <= '0';
elsif ((returning_status = '1') and (passed_crc = '1') and (response_done = '1') and (timed_out = '0')) then
SD_REG_status_register <= receive_data_out(31 downto 0);
SD_REG_status_register_valid <= '1';
end if;
end if;
end process;
-- Instantiated components
command_generator: Altera_UP_SD_Card_48_bit_Command_Generator PORT MAP
(
i_clock => i_clock,
i_reset_n => i_reset_n,
i_message_bit_out => send_next_bit,
i_command_ID => i_command_ID,
i_argument => i_argument,
i_predefined_message => predef_message_ID,
i_generate => create_message,
i_DSR => SD_REG_driver_stage_register,
i_OCR => SD_REG_operating_conditions_register,
i_RCA => SD_REG_relative_card_address,
o_dataout => data_to_CMD_line,
o_message_done => message_sent,
o_valid => message_valid,
o_returning_ocr => returning_ocr,
o_returning_cid => returning_cid,
o_returning_rca => returning_rca,
o_returning_csd => returning_csd,
o_returning_status => returning_status,
o_data_read => data_read,
o_data_write => data_write,
o_wait_cmd_busy => wait_cmd_busy,
o_last_cmd_was_55 => last_cmd_was_55,
o_response_type => response_type
);
response_receiver: Altera_UP_SD_Card_Response_Receiver PORT MAP
(
i_clock => i_clock,
i_reset_n => i_reset_n,
i_begin => begin_reading_response,
i_scan_pulse => receive_next_bit,
i_datain => b_SD_cmd,
i_response_type => response_type,
i_wait_cmd_busy => wait_cmd_busy,
o_data => receive_data_out,
o_CRC_passed => passed_crc,
o_timeout => timed_out,
o_done => response_done
);
control_FSM: Altera_UP_SD_Card_Control_FSM PORT MAP
(
-- Clock and Reset signals
i_clock => i_clock,
i_reset_n => i_reset_n,
-- FSM Inputs
i_user_command_ready => i_user_command_ready,
i_clocking_pulse_enable => receive_next_bit,
i_response_received => response_done_combined,
i_response_timed_out => timeout_combined,
i_response_crc_passed => crc_combined,
i_command_sent => message_sent,
i_powerup_busy_n => SD_REG_operating_conditions_register(31),
i_current_clock_mode => clock_generator_mode,
i_user_message_valid => message_valid,
i_last_cmd_was_55 => last_cmd_was_55,
i_allow_partial_rw => allow_partial_rw,
-- FSM Outputs
o_generate_command => create_message,
o_predefined_command_ID => predef_message_ID,
o_receive_response => begin_reading_response,
o_drive_CMD_line => CMD_tristate_buffer_enable,
o_SD_clock_mode => sd_mode, -- 0 means slow clock for card identification, 1 means fast clock for transfer mode.
o_card_connected => o_card_connected,
o_command_completed => o_command_completed,
o_resetting => resetting,
o_clear_response_register => clear_response_register,
o_enable_clock_generator => enable_generator
);
clock_generator: Altera_UP_SD_Card_Clock PORT MAP
(
i_clock => i_clock,
i_reset_n => i_reset_n,
i_mode => sd_mode,
i_enable => enable_generator,
o_SD_clock => SD_clock,
o_clock_mode => clock_generator_mode,
o_trigger_receive => receive_next_bit,
o_trigger_send => send_next_bit
);
SD_clock_pulse_trigger: Altera_UP_SD_Signal_Trigger PORT MAP
(
i_clock => i_clock,
i_reset_n => i_reset_n,
i_signal => message_sent,
o_trigger => message_sent_trigger
);
data_line: Altera_UP_SD_Card_Buffer
port map
(
i_clock => i_clock,
i_reset_n => i_reset_n,
-- 1 bit port to transmit and receive data on the data line.
i_begin => begin_data_line_operations,
i_sd_clock_pulse_trigger => data_line_sd_clock_pulse_trigger,
i_transmit => data_write,
i_1bit_data_in => b_SD_dat,
o_1bit_data_out => data_line_out,
o_operation_complete => data_line_done,
o_crc_passed => data_line_crc,
o_timed_out => data_line_timeout,
o_dat_direction => data_line_direction,
-- 16 bit port to be accessed by a user circuit.
i_enable_16bit_port => i_buffer_enable,
i_address_16bit_port => i_buffer_address,
i_write_16bit => i_buffer_write,
i_16bit_data_in => i_buffer_data_in,
o_16bit_data_out => data_from_buffer
);
data_line_sd_clock_pulse_trigger <= (data_write and send_next_bit) or ((not data_write) and receive_next_bit);
-- Buffer output registers.
buff_regs: process(i_clock, i_reset_n, data_from_buffer)
begin
if (i_reset_n = '0') then
o_buffer_data_out <= (OTHERS=> '0');
elsif (rising_edge(i_clock)) then
o_buffer_data_out <= data_from_buffer;
end if;
end process;
-- Circuit outputs.
o_command_valid <= message_valid;
o_command_timed_out <= timeout_combined;
o_command_crc_failed <= not crc_combined;
o_SD_clock <= SD_clock;
b_SD_cmd <= data_to_CMD_line when (CMD_tristate_buffer_enable = '1') else 'Z';
b_SD_dat <= data_line_out when (data_line_direction = '1') else 'Z';
b_SD_dat3 <= 'Z'; -- Set SD card to SD mode.
-- SD card registers
o_SD_REG_card_identification_number <= SD_REG_card_identification_number;
o_SD_REG_relative_card_address <= SD_REG_relative_card_address;
o_SD_REG_operating_conditions_register <= SD_REG_operating_conditions_register;
o_SD_REG_card_specific_data <= SD_REG_card_specific_data;
o_SD_REG_status_register <= SD_REG_status_register;
o_SD_REG_response_R1 <= SD_REG_response_R1;
o_SD_REG_status_register_valid <= SD_REG_status_register_valid;
end rtl;

View File

@ -1,296 +0,0 @@
-- (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.
-- megafunction wizard: %RAM: 2-PORT%
-- GENERATION: STANDARD
-- VERSION: WM1.0
-- MODULE: altsyncram
-- ============================================================
-- File Name: Altera_UP_SD_Card_Memory_Block.vhd
-- Megafunction Name(s):
-- altsyncram
--
-- Simulation Library Files(s):
-- altera_mf
-- ============================================================
-- ************************************************************
-- THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
--
-- 8.0 Build 215 05/29/2008 SJ Full Version
-- ************************************************************
--Copyright (C) 1991-2013 Altera Corporation
--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 from 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.
LIBRARY ieee;
USE ieee.std_logic_1164.all;
LIBRARY altera_mf;
USE altera_mf.all;
ENTITY Altera_UP_SD_Card_Memory_Block IS
PORT
(
address_a : IN STD_LOGIC_VECTOR (7 DOWNTO 0);
address_b : IN STD_LOGIC_VECTOR (11 DOWNTO 0);
clock_a : IN STD_LOGIC ;
clock_b : IN STD_LOGIC ;
data_a : IN STD_LOGIC_VECTOR (15 DOWNTO 0);
data_b : IN STD_LOGIC_VECTOR (0 DOWNTO 0);
enable_a : IN STD_LOGIC := '1';
enable_b : IN STD_LOGIC := '1';
wren_a : IN STD_LOGIC := '1';
wren_b : IN STD_LOGIC := '1';
q_a : OUT STD_LOGIC_VECTOR (15 DOWNTO 0);
q_b : OUT STD_LOGIC_VECTOR (0 DOWNTO 0)
);
END Altera_UP_SD_Card_Memory_Block;
ARCHITECTURE SYN OF altera_up_sd_card_memory_block IS
SIGNAL sub_wire0 : STD_LOGIC_VECTOR (15 DOWNTO 0);
SIGNAL sub_wire1 : STD_LOGIC_VECTOR (0 DOWNTO 0);
COMPONENT altsyncram
GENERIC (
address_reg_b : STRING;
clock_enable_input_a : STRING;
clock_enable_input_b : STRING;
clock_enable_output_a : STRING;
clock_enable_output_b : STRING;
indata_reg_b : STRING;
init_file : STRING;
init_file_layout : STRING;
intended_device_family : STRING;
lpm_type : STRING;
numwords_a : NATURAL;
numwords_b : NATURAL;
operation_mode : STRING;
outdata_aclr_a : STRING;
outdata_aclr_b : STRING;
outdata_reg_a : STRING;
outdata_reg_b : STRING;
power_up_uninitialized : STRING;
widthad_a : NATURAL;
widthad_b : NATURAL;
width_a : NATURAL;
width_b : NATURAL;
width_byteena_a : NATURAL;
width_byteena_b : NATURAL;
wrcontrol_wraddress_reg_b : STRING
);
PORT (
clocken0 : IN STD_LOGIC ;
clocken1 : IN STD_LOGIC ;
wren_a : IN STD_LOGIC ;
clock0 : IN STD_LOGIC ;
wren_b : IN STD_LOGIC ;
clock1 : IN STD_LOGIC ;
address_a : IN STD_LOGIC_VECTOR (7 DOWNTO 0);
address_b : IN STD_LOGIC_VECTOR (11 DOWNTO 0);
q_a : OUT STD_LOGIC_VECTOR (15 DOWNTO 0);
q_b : OUT STD_LOGIC_VECTOR (0 DOWNTO 0);
data_a : IN STD_LOGIC_VECTOR (15 DOWNTO 0);
data_b : IN STD_LOGIC_VECTOR (0 DOWNTO 0)
);
END COMPONENT;
BEGIN
q_a <= sub_wire0(15 DOWNTO 0);
q_b <= sub_wire1(0 DOWNTO 0);
altsyncram_component : altsyncram
GENERIC MAP (
address_reg_b => "CLOCK1",
clock_enable_input_a => "NORMAL",
clock_enable_input_b => "NORMAL",
clock_enable_output_a => "BYPASS",
clock_enable_output_b => "BYPASS",
indata_reg_b => "CLOCK1",
init_file => "initial_data.mif",
init_file_layout => "PORT_A",
intended_device_family => "Cyclone II",
lpm_type => "altsyncram",
numwords_a => 256,
numwords_b => 4096,
operation_mode => "BIDIR_DUAL_PORT",
outdata_aclr_a => "NONE",
outdata_aclr_b => "NONE",
outdata_reg_a => "UNREGISTERED",
outdata_reg_b => "UNREGISTERED",
power_up_uninitialized => "FALSE",
widthad_a => 8,
widthad_b => 12,
width_a => 16,
width_b => 1,
width_byteena_a => 1,
width_byteena_b => 1,
wrcontrol_wraddress_reg_b => "CLOCK1"
)
PORT MAP (
clocken0 => enable_a,
clocken1 => enable_b,
wren_a => wren_a,
clock0 => clock_a,
wren_b => wren_b,
clock1 => clock_b,
address_a => address_a,
address_b => address_b,
data_a => data_a,
data_b => data_b,
q_a => sub_wire0,
q_b => sub_wire1
);
END SYN;
-- ============================================================
-- CNX file retrieval info
-- ============================================================
-- Retrieval info: PRIVATE: ADDRESSSTALL_A NUMERIC "0"
-- Retrieval info: PRIVATE: ADDRESSSTALL_B NUMERIC "0"
-- Retrieval info: PRIVATE: BYTEENA_ACLR_A NUMERIC "0"
-- Retrieval info: PRIVATE: BYTEENA_ACLR_B NUMERIC "0"
-- Retrieval info: PRIVATE: BYTE_ENABLE_A NUMERIC "0"
-- Retrieval info: PRIVATE: BYTE_ENABLE_B NUMERIC "0"
-- Retrieval info: PRIVATE: BYTE_SIZE NUMERIC "8"
-- Retrieval info: PRIVATE: BlankMemory NUMERIC "0"
-- Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_A NUMERIC "1"
-- Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_B NUMERIC "1"
-- Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_A NUMERIC "0"
-- Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_B NUMERIC "0"
-- Retrieval info: PRIVATE: CLRdata NUMERIC "0"
-- Retrieval info: PRIVATE: CLRq NUMERIC "0"
-- Retrieval info: PRIVATE: CLRrdaddress NUMERIC "0"
-- Retrieval info: PRIVATE: CLRrren NUMERIC "0"
-- Retrieval info: PRIVATE: CLRwraddress NUMERIC "0"
-- Retrieval info: PRIVATE: CLRwren NUMERIC "0"
-- Retrieval info: PRIVATE: Clock NUMERIC "5"
-- Retrieval info: PRIVATE: Clock_A NUMERIC "0"
-- Retrieval info: PRIVATE: Clock_B NUMERIC "0"
-- Retrieval info: PRIVATE: ECC NUMERIC "0"
-- Retrieval info: PRIVATE: IMPLEMENT_IN_LES NUMERIC "0"
-- Retrieval info: PRIVATE: INDATA_ACLR_B NUMERIC "0"
-- Retrieval info: PRIVATE: INDATA_REG_B NUMERIC "1"
-- Retrieval info: PRIVATE: INIT_FILE_LAYOUT STRING "PORT_A"
-- Retrieval info: PRIVATE: INIT_TO_SIM_X NUMERIC "0"
-- Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone II"
-- Retrieval info: PRIVATE: JTAG_ENABLED NUMERIC "0"
-- Retrieval info: PRIVATE: JTAG_ID STRING "NONE"
-- Retrieval info: PRIVATE: MAXIMUM_DEPTH NUMERIC "0"
-- Retrieval info: PRIVATE: MEMSIZE NUMERIC "4096"
-- Retrieval info: PRIVATE: MEM_IN_BITS NUMERIC "1"
-- Retrieval info: PRIVATE: MIFfilename STRING "initial_data.mif"
-- Retrieval info: PRIVATE: OPERATION_MODE NUMERIC "3"
-- Retrieval info: PRIVATE: OUTDATA_ACLR_B NUMERIC "0"
-- Retrieval info: PRIVATE: OUTDATA_REG_B NUMERIC "0"
-- Retrieval info: PRIVATE: RAM_BLOCK_TYPE NUMERIC "0"
-- Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_MIXED_PORTS NUMERIC "2"
-- Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_PORT_A NUMERIC "3"
-- Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_PORT_B NUMERIC "3"
-- Retrieval info: PRIVATE: REGdata NUMERIC "1"
-- Retrieval info: PRIVATE: REGq NUMERIC "0"
-- Retrieval info: PRIVATE: REGrdaddress NUMERIC "0"
-- Retrieval info: PRIVATE: REGrren NUMERIC "0"
-- Retrieval info: PRIVATE: REGwraddress NUMERIC "1"
-- Retrieval info: PRIVATE: REGwren NUMERIC "1"
-- Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0"
-- Retrieval info: PRIVATE: USE_DIFF_CLKEN NUMERIC "0"
-- Retrieval info: PRIVATE: UseDPRAM NUMERIC "1"
-- Retrieval info: PRIVATE: VarWidth NUMERIC "1"
-- Retrieval info: PRIVATE: WIDTH_READ_A NUMERIC "16"
-- Retrieval info: PRIVATE: WIDTH_READ_B NUMERIC "1"
-- Retrieval info: PRIVATE: WIDTH_WRITE_A NUMERIC "16"
-- Retrieval info: PRIVATE: WIDTH_WRITE_B NUMERIC "1"
-- Retrieval info: PRIVATE: WRADDR_ACLR_B NUMERIC "0"
-- Retrieval info: PRIVATE: WRADDR_REG_B NUMERIC "1"
-- Retrieval info: PRIVATE: WRCTRL_ACLR_B NUMERIC "0"
-- Retrieval info: PRIVATE: enable NUMERIC "1"
-- Retrieval info: PRIVATE: rden NUMERIC "0"
-- Retrieval info: CONSTANT: ADDRESS_REG_B STRING "CLOCK1"
-- Retrieval info: CONSTANT: CLOCK_ENABLE_INPUT_A STRING "NORMAL"
-- Retrieval info: CONSTANT: CLOCK_ENABLE_INPUT_B STRING "NORMAL"
-- Retrieval info: CONSTANT: CLOCK_ENABLE_OUTPUT_A STRING "BYPASS"
-- Retrieval info: CONSTANT: CLOCK_ENABLE_OUTPUT_B STRING "BYPASS"
-- Retrieval info: CONSTANT: INDATA_REG_B STRING "CLOCK1"
-- Retrieval info: CONSTANT: INIT_FILE STRING "initial_data.mif"
-- Retrieval info: CONSTANT: INIT_FILE_LAYOUT STRING "PORT_A"
-- Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone II"
-- Retrieval info: CONSTANT: LPM_TYPE STRING "altsyncram"
-- Retrieval info: CONSTANT: NUMWORDS_A NUMERIC "256"
-- Retrieval info: CONSTANT: NUMWORDS_B NUMERIC "4096"
-- Retrieval info: CONSTANT: OPERATION_MODE STRING "BIDIR_DUAL_PORT"
-- Retrieval info: CONSTANT: OUTDATA_ACLR_A STRING "NONE"
-- Retrieval info: CONSTANT: OUTDATA_ACLR_B STRING "NONE"
-- Retrieval info: CONSTANT: OUTDATA_REG_A STRING "UNREGISTERED"
-- Retrieval info: CONSTANT: OUTDATA_REG_B STRING "UNREGISTERED"
-- Retrieval info: CONSTANT: POWER_UP_UNINITIALIZED STRING "FALSE"
-- Retrieval info: CONSTANT: WIDTHAD_A NUMERIC "8"
-- Retrieval info: CONSTANT: WIDTHAD_B NUMERIC "12"
-- Retrieval info: CONSTANT: WIDTH_A NUMERIC "16"
-- Retrieval info: CONSTANT: WIDTH_B NUMERIC "1"
-- Retrieval info: CONSTANT: WIDTH_BYTEENA_A NUMERIC "1"
-- Retrieval info: CONSTANT: WIDTH_BYTEENA_B NUMERIC "1"
-- Retrieval info: CONSTANT: WRCONTROL_WRADDRESS_REG_B STRING "CLOCK1"
-- Retrieval info: USED_PORT: address_a 0 0 8 0 INPUT NODEFVAL address_a[7..0]
-- Retrieval info: USED_PORT: address_b 0 0 12 0 INPUT NODEFVAL address_b[11..0]
-- Retrieval info: USED_PORT: clock_a 0 0 0 0 INPUT NODEFVAL clock_a
-- Retrieval info: USED_PORT: clock_b 0 0 0 0 INPUT NODEFVAL clock_b
-- Retrieval info: USED_PORT: data_a 0 0 16 0 INPUT NODEFVAL data_a[15..0]
-- Retrieval info: USED_PORT: data_b 0 0 1 0 INPUT NODEFVAL data_b[0..0]
-- Retrieval info: USED_PORT: enable_a 0 0 0 0 INPUT VCC enable_a
-- Retrieval info: USED_PORT: enable_b 0 0 0 0 INPUT VCC enable_b
-- Retrieval info: USED_PORT: q_a 0 0 16 0 OUTPUT NODEFVAL q_a[15..0]
-- Retrieval info: USED_PORT: q_b 0 0 1 0 OUTPUT NODEFVAL q_b[0..0]
-- Retrieval info: USED_PORT: wren_a 0 0 0 0 INPUT VCC wren_a
-- Retrieval info: USED_PORT: wren_b 0 0 0 0 INPUT VCC wren_b
-- Retrieval info: CONNECT: @data_a 0 0 16 0 data_a 0 0 16 0
-- Retrieval info: CONNECT: @wren_a 0 0 0 0 wren_a 0 0 0 0
-- Retrieval info: CONNECT: q_a 0 0 16 0 @q_a 0 0 16 0
-- Retrieval info: CONNECT: q_b 0 0 1 0 @q_b 0 0 1 0
-- Retrieval info: CONNECT: @address_a 0 0 8 0 address_a 0 0 8 0
-- Retrieval info: CONNECT: @data_b 0 0 1 0 data_b 0 0 1 0
-- Retrieval info: CONNECT: @address_b 0 0 12 0 address_b 0 0 12 0
-- Retrieval info: CONNECT: @wren_b 0 0 0 0 wren_b 0 0 0 0
-- Retrieval info: CONNECT: @clock0 0 0 0 0 clock_a 0 0 0 0
-- Retrieval info: CONNECT: @clocken0 0 0 0 0 enable_a 0 0 0 0
-- Retrieval info: CONNECT: @clock1 0 0 0 0 clock_b 0 0 0 0
-- Retrieval info: CONNECT: @clocken1 0 0 0 0 enable_b 0 0 0 0
-- Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all
-- Retrieval info: GEN_FILE: TYPE_NORMAL Altera_UP_SD_Card_Memory_Block.vhd TRUE
-- Retrieval info: GEN_FILE: TYPE_NORMAL Altera_UP_SD_Card_Memory_Block.inc FALSE
-- Retrieval info: GEN_FILE: TYPE_NORMAL Altera_UP_SD_Card_Memory_Block.cmp TRUE
-- Retrieval info: GEN_FILE: TYPE_NORMAL Altera_UP_SD_Card_Memory_Block.bsf TRUE FALSE
-- Retrieval info: GEN_FILE: TYPE_NORMAL Altera_UP_SD_Card_Memory_Block_inst.vhd FALSE
-- Retrieval info: GEN_FILE: TYPE_NORMAL Altera_UP_SD_Card_Memory_Block_waveforms.html TRUE
-- Retrieval info: GEN_FILE: TYPE_NORMAL Altera_UP_SD_Card_Memory_Block_wave*.jpg FALSE
-- Retrieval info: LIB_FILE: altera_mf

View File

@ -1,308 +0,0 @@
-- (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 looks at the data on the CMD line and waits to receive a response.
-- It begins examining the data lines when the i_begin signal is asserted. It then
-- waits for a first '0'. It then proceeds to store as many bits as are required by
-- the response packet. Each message bit passes through the CRC7 circuit so that
-- the CRC check sum can be verified at the end of transmission. The circuit then produces
-- the o_data and o_CRC_passed outputs to indicate the message received and if the CRC
-- check passed.
--
-- If for some reason the requested response does not arrive within 56 clock cycles
-- then the circuit will produce a '1' on the o_timeout output. In such a case the
-- o_data should be ignored.
--
-- In case of a response that is not 001, 010, 011 or 110, the circuit expects
-- no response.
--
-- A signal o_done is asserted when the circuit has completed response retrieval. In
-- a case when a response is not expected, just wait for the CD Card to process the
-- command. This is done by waiting 8 (=PROCESSING_DELAY) clock cycles.
--
-- 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_Response_Receiver is
generic (
TIMEOUT : std_logic_vector(7 downto 0) := "00111000";
BUSY_WAIT : std_logic_vector(7 downto 0) := "00110000";
PROCESSING_DELAY : std_logic_vector(7 downto 0) := "00001000"
);
port
(
i_clock : in std_logic;
i_reset_n : in std_logic;
i_begin : in std_logic;
i_scan_pulse : in std_logic;
i_datain : in std_logic;
i_wait_cmd_busy : in std_logic;
i_response_type : in std_logic_vector(2 downto 0);
o_data : out std_logic_vector(127 downto 0);
o_CRC_passed : out std_logic;
o_timeout : out std_logic;
o_done : out std_logic
);
end entity;
architecture rtl of Altera_UP_SD_Card_Response_Receiver 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;
-- Build an enumerated type for the state machine. On reset always reset the DE2 and read the state
-- of the switches.
type state_type is (s_WAIT_BEGIN, s_WAIT_END, s_WAIT_PROCESSING_DELAY, s_WAIT_BUSY, s_WAIT_BUSY_END, s_WAIT_BEGIN_DEASSERT);
-- Register to hold the current state
signal current_state : state_type;
signal next_state : state_type;
-- Local wires
-- REGISTERED
signal registered_data_input : std_logic_vector(127 downto 0);
signal response_incoming : std_logic;
signal counter, timeout_counter : std_logic_vector(7 downto 0);
signal crc_shift, keep_reading_bits, shift_crc_bits : std_logic;
-- UNREGISTERED
signal limit, limit_minus_1 : std_logic_vector(7 downto 0);
signal check_crc : std_logic;
signal CRC_bits : std_logic_vector(6 downto 0);
signal start_reading_bits, operation_complete, enable_crc_unit : std_logic;
begin
-- Control FSM. Begin operation when i_begin is raised, then wait for the operation to end and i_begin to be deasserted.
state_regs: process(i_clock, i_reset_n)
begin
if (i_reset_n = '0') then
current_state <= s_WAIT_BEGIN;
elsif (rising_edge(i_clock)) then
current_state <= next_state;
end if;
end process;
state_transitions: process(current_state, i_begin, operation_complete, timeout_counter, i_wait_cmd_busy, i_scan_pulse, i_datain)
begin
case current_state is
when s_WAIT_BEGIN =>
if (i_begin = '1') then
next_state <= s_WAIT_END;
else
next_state <= s_WAIT_BEGIN;
end if;
when s_WAIT_END =>
if (operation_complete = '1') then
if (timeout_counter = TIMEOUT) then
next_state <= s_WAIT_BEGIN_DEASSERT;
else
next_state <= s_WAIT_PROCESSING_DELAY;
end if;
else
next_state <= s_WAIT_END;
end if;
when s_WAIT_PROCESSING_DELAY =>
if (timeout_counter = PROCESSING_DELAY) then
if (i_wait_cmd_busy = '1') then
next_state <= s_WAIT_BUSY;
else
next_state <= s_WAIT_BEGIN_DEASSERT;
end if;
else
next_state <= s_WAIT_PROCESSING_DELAY;
end if;
when s_WAIT_BUSY =>
if ((i_scan_pulse = '1') and (i_datain = '0')) then
next_state <= s_WAIT_BUSY_END;
else
if (timeout_counter = BUSY_WAIT) then
-- If the card did not become busy, then it would not have raised the optional busy signal.
-- In such a case, proceeed further as the command has finished correctly.
next_state <= s_WAIT_BEGIN_DEASSERT;
else
next_state <= s_WAIT_BUSY;
end if;
end if;
when s_WAIT_BUSY_END =>
if ((i_scan_pulse = '1') and (i_datain = '1')) then
next_state <= s_WAIT_BEGIN_DEASSERT;
else
next_state <= s_WAIT_BUSY_END;
end if;
when s_WAIT_BEGIN_DEASSERT =>
if (i_begin = '1') then
next_state <= s_WAIT_BEGIN_DEASSERT;
else
next_state <= s_WAIT_BEGIN;
end if;
when others =>
next_state <= s_WAIT_BEGIN;
end case;
end process;
-- Store the response as it appears on the i_datain line.
received_data_buffer: process (i_clock, i_reset_n)
begin
if (i_reset_n = '0') then
registered_data_input <= (OTHERS=>'0');
elsif (rising_edge(i_clock)) then
-- Only read new data and update the counter value when the scan pulse is high.
if (i_scan_pulse = '1') then
if ((start_reading_bits = '1') or (keep_reading_bits = '1')) then
registered_data_input(127 downto 1) <= registered_data_input(126 downto 0);
registered_data_input(0) <= i_datain;
end if;
end if;
end if;
end process;
-- Counter received bits
data_read_counter: process (i_clock, i_reset_n)
begin
if (i_reset_n = '0') then
counter <= (OTHERS=>'0');
elsif (rising_edge(i_clock)) then
-- Reset he counter every time you being reading the response.
if (current_state = s_WAIT_BEGIN) then
counter <= (OTHERS => '0');
end if;
-- Update the counter value when the scan pulse is high.
if (i_scan_pulse = '1') then
if ((start_reading_bits = '1') or (keep_reading_bits = '1')) then
counter <= counter + '1';
end if;
end if;
end if;
end process;
operation_complete <= '1' when (((counter = limit) and (not (limit = "00000000"))) or
(timeout_counter = TIMEOUT) or
((timeout_counter = PROCESSING_DELAY) and (limit = "00000000"))) else '0';
-- Count the number of scan pulses before the response is received. If the counter
-- exceeds TIMEOUT value, then an error must have occured when the SD card received a message.
timeout_counter_control: process (i_clock, i_reset_n)
begin
if (i_reset_n = '0') then
timeout_counter <= (OTHERS=>'0');
elsif (rising_edge(i_clock)) then
-- Reset the counter every time you begin reading the response.
if ((current_state = s_WAIT_BEGIN) or ((current_state = s_WAIT_END) and (operation_complete = '1') and (not (timeout_counter = TIMEOUT)))) then
timeout_counter <= (OTHERS => '0');
end if;
-- Update the counter value when the scan pulse is high.
if (i_scan_pulse = '1') then
if (((start_reading_bits = '0') and (keep_reading_bits = '0') and (current_state = s_WAIT_END) and (not (timeout_counter = TIMEOUT))) or
(current_state = s_WAIT_PROCESSING_DELAY) or (current_state = s_WAIT_BUSY)) then
timeout_counter <= timeout_counter + '1';
end if;
end if;
end if;
end process;
-- Enable data storing only after you see the first 0.
read_enable_logic: process (i_clock, i_reset_n)
begin
if (i_reset_n = '0') then
keep_reading_bits <= '0';
elsif (rising_edge(i_clock)) then
if (i_scan_pulse = '1') then
if ((start_reading_bits = '1') or ((keep_reading_bits = '1') and (not (counter = limit_minus_1)))) then
keep_reading_bits <= '1';
else
keep_reading_bits <= '0';
end if;
end if;
end if;
end process;
start_reading_bits <= '1' when ((current_state = s_WAIT_END) and (i_datain = '0') and
(counter = "00000000") and (not (limit = "00000000"))) else '0';
-- CRC7 checker.
crc_checker: Altera_UP_SD_CRC7_Generator PORT MAP
(
i_clock => i_clock,
i_reset_n => i_reset_n,
i_enable => enable_crc_unit,
i_shift => shift_crc_bits,
i_datain => registered_data_input(7),
o_crcout => CRC_bits
);
enable_crc_unit <= '1' when ((i_scan_pulse = '1') and (current_state = s_WAIT_END)) else '0';
-- Clear CRC7 registers before processing the response bits
crc_control_register: process (i_clock, i_reset_n)
begin
if (i_reset_n = '0') then
shift_crc_bits <= '1';
elsif (rising_edge(i_clock)) then
-- Reset he counter every time you being reading the response.
if (current_state = s_WAIT_BEGIN) then
-- clear the CRC7 contents before you process the next message.
shift_crc_bits <= '1';
end if;
-- Only read new data and update the counter value when the scan pulse is high.
if (i_scan_pulse = '1') then
if ((start_reading_bits = '1') or (keep_reading_bits = '1')) then
if (counter = "00000111") then
-- Once the 7-bits of the CRC checker have been cleared you can process the message and
-- compute its CRC bits to verify the validity of the transmission.
shift_crc_bits <= '0';
end if;
end if;
end if;
end if;
end process;
-- Indicate the number of bits to expect in the response packet.
limit <= "00110000" when ((i_response_type = "001") or
(i_response_type = "011") or
(i_response_type = "110")) else
"10001000" when (i_response_type = "010") else
"00000000"; -- No response
limit_minus_1 <=
"00101111" when ((i_response_type = "001") or
(i_response_type = "011") or
(i_response_type = "110")) else
"10000111" when (i_response_type = "010") else
"00000000"; -- No response
check_crc <= '1' when ((i_response_type = "001") or (i_response_type = "110")) else '0';
-- Generate Circuit outputs
o_data <= (registered_data_input(127 downto 1) & '1') when (i_response_type = "010") else
(CONV_STD_LOGIC_VECTOR(0, 96) & registered_data_input(39 downto 8));
o_CRC_passed <= '1' when ((check_crc = '0') or
((registered_data_input(0) = '1') and (CRC_bits = registered_data_input(7 downto 1)))) else '0';
o_timeout <= '1' when (timeout_counter = TIMEOUT) else '0';
o_done <= '1' when (current_state = s_WAIT_BEGIN_DEASSERT) else '0';
end rtl;

View File

@ -1,57 +0,0 @@
-- (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 generates a trigger pulse every time it sees a transition
-- from 0 to 1 on signal i_signal.
--
-- NOTES/REVISIONS:
---------------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity Altera_UP_SD_Signal_Trigger is
port
(
i_clock : in std_logic;
i_reset_n : in std_logic;
i_signal : in std_logic;
o_trigger : out std_logic
);
end entity;
architecture rtl of Altera_UP_SD_Signal_Trigger is
-- Local wires
-- REGISTERED
signal local_reg : std_logic;
begin
process (i_clock, i_reset_n)
begin
if (i_reset_n = '0') then
local_reg <= '0';
else
if (rising_edge(i_clock)) then
local_reg <= i_signal;
end if;
end if;
end process;
o_trigger <= '1' when ((local_reg = '0') and (i_signal = '1'))
else '0';
end rtl;