xilinx sdk 之SPI配置

使用ZYNQ PS端的SPI接口配置图像 cmos芯片

第一步:看原理图,看看原理图的cmos芯片的接口接在PL的那个管脚上的。有几个管脚

第二步:打开zynq ps,选择SD0  MIO 40- 45

选择UART0 选择 MIO 46-47

SPI0 选择 EMIO 因为ps接口连接到了PL侧

选择GPIO中的EMIO,因为要配置摄像头的复位引脚,复位引脚连接PL侧,要使用EMIO,先选择一个就可以了。

 

第三步:引出管脚,引出需要的管脚 ,选择make externel

第四步:可以修改管脚名,方便认识

第五步:create hdl wrapper,创建硬件描述

第六步:因为使用了gpio,所以需要进行配置管脚约束

add source 

设置管脚,设置电平

set_property PACKAGE_PIN P20  [get_ports spi_miso      ]
set_property PACKAGE_PIN R19  [get_ports spi_cs      ]
set_property PACKAGE_PIN J19  [get_ports spi_mosi      ]
set_property PACKAGE_PIN K19  [get_ports spi_sclk      ] 

set_property PACKAGE_PIN U20  [get_ports cmos_rst    ]

 

set_property IOSTANDARD LVCMOS33 [get_ports spi_miso]
set_property IOSTANDARD LVCMOS33 [get_ports spi_mosi]
set_property IOSTANDARD LVCMOS33 [get_ports spi_cs]
set_property IOSTANDARD LVCMOS33 [get_ports spi_sclk]

set_property IOSTANDARD LVCMOS33 [get_ports cmos_rst]

之后生成bitstream文件。

然后export bit stream文件,之后进行设计。

latch sdk

添加配置文件,之后添加spi文件,可以参考spi例子

 

 

xilinx sdk 之SPI配置

 

 

 

使用 SPI库函数,这里涉及到库函数使用

#define XPAR_XSPIPS_0_DEVICE_ID XPAR_PS7_SPI_0_DEVICE_ID

#define SPI_DEVICE_ID        XPAR_XSPIPS_0_DEVICE_ID

在main函数中,包含spi结构体函数

定义两个结构体

 

首先在xparameters.h里面找到设备

static XSpiPs Spi_Instance;
static XSpiPs_Config *SpiPsCfg;

 

 

 

 

    /*
     * Initialize the SPI driver so that it's ready to use
     */
    SpiConfig = XSpiPs_LookupConfig(SpiDeviceId);
    if (NULL == SpiConfig) {
        return XST_FAILURE;
    }

    Status = XSpiPs_CfgInitialize((&SpiInstance), SpiConfig,
                    SpiConfig->BaseAddress);
    if (Status != XST_SUCCESS) {
        return XST_FAILURE;
    }

 

初试化以后,调用s32 XSpiPs_SetOptions(XSpiPs *InstancePtr, u32 Options),设置模式函数,XSPIPS_*_OPTIONS

关键在第二个参数,第二个参数到底怎么用呢???

首先要选择Master 模式,然后选择片选信号,

XSPIPS_DECODE_SSELECT_OPTION,设置38译码器,可以接一个38译码器,因为有三个片选信号。

XSPIPS_FORCE_SSELECT_OPTION,强制选择模式,通过调用发送函数来强制选择CS来使CS有效。

XSPIPS_MASTER_OPTION ,Master设置,

    status = XSpiPs_SetOptions(&Spi_Instance,XSPIPS_FORCE_SSELECT_OPTION|XSPIPS_MASTER_OPTION);
    if (Status != XST_SUCCESS) {
        return XST_FAILURE;
    }

 

然后设置时钟频率

This function sets the clock prescaler for an SPI device

s32 XSpiPs_SetClkPrescaler(XSpiPs *InstancePtr, u8 Prescaler)

关键还是第二个参数

XSPIPS_CLK_PRESCALE_32,这个32分频是怎么用的呢?

在zynq ps中,可以展开CLock Configuration,然后里面有个IO Peripheral clocks,这个就是SPI的时钟

然后,这个设置时钟的分频系数,就是分频这个时钟的。

xilinx sdk 之SPI配置

xilinx sdk 之SPI配置

 

设置完时钟以后,在设置片选

s32 XSpiPs_SetSlaveSelect(XSpiPs *InstancePtr, u8 SlaveSel)

第二个参数如果没有接38译码器的话,0-2对应着你zynq ps端接片选的值

比如2的话,你用的就是CS2.

 

大致流程如下:在main函数里注意先声明,不然找不到。

int spi_init(u16 SpiDeviceId)
{
    int Status;
    SpiPsCfg = XSpiPs_LookupConfig(SpiDeviceId);
    if (NULL == SpiPsCfg) {
        return XST_FAILURE;
    }

    SpiPsCfg = XSpiPs_CfgInitialize((&Spi_Instance), SpiPsCfg,
            SpiPsCfg->BaseAddress);
    if (Status != XST_SUCCESS) {
        return XST_FAILURE;
    }
    Status = XSpiPs_SetOptions(&Spi_Instance,XSPIPS_FORCE_SSELECT_OPTION|XSPIPS_MASTER_OPTION);
    if (Status != XST_SUCCESS) {
        return XST_FAILURE;
    }
    Status = XSpiPs_SetClkPrescaler(&Spi_Instance, XSPIPS_CLK_PRESCALE_32);
    if (Status != XST_SUCCESS) {
        return XST_FAILURE;
    }
    XSpiPs_SetSlaveSelect(&Spi_Instance,0);
    if (Status != XST_SUCCESS) {
        return XST_FAILURE;
    }
    return XST_SUCCESS;
}