mirror of
https://github.com/stnolting/neorv32.git
synced 2025-04-24 22:27:21 -04:00
Merge pull request #336 from stnolting/fix_spi_phase_offset
🐛 fix SPI & XIP clock phase offset
This commit is contained in:
commit
6a412d6ee4
4 changed files with 24 additions and 16 deletions
|
@ -32,6 +32,7 @@ mimpid = 0x01040312 => 01.04.03.12 => Version 01.04.03.12 => v1.4.3.12
|
|||
|
||||
| Date (*dd.mm.yyyy*) | Version | Comment |
|
||||
|:----------:|:-------:|:--------|
|
||||
| 04.06.2022 | 1.7.2.3 | :bug: fixed bug in **SPI** and **XIP** modules: phase offset between SPI clock and SPI data; [#336](https://github.com/stnolting/neorv32/pull/336) |
|
||||
| 03.06.2022 | 1.7.2.2 | :sparkles: (finally) added a **dedicated hardware reset** to all IO/peripheral devices; [#334](https://github.com/stnolting/neorv32/pull/334) |
|
||||
| 02.06.2022 | 1.7.2.1 | :sparkles: add **watchdog** pause flag to stop watchdog timeout counter when CPU is in sleep mode; [#331](https://github.com/stnolting/neorv32/pull/331) |
|
||||
| 02.06.2022 | [**:rocket:1.7.2**](https://github.com/stnolting/neorv32/releases/tag/v1.7.2) | **New release** |
|
||||
|
|
|
@ -68,7 +68,7 @@ package neorv32_package is
|
|||
-- Architecture Constants (do not modify!) ------------------------------------------------
|
||||
-- -------------------------------------------------------------------------------------------
|
||||
constant data_width_c : natural := 32; -- native data path width - do not change!
|
||||
constant hw_version_c : std_ulogic_vector(31 downto 0) := x"01070202"; -- NEORV32 version - no touchy!
|
||||
constant hw_version_c : std_ulogic_vector(31 downto 0) := x"01070203"; -- NEORV32 version - no touchy!
|
||||
constant archid_c : natural := 19; -- official NEORV32 architecture ID - hands off!
|
||||
|
||||
-- Check if we're inside the Matrix -------------------------------------------------------
|
||||
|
|
|
@ -223,12 +223,8 @@ begin
|
|||
spi_rtx_unit: process(clk_i)
|
||||
begin
|
||||
if rising_edge(clk_i) then
|
||||
-- input (sdi) synchronizer --
|
||||
rtx_engine.sdi_sync <= spi_sdi_i;
|
||||
|
||||
-- defaults --
|
||||
spi_sck_o <= ctrl(ctrl_cpol_c);
|
||||
irq_o <= '0';
|
||||
irq_o <= '0';
|
||||
|
||||
-- serial engine --
|
||||
rtx_engine.state(2) <= ctrl(ctrl_en_c);
|
||||
|
@ -236,6 +232,7 @@ begin
|
|||
|
||||
when "100" => -- enabled but idle, waiting for new transmission trigger
|
||||
-- ------------------------------------------------------------
|
||||
spi_sck_o <= ctrl(ctrl_cpol_c);
|
||||
rtx_engine.bitcnt <= (others => '0');
|
||||
if (rtx_engine.start = '1') then -- trigger new transmission
|
||||
rtx_engine.sreg <= data_i;
|
||||
|
@ -245,32 +242,38 @@ begin
|
|||
when "101" => -- start with next new clock pulse
|
||||
-- ------------------------------------------------------------
|
||||
if (spi_clk_en = '1') then
|
||||
if (ctrl(ctrl_cpha_c) = '1') then -- clock phase shift
|
||||
spi_sck_o <= not ctrl(ctrl_cpol_c);
|
||||
end if;
|
||||
rtx_engine.state(1 downto 0) <= "10";
|
||||
end if;
|
||||
|
||||
when "110" => -- first half of bit transmission
|
||||
-- ------------------------------------------------------------
|
||||
spi_sck_o <= ctrl(ctrl_cpha_c) xor ctrl(ctrl_cpol_c);
|
||||
if (spi_clk_en = '1') then
|
||||
spi_sck_o <= not (ctrl(ctrl_cpha_c) xor ctrl(ctrl_cpol_c));
|
||||
rtx_engine.sdi_sync <= spi_sdi_i; -- sample data input
|
||||
rtx_engine.bitcnt <= std_ulogic_vector(unsigned(rtx_engine.bitcnt) + 1);
|
||||
rtx_engine.state(1 downto 0) <= "11";
|
||||
end if;
|
||||
|
||||
when "111" => -- second half of bit transmission
|
||||
-- ------------------------------------------------------------
|
||||
spi_sck_o <= ctrl(ctrl_cpha_c) xnor ctrl(ctrl_cpol_c);
|
||||
if (spi_clk_en = '1') then
|
||||
rtx_engine.sreg <= rtx_engine.sreg(30 downto 0) & rtx_engine.sdi_sync;
|
||||
rtx_engine.sreg <= rtx_engine.sreg(30 downto 0) & rtx_engine.sdi_sync; -- shift and set output
|
||||
if (rtx_engine.bitcnt(5 downto 3) = rtx_engine.bytecnt) then -- all bits transferred?
|
||||
spi_sck_o <= ctrl(ctrl_cpol_c);
|
||||
irq_o <= '1'; -- interrupt!
|
||||
rtx_engine.state(1 downto 0) <= "00"; -- transmission done
|
||||
else
|
||||
spi_sck_o <= ctrl(ctrl_cpha_c) xor ctrl(ctrl_cpol_c);
|
||||
rtx_engine.state(1 downto 0) <= "10";
|
||||
end if;
|
||||
end if;
|
||||
|
||||
when others => -- "0--": SPI deactivated
|
||||
-- ------------------------------------------------------------
|
||||
spi_sck_o <= ctrl(ctrl_cpol_c);
|
||||
rtx_engine.sreg <= (others => '0');
|
||||
rtx_engine.state(1 downto 0) <= "00";
|
||||
|
||||
|
|
|
@ -488,15 +488,14 @@ begin
|
|||
ctrl.di_sync <= '-';
|
||||
else
|
||||
-- defaults --
|
||||
spi_clk_o <= cf_cpol_i;
|
||||
spi_csn_o <= '1'; -- de-selected by default
|
||||
ctrl.di_sync <= spi_data_i;
|
||||
spi_csn_o <= '1'; -- de-selected by default
|
||||
|
||||
-- fsm --
|
||||
case ctrl.state is
|
||||
|
||||
when S_IDLE => -- wait for new transmission trigger
|
||||
-- ------------------------------------------------------------
|
||||
spi_clk_o <= cf_cpol_i;
|
||||
ctrl.bitcnt <= op_nbytes_i & "000"; -- number of bytes
|
||||
ctrl.csen <= op_csen_i;
|
||||
if (op_start_i = '1') then
|
||||
|
@ -508,27 +507,32 @@ begin
|
|||
-- ------------------------------------------------------------
|
||||
spi_csn_o <= not ctrl.csen;
|
||||
if (spi_clk_en_i = '1') then
|
||||
if (cf_cpha_i = '1') then -- clock phase shift
|
||||
spi_clk_o <= not cf_cpol_i;
|
||||
end if;
|
||||
ctrl.state <= S_RTX_A;
|
||||
end if;
|
||||
|
||||
when S_RTX_A => -- first half of bit transmission
|
||||
-- ------------------------------------------------------------
|
||||
spi_csn_o <= not ctrl.csen;
|
||||
spi_clk_o <= cf_cpha_i xor cf_cpol_i;
|
||||
if (spi_clk_en_i = '1') then
|
||||
ctrl.bitcnt <= std_ulogic_vector(unsigned(ctrl.bitcnt) - 1);
|
||||
ctrl.state <= S_RTX_B;
|
||||
spi_clk_o <= not (cf_cpha_i xor cf_cpol_i);
|
||||
ctrl.di_sync <= spi_data_i;
|
||||
ctrl.bitcnt <= std_ulogic_vector(unsigned(ctrl.bitcnt) - 1);
|
||||
ctrl.state <= S_RTX_B;
|
||||
end if;
|
||||
|
||||
when S_RTX_B => -- second half of bit transmission
|
||||
-- ------------------------------------------------------------
|
||||
spi_csn_o <= not ctrl.csen;
|
||||
spi_clk_o <= not (cf_cpha_i xor cf_cpol_i);
|
||||
if (spi_clk_en_i = '1') then
|
||||
ctrl.sreg <= ctrl.sreg(ctrl.sreg'left-1 downto 0) & ctrl.di_sync;
|
||||
if (or_reduce_f(ctrl.bitcnt) = '0') then -- all bits transferred?
|
||||
spi_clk_o <= cf_cpol_i;
|
||||
ctrl.state <= S_DONE; -- transmission done
|
||||
else
|
||||
spi_clk_o <= cf_cpha_i xor cf_cpol_i;
|
||||
ctrl.state <= S_RTX_A; -- next bit
|
||||
end if;
|
||||
end if;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue