GSM给您一个能用SPI模式的SD读卡程序(VHDL)

[复制链接]
4034|8
 楼主| GoldSunMonkey 发表于 2012-8-21 22:46 | 显示全部楼层 |阅读模式
经测试能用,只是SPI的方式, 供大家使用。


  1. -- VHDL SD card interface
  2. -- by Steven J. Merrifield, June 2008

  3. -- Reads and writes a single block of data, and also writes continuous data
  4. -- Tested on Xilinx Spartan 3 hardware, using Transcend and SanDisk Ultra II cards
  5. -- Read states are derived from the Apple II emulator by Stephen Edwards

  6. library ieee;
  7. use ieee.std_logic_1164.all;
  8. use ieee.numeric_std.all;

  9. entity sd_controller is
  10. port (
  11.         cs : out std_logic;
  12.         mosi : out std_logic;
  13.         miso : in std_logic;
  14.         sclk : out std_logic;

  15.         rd : in std_logic;
  16.         wr : in std_logic;
  17.         dm_in : in std_logic;        -- data mode, 0 = write continuously, 1 = write single block
  18.         reset : in std_logic;
  19.         din : in std_logic_vector(7 downto 0);
  20.         dout : out std_logic_vector(7 downto 0);
  21.         clk : in std_logic        -- twice the SPI clk
  22. );

  23. end sd_controller;

  24. architecture rtl of sd_controller is
  25. type states is (
  26.         RST,
  27.         INIT,
  28.         CMD0,
  29.         CMD55,
  30.         CMD41,
  31.         POLL_CMD,
  32.   
  33.         IDLE,        -- wait for read or write pulse
  34.         READ_BLOCK,
  35.         READ_BLOCK_WAIT,
  36.         READ_BLOCK_DATA,
  37.         READ_BLOCK_CRC,
  38.         SEND_CMD,
  39.         RECEIVE_BYTE_WAIT,
  40.         RECEIVE_BYTE,
  41.         WRITE_BLOCK_CMD,
  42.         WRITE_BLOCK_INIT,                -- initialise write command
  43.         WRITE_BLOCK_DATA,                -- loop through all data bytes
  44.         WRITE_BLOCK_BYTE,                -- send one byte
  45.         WRITE_BLOCK_WAIT                -- wait until not busy
  46. );


  47. -- one start byte, plus 512 bytes of data, plus two FF end bytes (CRC)
  48. constant WRITE_DATA_SIZE : integer := 515;


  49. signal state, return_state : states;
  50. signal sclk_sig : std_logic := '0';
  51. signal cmd_out : std_logic_vector(55 downto 0);
  52. signal recv_data : std_logic_vector(7 downto 0);
  53. signal address : std_logic_vector(31 downto 0);
  54. signal cmd_mode : std_logic := '1';
  55. signal data_mode : std_logic := '1';
  56. signal response_mode : std_logic := '1';
  57. signal data_sig : std_logic_vector(7 downto 0) := x"00";

  58. begin
  59.   
  60.         process(clk,reset)
  61.                 variable byte_counter : integer range 0 to WRITE_DATA_SIZE;
  62.                 variable bit_counter : integer range 0 to 160;
  63.         begin
  64.                 data_mode <= dm_in;

  65.                 if rising_edge(clk) then
  66.                         if (reset='1') then
  67.                                 state <= RST;
  68.                                 sclk_sig <= '0';
  69.                         else
  70.                                 case state is
  71.                                
  72.                                 when RST =>
  73.                                         sclk_sig <= '0';
  74.                                         cmd_out <= (others => '1');
  75.                                         address <= x"00000000";
  76.                                         byte_counter := 0;
  77.                                         cmd_mode <= '1'; -- 0=data, 1=command
  78.                                         response_mode <= '1';        -- 0=data, 1=command
  79.                                         bit_counter := 160;
  80.                                         cs <= '1';
  81.                                         state <= INIT;
  82.                                
  83.                                 when INIT =>                -- CS=1, send 80 clocks, CS=0
  84.                                         if (bit_counter = 0) then
  85.                                                 cs <= '0';
  86.                                                 state <= CMD0;
  87.                                         else
  88.                                                 bit_counter := bit_counter - 1;
  89.                                                 sclk_sig <= not sclk_sig;
  90.                                         end if;       
  91.                                
  92.                                 when CMD0 =>
  93.                                         cmd_out <= x"FF400000000095";
  94.                                         bit_counter := 55;
  95.                                         return_state <= CMD55;
  96.                                         state <= SEND_CMD;

  97.                                 when CMD55 =>
  98.                                         cmd_out <= x"FF770000000001";        -- 55d OR 40h = 77h
  99.                                         bit_counter := 55;
  100.                                         return_state <= CMD41;
  101.                                         state <= SEND_CMD;
  102.                                
  103.                                 when CMD41 =>
  104.                                         cmd_out <= x"FF690000000001";        -- 41d OR 40h = 69h
  105.                                         bit_counter := 55;
  106.                                         return_state <= POLL_CMD;
  107.                                         state <= SEND_CMD;
  108.                        
  109.                                 when POLL_CMD =>
  110.                                         if (recv_data(0) = '0') then
  111.                                                 state <= IDLE;
  112.                                         else
  113.                                                 state <= CMD55;
  114.                                         end if;
  115.                
  116.                                 when IDLE =>
  117.                                         if (rd = '1') then
  118.                                                 state <= READ_BLOCK;
  119.                                         elsif (wr='1') then
  120.                                                 state <= WRITE_BLOCK_CMD;
  121.                                         else
  122.                                                 state <= IDLE;
  123.                                         end if;
  124.                                
  125.                                 when READ_BLOCK =>
  126.                                         cmd_out <= x"FF" & x"51" & address & x"FF";
  127.                                         bit_counter := 55;
  128.                                         return_state <= READ_BLOCK_WAIT;
  129.                                         state <= SEND_CMD;
  130.                                
  131.                                 when READ_BLOCK_WAIT =>
  132.                                         if (sclk_sig='1' and miso='0') then
  133.                                                 state <= READ_BLOCK_DATA;
  134.                                                 byte_counter := 511;
  135.                                                 bit_counter := 7;
  136.                                                 return_state <= READ_BLOCK_DATA;
  137.                                                 state <= RECEIVE_BYTE;
  138.                                         end if;
  139.                                         sclk_sig <= not sclk_sig;

  140.                                 when READ_BLOCK_DATA =>
  141.                                         if (byte_counter = 0) then
  142.                                                 bit_counter := 7;
  143.                                                 return_state <= READ_BLOCK_CRC;
  144.                                                 state <= RECEIVE_BYTE;
  145.                                         else
  146.                                                 byte_counter := byte_counter - 1;
  147.                                                 return_state <= READ_BLOCK_DATA;
  148.                                                 bit_counter := 7;
  149.                                                 state <= RECEIVE_BYTE;
  150.                                         end if;
  151.                        
  152.                                 when READ_BLOCK_CRC =>
  153.                                         bit_counter := 7;
  154.                                         return_state <= IDLE;
  155.                                         address <= std_logic_vector(unsigned(address) + x"200");
  156.                                         state <= RECEIVE_BYTE;
  157.                
  158.                                 when SEND_CMD =>
  159.                                         if (sclk_sig = '1') then
  160.                                                 if (bit_counter = 0) then
  161.                                                         state <= RECEIVE_BYTE_WAIT;
  162.                                                 else
  163.                                                         bit_counter := bit_counter - 1;
  164.                                                         cmd_out <= cmd_out(54 downto 0) & '1';
  165.                                                 end if;
  166.                                         end if;
  167.                                         sclk_sig <= not sclk_sig;
  168.                                
  169.                                 when RECEIVE_BYTE_WAIT =>
  170.                                         if (sclk_sig = '1') then
  171.                                                 if (miso = '0') then
  172.                                                         recv_data <= (others => '0');
  173.                                                         if (response_mode='0') then
  174.                                                                 bit_counter := 3; -- already read bits 7..4
  175.                                                         else
  176.                                                                 bit_counter := 6; -- already read bit 7
  177.                                                         end if;
  178.                                                         state <= RECEIVE_BYTE;
  179.                                                 end if;
  180.                                         end if;
  181.                                         sclk_sig <= not sclk_sig;

  182.                                 when RECEIVE_BYTE =>
  183.                                         if (sclk_sig = '1') then
  184.                                                 recv_data <= recv_data(6 downto 0) & miso;
  185.                                                 if (bit_counter = 0) then
  186.                                                         state <= return_state;
  187.                                                         dout <= recv_data(6 downto 0) & miso;
  188.                                                 else
  189.                                                         bit_counter := bit_counter - 1;
  190.                                                 end if;
  191.                                         end if;
  192.                                         sclk_sig <= not sclk_sig;

  193.                                 when WRITE_BLOCK_CMD =>
  194.                                         cmd_mode <= '1';
  195.                                         if (data_mode = '0') then
  196.                                                 cmd_out <= x"FF" & x"59" & address & x"FF";        -- continuous
  197.                                         else
  198.                                                 cmd_out <= x"FF" & x"58" & address & x"FF";        -- single block
  199.                                         end if;
  200.                                         bit_counter := 55;
  201.                                         return_state <= WRITE_BLOCK_INIT;
  202.                                         state <= SEND_CMD;
  203.                                        
  204.                                 when WRITE_BLOCK_INIT =>
  205.                                         cmd_mode <= '0';
  206.                                         byte_counter := WRITE_DATA_SIZE;
  207.                                         state <= WRITE_BLOCK_DATA;
  208.                                        
  209.                                 when WRITE_BLOCK_DATA =>
  210.                                         if byte_counter = 0 then
  211.                                                 state <= RECEIVE_BYTE_WAIT;
  212.                                                 return_state <= WRITE_BLOCK_WAIT;
  213.                                                 response_mode <= '0';
  214.                                         else        
  215.                                                 if ((byte_counter = 2) or (byte_counter = 1)) then
  216.                                                         data_sig <= x"FF"; -- two CRC bytes
  217.                                                 elsif byte_counter = WRITE_DATA_SIZE then
  218.                                                         if (data_mode='0') then
  219.                                                                 data_sig <= x"FC"; -- start byte, multiple blocks
  220.                                                         else
  221.                                                                 data_sig <= x"FE"; -- start byte, single block
  222.                                                         end if;
  223.                                                 else
  224.                                                         -- just a counter, get real data here
  225.                                                         data_sig <= std_logic_vector(to_unsigned(byte_counter,8));
  226.                                                 end if;
  227.                                                 bit_counter := 7;
  228.                                                 state <= WRITE_BLOCK_BYTE;
  229.                                                 byte_counter := byte_counter - 1;
  230.                                         end if;
  231.                                
  232.                                 when WRITE_BLOCK_BYTE =>
  233.                                         if (sclk_sig = '1') then
  234.                                                 if bit_counter=0 then
  235.                                                         state <= WRITE_BLOCK_DATA;
  236.                                                 else
  237.                                                         data_sig <= data_sig(6 downto 0) & '1';
  238.                                                         bit_counter := bit_counter - 1;
  239.                                                 end if;
  240.                                         end if;
  241.                                         sclk_sig <= not sclk_sig;
  242.                                        
  243.                                 when WRITE_BLOCK_WAIT =>
  244.                                         response_mode <= '1';
  245.                                         if sclk_sig='1' then
  246.                                                 if MISO='1' then
  247.                                                         if (data_mode='0') then
  248.                                                                 state <= WRITE_BLOCK_INIT;
  249.                                                         else
  250.                                                                 address <= std_logic_vector(unsigned(address) + x"200");
  251.                                                                 state <= IDLE;
  252.                                                         end if;
  253.                                                 end if;
  254.                                         end if;
  255.                                         sclk_sig <= not sclk_sig;

  256.                                 when others => state <= IDLE;
  257.         end case;
  258.       end if;
  259.     end if;
  260.   end process;

  261.   sclk <= sclk_sig;
  262.   mosi <= cmd_out(55) when cmd_mode='1' else data_sig(7);
  263.   
  264. end rtl;

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×

