前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Zynq中PL端SPI接口

Zynq中PL端SPI接口

作者头像
瓜大三哥
发布2019-11-09 13:39:17
2.9K0
发布2019-11-09 13:39:17
举报
文章被收录于专栏:瓜大三哥瓜大三哥

SPI接口主要应用在 EEPROM,FLASH,实时时钟,AD转换器,还有数字信号处理器和数字信号解码器之间。SPI,是一种高速的,全双工,同步的通信总线,并且在芯片的管脚上只占用四根线,节约了芯片的管脚,同时为PCB的布局上节省空间,提供方便,正是出于这种简单易用的特性,现在越来越多的芯片集成了这种通信协议

SDO – 主设备数据输出,从设备数据输入 对应MOSI master output slave input

SDI – 主设备数据输入,从设备数据输出 对应MISO master input slave output

SCLK – 时钟信号,由主设备产生

CS – 从设备使能信号,由主设备控制,CS: 其中CS是控制芯片是否被选中的,也就是说只有片选信号为预先规定的使能信号时(高电位或低电位),对此芯片的操作才有效,这就允许在同一总线上连接多个SPI设备成为可能。

通过控制CPOL和CPHA来控制采样边沿。

下面是SPI模式0,也就是数据在上升沿采样,在下降沿移出的简单程序。

-------------------------------------------------------------------------------

-- Copyright (c) 2010 Xilinx, Inc.

-- This design is confidential and proprietary of Xilinx, All Rights Reserved.

-------------------------------------------------------------------------------

-- ____ ____

-- / /\/ /

-- /___/ \ / Vendor: Xilinx, Inc.

-- \ \ \/ Version: 1.00

-- \ \ Filename: SpiSerDes.vhd

-- / / Date Last Modified: October 25 2009

-- /___/ /\ Date Created: October 25 2009

-- \ \ / \

-- \___\/\___\

--

--Devices: Spartan-6, Virtex-5, Virtex-6, 7 series FPGAs

--Purpose: This module serializes and deserializes a byte's worth of

-- data to/from a SPI device for a master SPI controller.

--Description: This modules takes the following inputs:

-- inClk - Module clock and forwarded to SPI bus clk.

-- The frequency of this clock must be less than

-- or equal to the Fmax of the peripheral(s) on

-- the SPI bus.

-- inReset_EnableB - Active-high synchronous reset.

-- When High, resets this module and

-- also drives the SPI device chip-select High.

-- When Low, enables this module and

-- also drives SPI device chip-select Low.

-- inData8Send - The data byte to send to SPI device.

-- The input data byte is registered on the

-- first rising edge of inClk after

-- inStartTransfer transitions to High (and

-- when outTransferDone is High).

-- inStartTransfer - Start SPI serialization when this is High

-- and when outTransferDone=High.

-- This module has the following outputs:

-- outTransferDone - Signals when serialization is DONE.

-- Signal is driven Low on the first rising

-- edge of inClk after inStartTransfer

-- transitions to High.

-- Signal is returned to High after the module

-- has completed the serialization of a byte

-- of data.

-- outData8Receive - When outTransferDone=High, this output has

-- the data byte received from the inSpiMiso

-- pin during the serial transfer process.

-- This module is the master controller for SPI bus signals:

-- outSpiCsB - Connect to SPI device active-low chip select

-- outSpiClk - Connect to SPI bus clk

-- outSpiMosi - Connect to SPI bus master-out, slave-input

-- inSpiMiso - Connect to SPI bus master-in, slave-output

-- If another device can be a master of the SPI bus, then use

-- outSpiCsB as the active-Low output enable control signal for

-- all SPI bus outputs. When using outSpiCsB as an output enable,

-- all controlled outputs must have a pull-up, especially the SPI

-- chip-select signal.

--Usage: Module setup:

-- - Connect for SPI ports to SPI bus. See above.

-- - Supply inClk. Fmax determined by target (slave) SPI device.

-- Module use sequence:

-- 1. Reset module:

-- 1.A. Drive inReset_EnableB=High to reset module

-- 2. Enable SPI device (SPI CSB=Low)

-- 2.A. Drive inReset_enableB=Low to select target SPI device.

-- 3. Serialize byte output via MOSI and byte input via MISO:

-- 3.A. For each byte:

-- 3.A.1: Start serialization:

-- inData8Send <= byte to send

-- inStartTransfer <= High

-- 3.A.2: Wait for serialization DONE

-- Wait for outTransferDone=High

-- Get parallel MISO data from outData8Receive

-- 4. Disable SPI device (SPI CSB=High)

-- 4.A. Drive inReset_EnableB=High

-- NOTES:

-- - All signals active/transition on rising-edge inClk except

-- outSpiMosi transitions on falling-edge of outSpiClk.

-- - If inStartTransfer=High when outTransferDone=High, then

-- next byte serialization starts on following rising inClk.

-- To prevent next byte serialization, set inStartTransfer=Low

-- before outTransferDone goes High.

-- - outSpiClk runs at same frequency and phase as inClk.

-- outSpiClk is gated.

--Signal Timing:

-- _ _ _ _ _ _ _ _ _

-- inClk _/ \_/ \_/ \_/ \_/ \_/ \.....\_/ \_/ \_/ \_

-- ___ _____

-- inReset_EnableB \_________________________________/

-- _____ ___

