zoukankan      html  css  js  c++  java
  • spi master vhdl

      1 http://eewiki.net/display/LOGIC/Serial+Peripheral+Interface+(SPI)+Master+(VHDL)
      2 
      3 --------------------------------------------------------------------------------
      4 --
      5 --   FileName:         spi_master.vhd
      6 --   Dependencies:     none
      7 --   Design Software:  Quartus II Version 9.0 Build 132 SJ Full Version
      8 --
      9 --   HDL CODE IS PROVIDED "AS IS."  DIGI-KEY EXPRESSLY DISCLAIMS ANY
     10 --   WARRANTY OF ANY KIND, WHETHER EXPRESS OR IMPLIED, INCLUDING BUT NOT
     11 --   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
     12 --   PARTICULAR PURPOSE, OR NON-INFRINGEMENT. IN NO EVENT SHALL DIGI-KEY
     13 --   BE LIABLE FOR ANY INCIDENTAL, SPECIAL, INDIRECT OR CONSEQUENTIAL
     14 --   DAMAGES, LOST PROFITS OR LOST DATA, HARM TO YOUR EQUIPMENT, COST OF
     15 --   PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY OR SERVICES, ANY CLAIMS
     16 --   BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF),
     17 --   ANY CLAIMS FOR INDEMNITY OR CONTRIBUTION, OR OTHER SIMILAR COSTS.
     18 --
     19 --   Version History
     20 --   Version 1.0 7/23/2010 Scott Larson
     21 --     Initial Public Release
     22 --    
     23 --------------------------------------------------------------------------------
     24 
     25 library ieee;
     26 use ieee.std_logic_1164.all;
     27 use ieee.std_logic_arith.all;
     28 use ieee.std_logic_unsigned.all;
     29 
     30 entity spi_master is
     31   generic(
     32     slaves  : INTEGER := 8;  --number of spi slaves
     33     d_width : INTEGER := 8); --data bus width
     34   port(
     35     clock   : in     STD_LOGIC;                             --system clock
     36     reset_n : in     STD_LOGIC;                             --asynchronous reset
     37     enable  : in     STD_LOGIC;                             --initiate transaction
     38     cpol    : in     STD_LOGIC;                             --spi clock polarity
     39     cpha    : in     STD_LOGIC;                             --spi clock phase
     40     cont    : in     STD_LOGIC;                             --continuous mode command
     41     clk_div : in     INTEGER;                               --system clock cycles per 1/2 period of sclk
     42     addr    : in     INTEGER;                               --address of slave
     43     tx_data : in     STD_LOGIC_VECTOR(d_width-1 downto 0);  --data to transmit
     44     miso    : in     STD_LOGIC;                             --master in, slave out
     45     sclk    : buffer STD_LOGIC;                             --spi clock
     46     ss_n    : buffer STD_LOGIC_VECTOR(slaves-1 downto 0);   --slave select
     47     mosi    : out    STD_LOGIC;                             --master out, slave in
     48     busy    : out    STD_LOGIC;                             --busy / data ready signal
     49     rx_data : out    STD_LOGIC_VECTOR(d_width-1 downto 0)); --data received
     50 end spi_master;
     51 
     52 architecture logic of spi_master is
     53   type machine is(ready, execute);                           --state machine data type
     54   signal state       : machine;                              --current state
     55   signal slave       : INTEGER;                              --slave selected for current transaction
     56   signal clk_ratio   : INTEGER;                              --current clk_div
     57   signal count       : INTEGER;                              --counter to trigger sclk from system clock
     58   signal clk_toggles : INTEGER range 0 to d_width*2 + 1;     --count spi clock toggles
     59   signal assert_data : STD_LOGIC;                            --'1' is tx sclk toggle, '0' is rx sclk toggle
     60   signal continue    : STD_LOGIC;                            --flag to continue transaction
     61   signal rx_buffer   : STD_LOGIC_VECTOR(d_width-1 downto 0); --receive data buffer
     62   signal tx_buffer   : STD_LOGIC_VECTOR(d_width-1 downto 0); --transmit data buffer
     63   signal last_bit_rx : INTEGER range 0 to d_width*2;         --last rx data bit location
     64 begin
     65   process(clock, reset_n)
     66   begin
     67 
     68     if(reset_n = '0') then        --reset system
     69       busy    <= '1';                --set busy signal
     70       ss_n    <= (others => '1');    --deassert all slave select lines
     71       mosi    <= 'Z';                --set master out to high impedance
     72       rx_data <= (others => '0'); --clear receive data port
     73       state   <= ready;             --go to ready state when reset is exited
     74 
     75     elsif(clock'EVENT and clock = '1') then
     76       case state is               --state machine
     77 
     78         when ready =>
     79           busy     <= '0';             --clock out not busy signal
     80           ss_n     <= (others => '1'); --set all slave select outputs high
     81           mosi     <= 'Z';             --set mosi output high impedance
     82           continue <= '0';         --clear continue flag
     83 
     84           --user input to initiate transaction
     85           if(enable = '1') then
     86             busy <= '1';             --set busy signal
     87             if(addr < slaves) then   --check for valid slave address
     88               slave <= addr;         --clock in current slave selection if valid
     89             else
     90               slave <= 0;            --set to first slave if not valid
     91             end if;
     92             if(clk_div = 0) then     --check for valid spi speed
     93               clk_ratio <= 1;        --set to maximum speed if zero
     94               count     <= 1;            --initiate system-to-spi clock counter
     95             else
     96               clk_ratio <= clk_div;  --set to input selection if valid
     97               count     <= clk_div;      --initiate system-to-spi clock counter
     98             end if;
     99             sclk        <= cpol;            --set spi clock polarity
    100             assert_data <= not cpha; --set spi clock phase
    101             tx_buffer   <= tx_data;    --clock in data for transmit into buffer
    102             clk_toggles <= 0;        --initiate clock toggle counter
    103             last_bit_rx <= d_width*2 + conv_integer(cpha) - 1; --set last rx data bit
    104             state       <= execute;        --proceed to execute state
    105           else
    106             state <= ready;          --remain in ready state
    107           end if;
    108 
    109         when execute =>
    110           busy        <= '1';        --set busy signal
    111           ss_n(slave) <= '0'; --set proper slave select output
    112 
    113           --system clock to sclk ratio is met
    114           if(count = clk_ratio) then
    115             count       <= 1;                     --reset system-to-spi clock counter
    116             assert_data <= not assert_data; --switch transmit/receive indicator
    117             clk_toggles <= clk_toggles + 1; --increment spi clock toggles counter
    118 
    119             --spi clock toggle needed
    120             if(clk_toggles <= d_width*2 and ss_n(slave) = '0') then
    121               sclk <= not sclk; --toggle spi clock
    122             end if;
    123 
    124             --receive spi clock toggle
    125             if(assert_data = '0' and clk_toggles < last_bit_rx + 1 and ss_n(slave) = '0') then
    126               rx_buffer <= rx_buffer(d_width-2 downto 0) & miso; --shift in received bit
    127             end if;
    128 
    129             --transmit spi clock toggle
    130             if(assert_data = '1' and clk_toggles < last_bit_rx) then
    131               mosi      <= tx_buffer(d_width-1);                     --clock out data bit
    132               tx_buffer <= tx_buffer(d_width-2 downto 0) & '0'; --shift data transmit buffer
    133             end if;
    134 
    135             --last data receive, but continue
    136             if(clk_toggles = last_bit_rx and cont = '1') then
    137               tx_buffer   <= tx_data;                       --reload transmit buffer
    138               clk_toggles <= last_bit_rx - d_width*2 + 1; --reset spi clock toggle counter
    139               continue    <= '1';                            --set continue flag
    140             end if;
    141 
    142             --normal end of transaction, but continue
    143             if(continue = '1') then
    144               continue <= '0';      --clear continue flag
    145               busy     <= '0';          --clock out signal that first receive data is ready
    146               rx_data  <= rx_buffer; --clock out received data to output port
    147             end if;
    148 
    149             --end of transaction
    150             if((clk_toggles = d_width*2 + 1) and cont = '0') then
    151               busy    <= '0';             --clock out not busy signal
    152               ss_n    <= (others => '1'); --set all slave selects high
    153               mosi    <= 'Z';             --set mosi output high impedance
    154               rx_data <= rx_buffer;    --clock out received data to output port
    155               state   <= ready;          --return to ready state
    156             else                       --not end of transaction
    157               state <= execute;        --remain in execute state
    158             end if;
    159 
    160           else        --system clock to sclk ratio not met
    161             count <= count + 1; --increment counter
    162             state <= execute;   --remain in execute state
    163           end if;
    164 
    165       end case;
    166     end if;
    167   end process;
    168 end logic;

  • 相关阅读:
    Java [leetcode 36]Valid Sudoku
    Java [leetcode 35]Search Insert Position
    java中正则表达式
    Java [leetcode 34]Search for a Range
    SSRS表达式里引用.net dll
    一个简单的批处理
    .NET大批量插入数据到Oracle
    AX2009里调用.NET DLL的效率问题
    生成折扣日记账
    python's twelth day for me
  • 原文地址:https://www.cnblogs.com/shangdawei/p/2498945.html
Copyright © 2011-2022 走看看