评分

参与人数 2威望 +6 收起 理由
星星之火红 + 5
shang651 + 1

查看全部评分

jakfens 发表于 2012-8-22 08:49 | 显示全部楼层
:lol能翻译为verilog么
jialio 发表于 2012-8-22 16:30 | 显示全部楼层
附件里面和这贴的是一样吗 hoho 就问问哈MRO
 楼主| GoldSunMonkey 发表于 2012-8-22 17:48 | 显示全部楼层
附件里面和这贴的是一样吗 hoho 就问问哈MRO
jialio 发表于 2012-8-22 16:30
一样的。
 楼主| GoldSunMonkey 发表于 2012-8-22 17:48 | 显示全部楼层
:lol能翻译为verilog么
jakfens 发表于 2012-8-22 08:49
哈哈,你翻译。我顶你的肺

评分

参与人数 1威望 +5 收起 理由
星星之火红 + 5

查看全部评分

jakfens 发表于 2012-8-23 08:45 | 显示全部楼层
哈哈,你翻译。我顶你的肺
GoldSunMonkey 发表于 2012-8-22 17:48
:funk:
 楼主| GoldSunMonkey 发表于 2012-8-23 10:05 | 显示全部楼层
千山万水js 发表于 2013-4-1 15:38 | 显示全部楼层
前段时间一直在做这个,最后用MB控制器做的。
ifpga 发表于 2013-4-1 15:41 | 显示全部楼层
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:                     2014, 追逐梦想

264

主题

17215

帖子

523

粉丝
快速回复 在线客服 返回列表 返回顶部