-- outSpiCsB \_________________________________/

-- ___________________________________

-- inStartTransfer _______/ \\\\\\\\\\\\\\\\\\\\\\\\*\\\\\\\

-- _________ ___________

-- outTransferDone \______________.....__/

-- _______ ___

-- inData8Send[7:0] _______XD8SXXX...

-- ___ ___ ___ ___ _________

-- inSpiMosi XD7_XD6_XD5_X.....XD0_X_________

-- ___________ _ _ _ _ ___________

-- outSpiClk \_/ \_/ \_/ \.....\_/

-- ___________

--outData8Receive[7:0] XD8SX XXXD8R*D8SX___

-- *Note: if inStartTransfer=High, then inData8Send loaded into outData8Receive

--Reference:

--Revision History:

-- Revision (YYYY/MM/DD) - [User] Description

-- Rev 1.00 (2009/10/25) - [RMK] Created.

-------------------------------------------------------------------------------

library ieee;

--Library UNISIM;

use ieee.std_logic_1164.all;

use ieee.std_logic_unsigned.all;

use ieee.numeric_std.all;

--use UNISIM.vcomponents.all;

entity SpiSerDes is

port

(

-- SerDes clock and control signals

inClk : in std_logic; -- System clock. Fmax <= SPI peripheral Fmax.

inReset_EnableB : in std_logic; -- Active-high, synchronous reset.

inStartTransfer : in std_logic; -- Active-high, initiate transfer of data

outTransferDone : out std_logic; -- DONE='1' when transfer is done

-- Parallel data ports

inData8Send : in std_logic_vector(7 downto 0); -- Sent to SPI device

outData8Receive : out std_logic_vector(7 downto 0); -- Received from SPI device

-- SPI ports and tristate control - Connect these to the SPI bus

outSpiCsB : out std_logic; -- SPI chip-select to SPI device

-- or all SPI outputs control enable

outSpiClk : out std_logic; -- SPI clock to SPI device

outSpiMosi : out std_logic; -- SPI master-out, slave-in to SPI device

inSpiMiso : in std_logic -- SPI master-in, slave-out from SPI device

);

end SpiSerDes;

architecture behavioral of SpiSerDes is

-- Constants

constant cShiftCountInit : std_logic_vector(8 downto 0) := B"000000001";

-- Registers

signal regShiftCount : std_logic_vector(8 downto 0) := cShiftCountInit;

signal regShiftData : std_logic_vector(7 downto 0) := B"00000000";

signal regSpiCsB : std_logic := '1';

signal regSpiMosi : std_logic := '1';

signal regTransferDoneDelayed : std_logic := '1';

-- Signals

signal intTransferDone : std_logic;

-- Attributes

attribute clock_signal : string;

attribute clock_signal of inClk : signal is "yes";

begin

-- Internal signals

intTransferDone <= regShiftCount(0);

-- TransferDone delayed by half clock cycle

processTransferDone : process (inClk)

begin

if (falling_edge(inClk)) then

regTransferDoneDelayed <= intTransferDone;

end if;

end process processTransferDone;

-- SPI chip-select (active-Low) is always inverse of inReset_EnableB.

processSpiCsB : process (inClk)

begin

if (rising_edge(inClk)) then

regSpiCsB <= inReset_EnableB;

end if;

end process processSpiCsB;

-- Track transfer of serial data with barrel shifter.

processShiftCount : process (inClk)

begin

if (rising_edge(inClk)) then

if (inReset_EnableB='1') then

regShiftCount <= cShiftCountInit;

elsif ((intTransferDone='0') or (inStartTransfer='1')) then

-- Barrel shift (rotate right)

regShiftCount <= regShiftCount(0) & regShiftCount(8 downto 1);

end if;

end if;

end process processShiftCount;

-- Simultaneous serialize outgoing data & deserialize incoming data. MSB first

processShiftData : process (inClk)

begin

if (rising_edge(inClk)) then

if (intTransferDone='0') then

-- SHIFT-left while not outTransferDone

regShiftData <= regShiftData(6 downto 0) & inSpiMiso;

elsif (inStartTransfer='1') then

-- Load data to start a new transfer sequence from a done state

regShiftData <= inData8Send;

end if;

end if;

end process processShiftData;

-- SPI MOSI register outputs on falling edge of inClk. MSB first.

processSpiMosi : process (inClk)

begin

if (falling_edge(inClk)) then

if (inReset_EnableB='1') then

regSpiMosi <= '1';

elsif (intTransferDone='0') then

regSpiMosi <= regShiftData(7);

end if;

end if;

end process processSpiMosi;

-- Assign outputs

outSpiClk <= (inClk or intTransferDone or regTransferDoneDelayed);

outSpiCsB <= regSpiCsB;

outSpiMosi <= regSpiMosi;

outTransferDone <= intTransferDone;

outData8Receive <= regShiftData;

end behavioral;

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-11-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 瓜大三哥 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
数据库一体机 TData
数据库一体机 TData 是融合了高性能计算、热插拔闪存、Infiniband 网络、RDMA 远程直接存取数据的数据库解决方案,为用户提供高可用、易扩展、高性能的数据库服务,适用于 OLAP、 OLTP 以及混合负载等各种应用场景下的极限性能需求,支持 Oracle、SQL Server、MySQL 和 PostgreSQL 等各种主流数据库。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档