Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

SPI MOSI phase #1

Open
wants to merge 2 commits into from

1 participant

@kkomnisys

fixed the alignment of data on MOSI for all SPI modes.

Needs to be merged with the regular SPI block

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Oct 10, 2013
  1. @kkomnisys
Commits on Feb 10, 2014
  1. @kkomnisys

    Fixed phase of data on MOSI

    kkomnisys authored
This page is out of date. Refresh to see the latest.
View
2  zpu/hdl/zpuino/boards/papilio-pro/S6LX9/variants/retrocade/papilio_pro_top.vhd
@@ -858,7 +858,7 @@ begin
-- IO SLOT 6
--
- slot1: zpuino_spi
+ slot1: zpuino_spi2
port map (
wb_clk_i => wb_clk_i,
wb_rst_i => wb_rst_i,
View
195 zpu/hdl/zpuino/spi2.vhd
@@ -0,0 +1,195 @@
+--
+-- SPI interface
+--
+-- Copyright 2010 Alvaro Lopes <alvieboy@alvie.com>
+--
+-- Version: 1.0
+--
+-- The FreeBSD license
+--
+-- Redistribution and use in source and binary forms, with or without
+-- modification, are permitted provided that the following conditions
+-- are met:
+--
+-- 1. Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+-- 2. Redistributions in binary form must reproduce the above
+-- copyright notice, this list of conditions and the following
+-- disclaimer in the documentation and/or other materials
+-- provided with the distribution.
+--
+-- THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY
+-- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+-- PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+-- ZPU PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+-- INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+-- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+-- OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+-- HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+-- STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+-- ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+--
+--
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+entity spi2 is
+ port (
+ clk : in std_logic;
+ rst : in std_logic;
+ din : in std_logic_vector(31 downto 0);
+ dout : out std_logic_vector(31 downto 0);
+ en : in std_logic;
+ ready : out std_logic;
+ transfersize: in std_logic_vector(1 downto 0);
+
+ miso : in std_logic;
+ mosi : out std_logic;
+
+ clk_en : out std_logic;
+
+ clkrise : in std_logic;
+ clkfall : in std_logic;
+ samprise : in std_logic -- Sample on rising edge, shift data on falling edge
+);
+end entity spi2;
+
+
+architecture behave of spi2 is
+
+signal read_reg_q : std_logic_vector(31 downto 0);
+signal write_reg_q : std_logic_vector(31 downto 0);
+
+signal ready_q : std_logic;
+signal count : integer range 0 to 32;
+--signal count_val_q: integer range 0 to 32;
+
+signal sample_event : std_logic;
+signal do_shift : std_logic;
+signal ignore_sample_q : std_logic;
+
+begin
+
+dout <= read_reg_q;
+
+process(samprise,clkrise,clkfall)
+begin
+ sample_event <= '0';
+ if (clkfall = '1' and samprise = '0') then
+ sample_event <= '1';
+ elsif (clkrise = '1' and samprise='1') then
+ sample_event <= '1';
+ end if;
+end process;
+
+process(ready_q, en)
+begin
+ ready <= ready_q;
+end process;
+
+process(ready_q, clkrise, clkfall, samprise, en)
+begin
+ if ready_q = '0' and samprise = '0' and clkrise = '1' then
+ do_shift <= '1';
+ elsif ready_q = '0' and samprise = '1' and clkfall = '1' then
+ do_shift <= '1';
+ else
+ do_shift<='0';
+ end if;
+end process;
+
+process(clk)
+begin
+ if rising_edge(clk) then
+ if do_shift = '1' then
+ case transfersize is
+ when "00" =>
+ MOSI <= write_reg_q(7); -- 8-bit write
+ when "01" =>
+ MOSI <= write_reg_q(15); -- 16-bit write
+ when "10" =>
+ MOSI <= write_reg_q(23); -- 24-bit write
+ when "11" =>
+ MOSI <= write_reg_q(31); -- 32-bit write
+ when others => NULL;
+ end case;
+ end if;
+ end if;
+end process;
+
+process(ready_q, clkrise, clkfall, count)
+begin
+ if ready_q = '1' then
+ clk_en <= '0';
+ else
+ if count/=0 then
+ clk_en <= '1';
+ else
+ if samprise = '0' then
+ clk_en <= not clkrise;
+ elsif samprise = '1' then
+ clk_en <= not clkfall;
+ end if;
+ end if;
+ end if;
+end process;
+
+process(clk)
+begin
+ if rising_edge(clk) then
+ if rst='1' then
+ ready_q <= '1';
+ count <= 0;
+ else
+ if ready_q = '1' then
+ if en = '1' then
+ ready_q <= '0';
+ write_reg_q <= din(31 downto 0);
+ ignore_sample_q <= not samprise;
+
+ -- Shift the 32-bit register
+ case transfersize is
+ when "00" =>
+ count <= 8;
+ when "01" =>
+ count <= 16;
+ when "10" =>
+ count <= 24;
+ when "11" =>
+ count <= 32;
+ when others => NULL;
+ end case;
+
+ end if;
+ else
+
+ if count/=0 then
+ if do_shift = '1' then
+ count <= count - 1;
+ end if;
+ else
+ if clkrise = '1' and ready_q = '0' and samprise = '0' then
+ ready_q <= '1';
+ elsif clkfall = '1' and ready_q = '0' and samprise = '1' then
+ ready_q <= '1';
+ end if;
+ end if;
+ end if;
+
+ if ready_q = '0' and sample_event = '1' then
+ ignore_sample_q <= '0';
+
+ if ignore_sample_q = '0' then
+ write_reg_q(31 downto 0) <= write_reg_q(30 downto 0) & '0';
+ read_reg_q(31 downto 0) <= read_reg_q(30 downto 0) & MISO;
+ end if;
+ end if;
+
+ end if;
+ end if;
+end process;
+
+end behave;
View
170 zpu/hdl/zpuino/spiclkgen2.vhd
@@ -0,0 +1,170 @@
+--
+-- SPI Clock generator
+--
+-- Copyright 2010 Alvaro Lopes <alvieboy@alvie.com>
+--
+-- Version: 1.0
+--
+-- The FreeBSD license
+--
+-- Redistribution and use in source and binary forms, with or without
+-- modification, are permitted provided that the following conditions
+-- are met:
+--
+-- 1. Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+-- 2. Redistributions in binary form must reproduce the above
+-- copyright notice, this list of conditions and the following
+-- disclaimer in the documentation and/or other materials
+-- provided with the distribution.
+--
+-- THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY
+-- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+-- PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+-- ZPU PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+-- INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+-- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+-- OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+-- HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+-- STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+-- ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+--
+--
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+entity spiclkgen2 is
+ port (
+ clk: in std_logic;
+ rst: in std_logic;
+ en: in std_logic;
+ cpol: in std_logic;
+ pres: in std_logic_vector(2 downto 0);
+
+ clkrise: out std_logic;
+ clkfall: out std_logic;
+ spiclk: out std_logic
+
+ );
+end entity spiclkgen2;
+
+
+
+architecture behave of spiclkgen2 is
+
+signal running_q: std_logic;
+signal clkrise_i: std_logic;
+signal clkfall_i: std_logic;
+
+component prescaler is
+ port (
+ clk: in std_logic;
+ rst: in std_logic;
+ prescale: in std_logic_vector(2 downto 0);
+ event: out std_logic
+ );
+end component prescaler;
+
+
+signal prescale_q: std_logic_vector(2 downto 0);
+signal clk_i: std_logic;
+signal prescale_event: std_logic;
+signal prescale_reset: std_logic;
+signal enq : std_logic;
+
+begin
+
+clkrise <= clkrise_i;
+clkfall <= clkfall_i;
+
+pr: prescaler
+ port map (
+ clk => clk,
+ rst => prescale_reset,
+ prescale => prescale_q,
+ event => prescale_event
+ );
+
+
+genclk: process(clk)
+begin
+ if rising_edge(clk) then
+ if rst='1' or en='0' then
+ spiclk <= cpol;
+ else
+
+ if clkrise_i='1' then
+ spiclk<=not cpol;
+ end if;
+
+ if clkfall_i='1' then
+ spiclk<=cpol;
+ end if;
+
+ end if;
+ end if;
+end process;
+
+
+process(clk)
+begin
+ if rising_edge(clk) then
+ enq <= en;
+
+ if rst='1' then
+ prescale_q <= (others => '0');
+ running_q <= '0';
+ prescale_reset <= '0';
+ else
+ if en='1' then
+ prescale_reset<='0';
+ running_q <= '1';
+
+ if running_q='0' then
+ prescale_q <= pres;
+ prescale_reset<='1';
+ end if;
+
+ else
+ running_q <= '0';
+ end if;
+ end if;
+ end if;
+end process;
+
+process(clk)
+begin
+ if rising_edge(clk) then
+ if rst='1' then
+ clkrise_i<='0';
+ clkfall_i<='0';
+ clk_i<='0';
+ else
+ clkrise_i <= '0';
+ clkfall_i <= '0';
+
+ if en = '1' and enq = '0' then
+ clkfall_i <= '1';
+ end if;
+
+ if running_q='1' and en='1' then
+ if prescale_event='1' then
+ clk_i <= not clk_i;
+ if clk_i='0' then
+ clkrise_i <= '1';
+ else
+ clkfall_i <= '1';
+ end if;
+ end if;
+ else
+ clk_i <= '0';
+ end if;
+ end if;
+ end if;
+end process;
+
+end behave;
View
261 zpu/hdl/zpuino/zpuino_spi2.vhd
@@ -0,0 +1,261 @@
+--
+-- SPI interface for ZPUINO
+--
+-- Copyright 2010 Alvaro Lopes <alvieboy@alvie.com>
+--
+-- Version: 1.0
+--
+-- The FreeBSD license
+--
+-- Redistribution and use in source and binary forms, with or without
+-- modification, are permitted provided that the following conditions
+-- are met:
+--
+-- 1. Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+-- 2. Redistributions in binary form must reproduce the above
+-- copyright notice, this list of conditions and the following
+-- disclaimer in the documentation and/or other materials
+-- provided with the distribution.
+--
+-- THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY
+-- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+-- PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+-- ZPU PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+-- INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+-- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+-- OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+-- HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+-- STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+-- ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+--
+--
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+library work;
+use work.zpu_config.all;
+use work.zpuino_config.all;
+use work.zpupkg.all;
+use work.zpuinopkg.all;
+
+entity zpuino_spi2 is
+ port (
+ wb_clk_i: in std_logic;
+ wb_rst_i: in std_logic;
+ wb_dat_o: out std_logic_vector(wordSize-1 downto 0);
+ wb_dat_i: in std_logic_vector(wordSize-1 downto 0);
+ wb_adr_i: in std_logic_vector(maxIObit downto minIObit);
+ wb_we_i: in std_logic;
+ wb_cyc_i: in std_logic;
+ wb_stb_i: in std_logic;
+ wb_ack_o: out std_logic;
+ wb_inta_o:out std_logic;
+
+ mosi: out std_logic;
+ miso: in std_logic;
+ sck: out std_logic;
+ enabled: out std_logic
+ );
+end entity zpuino_spi2;
+
+architecture behave of zpuino_spi2 is
+
+
+ component spi2 is
+ port (
+ clk: in std_logic;
+ rst: in std_logic;
+ din: in std_logic_vector(31 downto 0);
+ dout: out std_logic_vector(31 downto 0);
+ en: in std_logic;
+ ready: out std_logic;
+ transfersize: in std_logic_vector(1 downto 0);
+
+ miso: in std_logic;
+ mosi: out std_logic;
+
+ clk_en: out std_logic;
+
+ clkrise: in std_logic;
+ clkfall: in std_logic;
+ samprise:in std_logic
+ );
+ end component spi2;
+
+ component spiclkgen2 is
+ port (
+ clk: in std_logic;
+ rst: in std_logic;
+ en: in std_logic;
+ cpol: in std_logic;
+ pres: in std_logic_vector(2 downto 0);
+
+ clkrise: out std_logic;
+ clkfall: out std_logic;
+ spiclk: out std_logic
+ );
+ end component spiclkgen2;
+
+ signal spi_read: std_logic_vector(31 downto 0);
+ signal spi_en: std_logic;
+ signal spi_ready: std_logic;
+ signal spi_clk_en: std_logic;
+ signal spi_clkrise: std_logic;
+ signal spi_clkfall: std_logic;
+ signal spi_clk_pres: std_logic_vector(2 downto 0);
+ signal spi_samprise: std_logic;
+ signal spi_enable_q: std_logic;
+ signal spi_txblock_q: std_logic;
+ signal cpol: std_logic;
+ signal miso_i: std_logic;
+ signal spi_transfersize_q: std_logic_vector(1 downto 0);
+ signal trans: std_logic;
+begin
+
+ zspi: spi2
+ port map (
+ clk => wb_clk_i,
+ rst => wb_rst_i,
+ din => wb_dat_i,
+ dout => spi_read,
+ en => spi_en,
+ ready => spi_ready,
+ transfersize => spi_transfersize_q,
+
+ miso => miso_i,
+ mosi => mosi,
+
+ clk_en => spi_clk_en,
+
+ clkrise => spi_clkrise,
+ clkfall => spi_clkfall,
+ samprise => spi_samprise
+ );
+
+ zspiclk: spiclkgen2
+ port map (
+ clk => wb_clk_i,
+ rst => wb_rst_i,
+ en => spi_clk_en,
+ pres => spi_clk_pres,
+ clkrise => spi_clkrise,
+ clkfall => spi_clkfall,
+ spiclk => sck,
+ cpol => cpol
+ );
+
+ -- Simulation only
+ miso_i <= '0' when miso='Z' else miso;
+
+ -- Direct access (write) to SPI
+
+ --spi_en <= '1' when (wb_cyc_i='1' and wb_stb_i='1' and wb_we_i='1') and wb_adr_i(2)='1' and spi_ready='1' else '0';
+
+ busygen: if zpuino_spiblocking=true generate
+
+ process(wb_clk_i)
+ begin
+ if rising_edge(wb_clk_i) then
+ if wb_rst_i='1' then
+
+ wb_ack_o <= '0';
+ spi_en <= '0';
+ trans <= '0';
+
+ else
+ wb_ack_o <= '0';
+ spi_en <= '0';
+ trans <='0';
+ if trans='0' then
+ if (wb_cyc_i='1' and wb_stb_i='1') then
+ if wb_adr_i(2)='1' then
+ if spi_txblock_q='1' then
+ if spi_ready='1' then
+ if wb_we_i='1' then
+ spi_en <= '1';
+ spi_transfersize_q <= wb_adr_i(4 downto 3);
+ end if;
+ wb_ack_o <= '1';
+ trans <= '1';
+ end if;
+ else
+ if wb_we_i='1' then
+ spi_en <= '1';
+ spi_transfersize_q <= wb_adr_i(4 downto 3);
+ end if;
+ trans <= '1';
+ wb_ack_o <= '1';
+ end if;
+ else
+ trans <= '1';
+ wb_ack_o <= '1';
+ end if;
+ end if;
+ end if;
+ end if;
+ end if;
+ end process;
+ --busy <= '1' when address(2)='1' and (we='1' or re='1') and spi_ready='0' and spi_txblock_q='1' else '0';
+
+ end generate;
+
+ nobusygen: if zpuino_spiblocking=false generate
+ --busy <= '0';
+ spi_en <= '1' when (wb_cyc_i='1' and wb_stb_i='1' and wb_we_i='1') and wb_adr_i(2)='1' and spi_ready='1' else '0';
+ wb_ack_o <= wb_cyc_i and wb_stb_i;
+ end generate;
+
+
+
+ wb_inta_o <= '0';
+ enabled <= spi_enable_q;
+
+ -- Prescaler write
+
+ process(wb_clk_i)
+ begin
+ if rising_edge(wb_clk_i) then
+ if wb_rst_i='1' then
+ spi_enable_q<='0';
+ spi_txblock_q<='1';
+ --spi_transfersize_q<=(others => '0');
+ else
+ if wb_cyc_i='1' and wb_stb_i='1' and wb_we_i='1' then
+ if wb_adr_i(2)='0' then
+ spi_clk_pres <= wb_dat_i(3 downto 1);
+ cpol <= wb_dat_i(4);
+ spi_samprise <= wb_dat_i(5);
+ spi_enable_q <= wb_dat_i(6);
+ spi_txblock_q <= wb_dat_i(7);
+ --spi_transfersize_q <= wb_dat_i(9 downto 8);
+ end if;
+ end if;
+ end if;
+ end if;
+ end process;
+
+ process(wb_adr_i, spi_ready, spi_read, spi_clk_pres,cpol,spi_samprise,spi_enable_q,spi_txblock_q,spi_transfersize_q)
+ begin
+ wb_dat_o <= (others =>Undefined);
+ case wb_adr_i(2) is
+ when '0' =>
+ wb_dat_o(0) <= spi_ready;
+ wb_dat_o(3 downto 1) <= spi_clk_pres;
+ wb_dat_o(4) <= cpol;
+ wb_dat_o(5) <= spi_samprise;
+ wb_dat_o(6) <= spi_enable_q;
+ wb_dat_o(7) <= spi_txblock_q;
+ wb_dat_o(9 downto 8) <= spi_transfersize_q;
+ when '1' =>
+ wb_dat_o <= spi_read;
+ when others =>
+ wb_dat_o <= (others => DontCareValue);
+ end case;
+ end process;
+
+end behave;
+
View
21 zpu/hdl/zpuino/zpuinopkg.vhd
@@ -207,6 +207,27 @@ package zpuinopkg is
);
end component zpuino_spi;
+ component zpuino_spi2 is
+ port (
+ wb_clk_i: in std_logic;
+ wb_rst_i: in std_logic;
+ wb_dat_o: out std_logic_vector(wordSize-1 downto 0);
+ wb_dat_i: in std_logic_vector(wordSize-1 downto 0);
+ wb_adr_i: in std_logic_vector(maxIObit downto minIObit);
+ wb_we_i: in std_logic;
+ wb_cyc_i: in std_logic;
+ wb_stb_i: in std_logic;
+ wb_ack_o: out std_logic;
+ wb_inta_o:out std_logic;
+
+ mosi: out std_logic;
+ miso: in std_logic;
+ sck: out std_logic;
+
+ enabled: out std_logic
+ );
+ end component zpuino_spi2;
+
component zpuino_uart is
generic (
bits: integer := 11
Something went wrong with that request. Please try again.