FPGA开发之SD驱动的资料汇总

来源:互联网 发布:java中文编译器 编辑:程序博客网 时间:2024/05/21 14:05

http://wenku.baidu.com/link?url=y0YBidh5Tz6u6-pUtZbNkcPUHEk6CUZQP_EwSXxXGxPbtd9mhJh94E7K0IOVAWVCeUX8PvPL7Bjq8Gn_b9lDDKI2Og7CQlaU5YMbaax7ij3

http://jinyong314.blog.163.com/blog/static/301657422010530112349686/

http://wenku.baidu.com/link?url=y0YBidh5Tz6u6-pUtZbNkcPUHEk6CUZQP_EwSXxXGxPbtd9mhJh94E7K0IOVAWVCeUX8PvPL7Bjq8Gn_b9lDDKI2Og7CQlaU5YMbaax7ij3

http://www.docin.com/p-455437652.html

http://wenku.baidu.com/link?url=QQbvBB6FE5d5DHLrB4rtVZwNDHSs0t4gD-t1Ey60PltrC47N2__4iQDs8_FPoHGQEcIFinpfG5L6wizTa6X0rXkB-XoIoV-bmOhj70Xq9iW

http://bbs.ednchina.com/BLOG_ARTICLE_235060_3.HTM

http://wenku.baidu.com/view/c2033f8271fe910ef12df869.html

http://wenku.baidu.com/view/c2033f8271fe910ef12df869.html

http://wenku.baidu.com/link?url=QDWh6vLcQ6DaEXPpaLhnguyCkqqV-_lGb2CThuStGj-aeoaarSS4RvFI4oRniUrwQNEcc-ITv-g2oFFOZQzE7R0rFeU3eAWiVJ-vv_BJwLG

http://wehat1148158886.blog.163.com/blog/static/181685163201122651357193/

VHDL实现代码:

-- VHDL SD card interface-- by Steven J. Merrifield, June 2008-- Reads and writes a single block of data, and also writes continuous data-- Tested on Xilinx Spartan 3 hardware, using Transcend and SanDisk Ultra II cards-- Read states are derived from the Apple II emulator by Stephen Edwards library ieee;use ieee.std_logic_1164.all;use ieee.numeric_std.all;entity sd_controller isport (cs : out std_logic;mosi : out std_logic;miso : in std_logic;sclk : out std_logic;rd : in std_logic;wr : in std_logic;dm_in : in std_logic;-- data mode, 0 = write continuously, 1 = write single blockreset : in std_logic;din : in std_logic_vector(7 downto 0);dout : out std_logic_vector(7 downto 0);clk : in std_logic-- twice the SPI clk);end sd_controller;architecture rtl of sd_controller istype states is (RST,INIT,CMD0,CMD55,CMD41,POLL_CMD,  IDLE,-- wait for read or write pulseREAD_BLOCK,READ_BLOCK_WAIT,READ_BLOCK_DATA,READ_BLOCK_CRC,SEND_CMD,RECEIVE_BYTE_WAIT,RECEIVE_BYTE,WRITE_BLOCK_CMD,WRITE_BLOCK_INIT,-- initialise write commandWRITE_BLOCK_DATA,-- loop through all data bytesWRITE_BLOCK_BYTE,-- send one byteWRITE_BLOCK_WAIT-- wait until not busy);-- one start byte, plus 512 bytes of data, plus two FF end bytes (CRC)constant WRITE_DATA_SIZE : integer := 515;signal state, return_state : states;signal sclk_sig : std_logic := '0';signal cmd_out : std_logic_vector(55 downto 0);signal recv_data : std_logic_vector(7 downto 0);signal address : std_logic_vector(31 downto 0);signal cmd_mode : std_logic := '1';signal data_mode : std_logic := '1';signal response_mode : std_logic := '1';signal data_sig : std_logic_vector(7 downto 0) := x"00";begin  process(clk,reset)variable byte_counter : integer range 0 to WRITE_DATA_SIZE;variable bit_counter : integer range 0 to 160;begindata_mode <= dm_in;if rising_edge(clk) thenif (reset='1') thenstate <= RST;sclk_sig <= '0';elsecase state iswhen RST =>sclk_sig <= '0';cmd_out <= (others => '1');address <= x"00000000";byte_counter := 0;cmd_mode <= '1'; -- 0=data, 1=commandresponse_mode <= '1';-- 0=data, 1=commandbit_counter := 160;cs <= '1';state <= INIT;when INIT =>-- CS=1, send 80 clocks, CS=0if (bit_counter = 0) thencs <= '0';state <= CMD0;elsebit_counter := bit_counter - 1;sclk_sig <= not sclk_sig;end if;when CMD0 =>cmd_out <= x"FF400000000095";bit_counter := 55;return_state <= CMD55;state <= SEND_CMD;when CMD55 =>cmd_out <= x"FF770000000001";-- 55d OR 40h = 77hbit_counter := 55;return_state <= CMD41;state <= SEND_CMD;when CMD41 =>cmd_out <= x"FF690000000001";-- 41d OR 40h = 69hbit_counter := 55;return_state <= POLL_CMD;state <= SEND_CMD;when POLL_CMD =>if (recv_data(0) = '0') thenstate <= IDLE;elsestate <= CMD55;end if;        when IDLE => if (rd = '1') thenstate <= READ_BLOCK;elsif (wr='1') thenstate <= WRITE_BLOCK_CMD;elsestate <= IDLE;end if;when READ_BLOCK =>cmd_out <= x"FF" & x"51" & address & x"FF";bit_counter := 55;return_state <= READ_BLOCK_WAIT;state <= SEND_CMD;when READ_BLOCK_WAIT =>if (sclk_sig='1' and miso='0') thenstate <= READ_BLOCK_DATA;byte_counter := 511;bit_counter := 7;return_state <= READ_BLOCK_DATA;state <= RECEIVE_BYTE;end if;sclk_sig <= not sclk_sig;when READ_BLOCK_DATA =>if (byte_counter = 0) thenbit_counter := 7;return_state <= READ_BLOCK_CRC;state <= RECEIVE_BYTE;elsebyte_counter := byte_counter - 1;return_state <= READ_BLOCK_DATA;bit_counter := 7;state <= RECEIVE_BYTE;end if;when READ_BLOCK_CRC =>bit_counter := 7;return_state <= IDLE;address <= std_logic_vector(unsigned(address) + x"200");state <= RECEIVE_BYTE;        when SEND_CMD =>if (sclk_sig = '1') thenif (bit_counter = 0) thenstate <= RECEIVE_BYTE_WAIT;elsebit_counter := bit_counter - 1;cmd_out <= cmd_out(54 downto 0) & '1';end if;end if;sclk_sig <= not sclk_sig;when RECEIVE_BYTE_WAIT =>if (sclk_sig = '1') thenif (miso = '0') thenrecv_data <= (others => '0');if (response_mode='0') thenbit_counter := 3; -- already read bits 7..4elsebit_counter := 6; -- already read bit 7end if;state <= RECEIVE_BYTE;end if;end if;sclk_sig <= not sclk_sig;when RECEIVE_BYTE =>if (sclk_sig = '1') thenrecv_data <= recv_data(6 downto 0) & miso;if (bit_counter = 0) thenstate <= return_state;dout <= recv_data(6 downto 0) & miso;elsebit_counter := bit_counter - 1;end if;end if;sclk_sig <= not sclk_sig;when WRITE_BLOCK_CMD =>cmd_mode <= '1';if (data_mode = '0') thencmd_out <= x"FF" & x"59" & address & x"FF";-- continuouselsecmd_out <= x"FF" & x"58" & address & x"FF";-- single blockend if;bit_counter := 55;return_state <= WRITE_BLOCK_INIT;state <= SEND_CMD;when WRITE_BLOCK_INIT => cmd_mode <= '0';byte_counter := WRITE_DATA_SIZE; state <= WRITE_BLOCK_DATA;when WRITE_BLOCK_DATA => if byte_counter = 0 thenstate <= RECEIVE_BYTE_WAIT;return_state <= WRITE_BLOCK_WAIT;response_mode <= '0';else if ((byte_counter = 2) or (byte_counter = 1)) thendata_sig <= x"FF"; -- two CRC byteselsif byte_counter = WRITE_DATA_SIZE thenif (data_mode='0') thendata_sig <= x"FC"; -- start byte, multiple blockselsedata_sig <= x"FE"; -- start byte, single blockend if;else-- just a counter, get real data heredata_sig <= std_logic_vector(to_unsigned(byte_counter,8));end if;bit_counter := 7;state <= WRITE_BLOCK_BYTE;byte_counter := byte_counter - 1;end if;when WRITE_BLOCK_BYTE => if (sclk_sig = '1') thenif bit_counter=0 thenstate <= WRITE_BLOCK_DATA;elsedata_sig <= data_sig(6 downto 0) & '1';bit_counter := bit_counter - 1;end if;end if;sclk_sig <= not sclk_sig;when WRITE_BLOCK_WAIT =>response_mode <= '1';if sclk_sig='1' thenif MISO='1' thenif (data_mode='0') thenstate <= WRITE_BLOCK_INIT;elseaddress <= std_logic_vector(unsigned(address) + x"200");state <= IDLE;end if;end if;end if;sclk_sig <= not sclk_sig;when others => state <= IDLE;        end case;      end if;    end if;  end process;  sclk <= sclk_sig;  mosi <= cmd_out(55) when cmd_mode='1' else data_sig(7);  end rtl;


0 0