spips_v3_0: Added new version V3_0 and deprecated v2_0
This patch adds new version for spips driver. support for Zynq Ultrascale Mp added in new version. Signed-off-by: Vishnu Motghare <vishnum@xilinx.com>
This commit is contained in:
parent
f45ada332c
commit
8a752fd656
20 changed files with 6496 additions and 0 deletions
42
XilinxProcessorIPLib/drivers/spips/data/spips.mdd
Executable file
42
XilinxProcessorIPLib/drivers/spips/data/spips.mdd
Executable file
|
@ -0,0 +1,42 @@
|
|||
###############################################################################
|
||||
#
|
||||
# Copyright (C) 2011 - 2014 Xilinx, Inc. All rights reserved.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# Use of the Software is limited solely to applications:
|
||||
# (a) running on a Xilinx device, or
|
||||
# (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
# OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
#
|
||||
# Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
# in advertising or otherwise to promote the sale, use or other dealings in
|
||||
# this Software without prior written authorization from Xilinx.
|
||||
#
|
||||
###############################################################################
|
||||
OPTION psf_version = 2.1;
|
||||
|
||||
BEGIN driver spips
|
||||
|
||||
OPTION supported_peripherals = (ps7_spi ps8_spi pss_spi);
|
||||
OPTION driver_state = ACTIVE;
|
||||
OPTION copyfiles = all;
|
||||
OPTION VERSION = 3.0;
|
||||
OPTION NAME = spips;
|
||||
|
||||
END driver
|
51
XilinxProcessorIPLib/drivers/spips/data/spips.tcl
Executable file
51
XilinxProcessorIPLib/drivers/spips/data/spips.tcl
Executable file
|
@ -0,0 +1,51 @@
|
|||
###############################################################################
|
||||
#
|
||||
# Copyright (C) 2011 - 2014 Xilinx, Inc. All rights reserved.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# Use of the Software is limited solely to applications:
|
||||
# (a) running on a Xilinx device, or
|
||||
# (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
# OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
#
|
||||
# Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
# in advertising or otherwise to promote the sale, use or other dealings in
|
||||
# this Software without prior written authorization from Xilinx.
|
||||
#
|
||||
###############################################################################
|
||||
##############################################################################
|
||||
#
|
||||
# Modification History
|
||||
#
|
||||
# Ver Who Date Changes
|
||||
# ----- ---- -------- -----------------------------------------------
|
||||
# 1.00a sdm 11/22/11 Created
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
#uses "xillib.tcl"
|
||||
|
||||
proc generate {drv_handle} {
|
||||
xdefine_zynq_include_file $drv_handle "xparameters.h" "XSpiPs" "NUM_INSTANCES" "DEVICE_ID" "C_S_AXI_BASEADDR" "C_S_AXI_HIGHADDR" "C_SPI_CLK_FREQ_HZ"
|
||||
|
||||
xdefine_zynq_config_file $drv_handle "xspips_g.c" "XSpiPs" "DEVICE_ID" "C_S_AXI_BASEADDR" "C_SPI_CLK_FREQ_HZ"
|
||||
|
||||
xdefine_zynq_canonical_xpars $drv_handle "xparameters.h" "XSpiPs" "DEVICE_ID" "C_S_AXI_BASEADDR" "C_S_AXI_HIGHADDR" "C_SPI_CLK_FREQ_HZ"
|
||||
|
||||
}
|
40
XilinxProcessorIPLib/drivers/spips/data/spips_header.h
Executable file
40
XilinxProcessorIPLib/drivers/spips/data/spips_header.h
Executable file
|
@ -0,0 +1,40 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2011 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef SPIPS_HEADER_H /* prevent circular inclusions */
|
||||
#define SPIPS_HEADER_H /* by using protection macros */
|
||||
|
||||
#include "xil_types.h"
|
||||
#include "xil_assert.h"
|
||||
#include "xstatus.h"
|
||||
|
||||
int SpiPsSelfTestExample(u16 DeviceId);
|
||||
#endif
|
138
XilinxProcessorIPLib/drivers/spips/data/spips_tapp.tcl
Executable file
138
XilinxProcessorIPLib/drivers/spips/data/spips_tapp.tcl
Executable file
|
@ -0,0 +1,138 @@
|
|||
###############################################################################
|
||||
#
|
||||
# Copyright (C) 2011 - 2014 Xilinx, Inc. All rights reserved.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# Use of the Software is limited solely to applications:
|
||||
# (a) running on a Xilinx device, or
|
||||
# (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
# OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
#
|
||||
# Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
# in advertising or otherwise to promote the sale, use or other dealings in
|
||||
# this Software without prior written authorization from Xilinx.
|
||||
#
|
||||
###############################################################################
|
||||
###############################################################################
|
||||
# MODIFICATION HISTORY:
|
||||
# Ver Who Date Changes
|
||||
# -------- ------ -------- ------------------------------------
|
||||
# 2.0 adk 12/10/13 Updated as per the New Tcl API's
|
||||
##############################################################################
|
||||
|
||||
# Uses $XILINX_EDK/bin/lib/xillib_sw.tcl
|
||||
# -----------------------------------------------------------------
|
||||
# Software Project Types (swproj):
|
||||
# 0 : MemoryTest - Calls basic memorytest routines from common driver dir
|
||||
# 1 : PeripheralTest - Calls any existing polled_example and/or selftest
|
||||
# -----------------------------------------------------------------
|
||||
|
||||
# -----------------------------------------------------------------
|
||||
# TCL Procedures:
|
||||
# -----------------------------------------------------------------
|
||||
|
||||
proc gen_include_files {swproj mhsinst} {
|
||||
if {$swproj == 0} {
|
||||
return ""
|
||||
}
|
||||
if {$swproj == 1} {
|
||||
set inc_file_lines {xspips.h spips_header.h}
|
||||
}
|
||||
return $inc_file_lines
|
||||
}
|
||||
|
||||
proc gen_src_files {swproj mhsinst} {
|
||||
if {$swproj == 0} {
|
||||
return ""
|
||||
}
|
||||
if {$swproj == 1} {
|
||||
|
||||
set inc_file_lines {examples/xspips_selftest_example.c data/spips_header.h}
|
||||
|
||||
return $inc_file_lines
|
||||
}
|
||||
}
|
||||
|
||||
proc gen_testfunc_def {swproj mhsinst} {
|
||||
return ""
|
||||
}
|
||||
|
||||
proc gen_init_code {swproj mhsinst} {
|
||||
|
||||
if {$swproj == 0} {
|
||||
return ""
|
||||
}
|
||||
if {$swproj == 1} {
|
||||
return ""
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
proc gen_testfunc_call {swproj mhsinst} {
|
||||
|
||||
if {$swproj == 0} {
|
||||
return ""
|
||||
}
|
||||
|
||||
set ipname [get_property NAME $mhsinst]
|
||||
set deviceid [::hsm::utils::get_ip_param_name $mhsinst "DEVICE_ID"]
|
||||
set stdout [get_property CONFIG.STDOUT [get_os]]
|
||||
if { $stdout == "" || $stdout == "none" } {
|
||||
set hasStdout 0
|
||||
} else {
|
||||
set hasStdout 1
|
||||
}
|
||||
|
||||
set testfunc_call ""
|
||||
|
||||
if {${hasStdout} == 0} {
|
||||
|
||||
append testfunc_call "
|
||||
|
||||
{
|
||||
int Status;
|
||||
|
||||
Status = SpiPsSelfTestExample(${deviceid});
|
||||
|
||||
}"
|
||||
|
||||
|
||||
} else {
|
||||
|
||||
append testfunc_call "
|
||||
|
||||
{
|
||||
int Status;
|
||||
|
||||
print(\"\\r\\n Running SpiPsSelfTestExample() for ${ipname}...\\r\\n\");
|
||||
|
||||
Status = SpiPsSelfTestExample(${deviceid});
|
||||
|
||||
if (Status == 0) {
|
||||
print(\"SpiPsSelfTestExample PASSED\\r\\n\");
|
||||
}
|
||||
else {
|
||||
print(\"SpiPsSelfTestExample FAILED\\r\\n\");
|
||||
}
|
||||
}"
|
||||
|
||||
}
|
||||
|
||||
return $testfunc_call
|
||||
}
|
21
XilinxProcessorIPLib/drivers/spips/examples/index.html
Executable file
21
XilinxProcessorIPLib/drivers/spips/examples/index.html
Executable file
|
@ -0,0 +1,21 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Language" content="en-us">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<title>Driver example applications</title>
|
||||
<link rel="stylesheet" type="text/css" href="../help.css">
|
||||
</head>
|
||||
<body bgcolor="#FFFFFF">
|
||||
<h1> Example Applications for the driver spips_v2_0 </h1>
|
||||
<HR>
|
||||
<ul>
|
||||
<li>xspips_eeprom_intr_example.c <a href="xspips_eeprom_intr_example.c">(source)</a> </li>
|
||||
<li>xspips_eeprom_polled_example.c <a href="xspips_eeprom_polled_example.c">(source)</a> </li>
|
||||
<li>xspips_flash_intr_example.c <a href="xspips_flash_intr_example.c">(source)</a> </li>
|
||||
<li>xspips_flash_polled_example.c <a href="xspips_flash_polled_example.c">(source)</a> </li>
|
||||
<li>xspips_selftest_example.c <a href="xspips_selftest_example.c">(source)</a> </li>
|
||||
</ul>
|
||||
<p><font face="Times New Roman" color="#800000">Copyright <20> 1995-2014 Xilinx, Inc. All rights reserved.</font></p>
|
||||
</body>
|
||||
</html>
|
645
XilinxProcessorIPLib/drivers/spips/examples/xspips_eeprom_intr_example.c
Executable file
645
XilinxProcessorIPLib/drivers/spips/examples/xspips_eeprom_intr_example.c
Executable file
|
@ -0,0 +1,645 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2010 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* @file xspi_eeprom_intr_example.c
|
||||
*
|
||||
*
|
||||
* This file contains a design example using the SPI driver (XSpiPs) in
|
||||
* interrupt mode and hardware device with a serial EEPROM device. The
|
||||
* hardware which this example runs on must have a serial EEPROM (Microchip
|
||||
* 25XX320 or 25XX160) for it to run.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* None.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ---- -------- -----------------------------------------------
|
||||
* 1.00 sdm 02/27/10 First release
|
||||
* 1.00 sdm 10/25/11 Updated the chip select to be used to second chip select
|
||||
*
|
||||
*</pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
#include "xparameters.h" /* EDK generated parameters */
|
||||
#include "xspips.h" /* SPI device driver */
|
||||
#include "xscugic.h" /* Interrupt controller device driver */
|
||||
#include "xil_exception.h"
|
||||
#include "xil_printf.h"
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
/*
|
||||
* The following constants map to the XPAR parameters created in the
|
||||
* xparameters.h file. They are defined here such that a user can easily
|
||||
* change all the needed parameters in one place.
|
||||
*/
|
||||
#define SPI_DEVICE_ID XPAR_XSPIPS_0_DEVICE_ID
|
||||
#define INTC_DEVICE_ID XPAR_SCUGIC_SINGLE_DEVICE_ID
|
||||
#define SPI_INTR_ID XPAR_XSPIPS_0_INTR
|
||||
|
||||
/*
|
||||
* The following constants define the commands which may be sent to the EEPROM
|
||||
* device.
|
||||
*/
|
||||
#define WRITE_STATUS_CMD 1
|
||||
#define WRITE_CMD 2
|
||||
#define READ_CMD 3
|
||||
#define WRITE_DISABLE_CMD 4
|
||||
#define READ_STATUS_CMD 5
|
||||
#define WRITE_ENABLE_CMD 6
|
||||
|
||||
/*
|
||||
* The following constants define the offsets within a EepromBuffer data
|
||||
* type for each kind of data. Note that the read data offset is not the
|
||||
* same as the write data because the SPI driver is designed to allow full
|
||||
* duplex transfers such that the number of bytes received is the number
|
||||
* sent and received.
|
||||
*/
|
||||
#define COMMAND_OFFSET 0 /* EEPROM instruction */
|
||||
#define ADDRESS_MSB_OFFSET 1 /* MSB of address to read or write */
|
||||
#define ADDRESS_LSB_OFFSET 2 /* LSB of address to read or write */
|
||||
#define DATA_OFFSET 3
|
||||
#define WRITE_DATA_OFFSET 3 /* Start of data to write to the EEPROM */
|
||||
#define READ_DATA_OFFSET 6 /* Start of data read from the EEPROM */
|
||||
|
||||
/*
|
||||
* The following constants specify the extra bytes which are sent to the
|
||||
* EEPROM on the SPI interface, that are not data, but control information
|
||||
* which includes the command and address
|
||||
*/
|
||||
#define OVERHEAD_SIZE 3
|
||||
|
||||
/*
|
||||
* The following constants specify the page size and number of pages for the
|
||||
* EEPROM. The page size specifies a max number of bytes that can be written
|
||||
* to the EEPROM with a single transfer using the SPI driver.
|
||||
*/
|
||||
#define PAGE_SIZE 16
|
||||
#define PAGE_COUNT 128
|
||||
|
||||
/*
|
||||
* The following constants specify the max amount of data and the size of the
|
||||
* the buffer required to hold the data and overhead to transfer the data to
|
||||
* and from the EEPROM.
|
||||
*/
|
||||
#define MAX_DATA PAGE_COUNT * PAGE_SIZE
|
||||
#define BUFFER_SIZE MAX_DATA + READ_DATA_OFFSET
|
||||
|
||||
/*
|
||||
* The following constant defines the slave select signal that is used to
|
||||
* to select the EEPROM device on the SPI bus, this signal is typically
|
||||
* connected to the chip select of the device
|
||||
*/
|
||||
#define EEPROM_SPI_SELECT 0x01
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
/*
|
||||
* The following data type is used to send and receive data to the serial
|
||||
* EEPROM device connected to the SPI interface. It is an array of bytes
|
||||
* rather than a structure for portability avoiding packing issues. The
|
||||
* application must setup the data to be written in this buffer and retrieve
|
||||
* the data read from it.
|
||||
*/
|
||||
typedef u8 EepromBuffer[BUFFER_SIZE];
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
static int SpiSetupIntrSystem(XScuGic *IntcInstancePtr,
|
||||
XSpiPs *SpiInstancePtr, u16 SpiIntrId);
|
||||
|
||||
static void SpiDisableIntrSystem(XScuGic *IntcInstancePtr, u16 SpiIntrId);
|
||||
|
||||
void SpiHandler(void *CallBackRef, u32 StatusEvent, unsigned int ByteCount);
|
||||
|
||||
void EepromRead(XSpiPs *SpiPtr, u16 Address, int ByteCount,
|
||||
EepromBuffer Buffer);
|
||||
|
||||
void EepromWrite(XSpiPs *SpiPtr, u16 Address, u8 ByteCount,
|
||||
EepromBuffer Buffer);
|
||||
|
||||
int SpiPsEepromIntrExample(XScuGic *IntcInstancePtr, XSpiPs *SpiInstancePtr,
|
||||
u16 SpiDeviceId, u16 SpiIntrId);
|
||||
|
||||
/************************** Variable Definitions *****************************/
|
||||
|
||||
/*
|
||||
* The instances to support the device drivers are global such that the
|
||||
* are initialized to zero each time the program runs. They could be local
|
||||
* but should at least be static so they are zeroed.
|
||||
*/
|
||||
static XScuGic IntcInstance;
|
||||
static XSpiPs SpiInstance;
|
||||
|
||||
/*
|
||||
* The following variables are shared between non-interrupt processing and
|
||||
* interrupt processing such that they must be global.
|
||||
*/
|
||||
volatile int TransferInProgress;
|
||||
|
||||
/*
|
||||
* The following variable tracks any errors that occur during interrupt
|
||||
* processing
|
||||
*/
|
||||
int Error;
|
||||
|
||||
/*
|
||||
* The following variable allows a test value to be added to the values that
|
||||
* are written to the EEPROM such that unique values can be generated to
|
||||
* guarantee the writes to the EEPROM were successful
|
||||
*/
|
||||
int Test;
|
||||
|
||||
/*
|
||||
* The following variables are used to read and write to the eeprom and they
|
||||
* are global to avoid having large buffers on the stack
|
||||
*/
|
||||
EepromBuffer ReadBuffer;
|
||||
EepromBuffer WriteBuffer;
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Main function to call the Spi Eeprom example.
|
||||
*
|
||||
* @param None
|
||||
*
|
||||
* @return XST_SUCCESS if successful, otherwise XST_FAILURE.
|
||||
*
|
||||
* @note None
|
||||
*
|
||||
******************************************************************************/
|
||||
int main(void)
|
||||
{
|
||||
int Status;
|
||||
|
||||
xil_printf("SPI EEPROM Interrupt Example Test \r\n");
|
||||
|
||||
/*
|
||||
* Run the Spi Interrupt example.
|
||||
*/
|
||||
Status = SpiPsEepromIntrExample(&IntcInstance, &SpiInstance,
|
||||
SPI_DEVICE_ID, SPI_INTR_ID);
|
||||
if (Status != XST_SUCCESS) {
|
||||
xil_printf("SPI EEPROM Interrupt Example Test Failed\r\n");
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
xil_printf("Successfully ran SPI EEPROM Interrupt Example Test\r\n");
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* The purpose of this function is to illustrate how to use the XSpiPs
|
||||
* device driver in interrupt mode . This test writes and reads data from a
|
||||
* serial EEPROM.
|
||||
* This part must be present in the hardware to use this example.
|
||||
*
|
||||
* @param IntcInstancePtr is a pointer to the GIC driver to use.
|
||||
* @param SpiInstancePtr is a pointer to the SPI driver to use.
|
||||
* @param SpiDeviceId is the DeviceId of the Spi device.
|
||||
* @param SpiIntrId is the Spi Interrupt Id.
|
||||
*
|
||||
* @return XST_SUCCESS if successful else XST_FAILURE.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* This function calls functions which contain loops that may be infinite
|
||||
* if interrupts are not working such that it may not return. If the device
|
||||
* slave select is not correct and the device is not responding on bus it will
|
||||
* read a status of 0xFF for the status register as the bus is pulled up.
|
||||
*
|
||||
*****************************************************************************/
|
||||
int SpiPsEepromIntrExample(XScuGic *IntcInstancePtr, XSpiPs *SpiInstancePtr,
|
||||
u16 SpiDeviceId, u16 SpiIntrId)
|
||||
{
|
||||
int Status;
|
||||
u8 *BufferPtr;
|
||||
u8 UniqueValue;
|
||||
int Count;
|
||||
int Page;
|
||||
XSpiPs_Config *SpiConfig;
|
||||
|
||||
/*
|
||||
* Initialize the SPI driver so that it's ready to use
|
||||
*/
|
||||
SpiConfig = XSpiPs_LookupConfig(SpiDeviceId);
|
||||
if (NULL == SpiConfig) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
Status = XSpiPs_CfgInitialize(SpiInstancePtr, SpiConfig,
|
||||
SpiConfig->BaseAddress);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Perform a self-test to check hardware build
|
||||
*/
|
||||
Status = XSpiPs_SelfTest(SpiInstancePtr);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Connect the Spi device to the interrupt subsystem such that
|
||||
* interrupts can occur. This function is application specific
|
||||
*/
|
||||
Status = SpiSetupIntrSystem(IntcInstancePtr, SpiInstancePtr, SpiIntrId);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup the handler for the SPI that will be called from the
|
||||
* interrupt context when an SPI status occurs, specify a pointer to
|
||||
* the SPI driver instance as the callback reference so the handler is
|
||||
* able to access the instance data
|
||||
*/
|
||||
XSpiPs_SetStatusHandler(SpiInstancePtr, SpiInstancePtr,
|
||||
(XSpiPs_StatusHandler) SpiHandler);
|
||||
|
||||
/*
|
||||
* Set the Spi device as a master. External loopback is required.
|
||||
*/
|
||||
XSpiPs_SetOptions(SpiInstancePtr, XSPIPS_MASTER_OPTION |
|
||||
XSPIPS_FORCE_SSELECT_OPTION);
|
||||
|
||||
XSpiPs_SetClkPrescaler(SpiInstancePtr, XSPIPS_CLK_PRESCALE_64);
|
||||
|
||||
/*
|
||||
* Initialize the write buffer for a pattern to write to the EEPROM
|
||||
* and the read buffer to zero so it can be verified after the read, the
|
||||
* test value that is added to the unique value allows the value to be
|
||||
* changed in a debug environment to guarantee
|
||||
*/
|
||||
for (UniqueValue = 13, Count = 0; Count < MAX_DATA;
|
||||
Count++, UniqueValue++) {
|
||||
WriteBuffer[WRITE_DATA_OFFSET + Count] =
|
||||
(u8)(UniqueValue + Test);
|
||||
ReadBuffer[READ_DATA_OFFSET + Count] = 0xA5;
|
||||
}
|
||||
|
||||
/*
|
||||
* Assert the EEPROM chip select
|
||||
*/
|
||||
XSpiPs_SetSlaveSelect(SpiInstancePtr, EEPROM_SPI_SELECT);
|
||||
|
||||
/*
|
||||
* Write the data in the write buffer to the serial EEPROM a page at a
|
||||
* time
|
||||
*/
|
||||
for (Page = 0; Page < PAGE_COUNT; Page++) {
|
||||
EepromWrite(SpiInstancePtr, Page * PAGE_SIZE, PAGE_SIZE,
|
||||
&WriteBuffer[Page * PAGE_SIZE]);
|
||||
}
|
||||
|
||||
/*
|
||||
* Read the contents of the entire EEPROM from address 0, since this
|
||||
* function reads the entire EEPROM it will take some amount of time to
|
||||
* complete
|
||||
*/
|
||||
EepromRead(SpiInstancePtr, 0, MAX_DATA, ReadBuffer);
|
||||
|
||||
/*
|
||||
* Setup a pointer to the start of the data that was read into the read
|
||||
* buffer and verify the data read is the data that was written
|
||||
*/
|
||||
BufferPtr = &ReadBuffer[READ_DATA_OFFSET];
|
||||
|
||||
for (UniqueValue = 13, Count = 0; Count < MAX_DATA;
|
||||
Count++, UniqueValue++) {
|
||||
if (BufferPtr[Count] != (u8)(UniqueValue + Test)) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
SpiDisableIntrSystem(IntcInstancePtr, SpiIntrId);
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This function is the handler which performs processing for the SPI driver.
|
||||
* It is called from an interrupt context such that the amount of processing
|
||||
* performed should be minimized. It is called when a transfer of SPI data
|
||||
* completes or an error occurs.
|
||||
*
|
||||
* This handler provides an example of how to handle SPI interrupts
|
||||
* but is application specific.
|
||||
*
|
||||
*
|
||||
* @param CallBackRef is a reference passed to the handler.
|
||||
* @param StatusEvent is the status of the SPI .
|
||||
* @param ByteCount is the number of bytes transferred.
|
||||
*
|
||||
* @return None
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
void SpiHandler(void *CallBackRef, u32 StatusEvent, unsigned int ByteCount)
|
||||
{
|
||||
/*
|
||||
* Indicate the transfer on the SPI bus is no longer in progress
|
||||
* regardless of the status event
|
||||
*/
|
||||
TransferInProgress = FALSE;
|
||||
|
||||
/*
|
||||
* If the event was not transfer done, then track it as an error
|
||||
*/
|
||||
if (StatusEvent != XST_SPI_TRANSFER_DONE) {
|
||||
Error++;
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This function reads from the serial EEPROM connected to the SPI interface.
|
||||
*
|
||||
* @param SpiPtr is a pointer to the SPI driver instance to use.
|
||||
* @param Address contains the address to read data from in the EEPROM.
|
||||
* @param ByteCount contains the number of bytes to read.
|
||||
* @param Buffer is a buffer to read the data into.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
void EepromRead(XSpiPs *SpiPtr, u16 Address, int ByteCount,
|
||||
EepromBuffer Buffer)
|
||||
{
|
||||
/*
|
||||
* Setup the write command with the specified address and data for the
|
||||
* EEPROM
|
||||
*/
|
||||
Buffer[COMMAND_OFFSET] = READ_CMD;
|
||||
Buffer[ADDRESS_MSB_OFFSET] = (u8)((Address & 0xFF00) >> 8);
|
||||
Buffer[ADDRESS_LSB_OFFSET] = (u8)(Address & 0x00FF);
|
||||
|
||||
/*
|
||||
* Send the read command to the EEPROM to read the specified number
|
||||
* of bytes from the EEPROM, send the read command and address and
|
||||
* receive the specified number of bytes of data in the data buffer
|
||||
*/
|
||||
TransferInProgress = TRUE;
|
||||
|
||||
XSpiPs_Transfer(SpiPtr, Buffer, &Buffer[DATA_OFFSET],
|
||||
ByteCount + OVERHEAD_SIZE);
|
||||
|
||||
/*
|
||||
* Wait for the transfer on the SPI bus to be complete before proceeding
|
||||
*/
|
||||
while (TransferInProgress);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
*
|
||||
* This function writes to the serial EEPROM connected to the SPI interface.
|
||||
* This function is not designed to be a driver to handle all
|
||||
* the conditions of the EEPROM device. The EEPROM contains a 32 byte write
|
||||
* buffer which can be filled and then a write is automatically performed by
|
||||
* the device. All the data put into the buffer must be in the same page of
|
||||
* the device with page boundaries being on 32 byte boundaries.
|
||||
*
|
||||
* @param SpiPtr is a pointer to the SPI driver instance to use.
|
||||
* @param Address contains the address to write data to in the EEPROM.
|
||||
* @param ByteCount contains the number of bytes to write.
|
||||
* @param Buffer is a buffer of data to write from.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
void EepromWrite(XSpiPs *SpiPtr, u16 Address, u8 ByteCount,
|
||||
EepromBuffer Buffer)
|
||||
{
|
||||
u8 WriteEnableCmd = { WRITE_ENABLE_CMD };
|
||||
u8 ReadStatusCmd[] = { READ_STATUS_CMD, 0 }; /* must send 2 bytes */
|
||||
u8 EepromStatus[2];
|
||||
int DelayCount = 0;
|
||||
|
||||
/*
|
||||
* Send the write enable command to the SEEPOM so that it can be
|
||||
* written to, this needs to be sent as a seperate transfer before
|
||||
* the write
|
||||
*/
|
||||
TransferInProgress = TRUE;
|
||||
|
||||
XSpiPs_Transfer(SpiPtr, &WriteEnableCmd, NULL, sizeof(WriteEnableCmd));
|
||||
|
||||
/*
|
||||
* Wait for the transfer on the SPI bus to be complete before proceeding
|
||||
*/
|
||||
while (TransferInProgress);
|
||||
|
||||
/*
|
||||
* Setup the write command with the specified address and data for the
|
||||
* EEPROM
|
||||
*/
|
||||
Buffer[COMMAND_OFFSET] = WRITE_CMD;
|
||||
Buffer[ADDRESS_MSB_OFFSET] = (u8)((Address & 0xFF00) >> 8);
|
||||
Buffer[ADDRESS_LSB_OFFSET] = (u8)(Address & 0x00FF);
|
||||
|
||||
/*
|
||||
* Send the write command, address, and data to the EEPROM to be
|
||||
* written, no receive buffer is specified since there is nothing to
|
||||
* receive
|
||||
*/
|
||||
TransferInProgress = TRUE;
|
||||
XSpiPs_Transfer(SpiPtr, Buffer, NULL, ByteCount + OVERHEAD_SIZE);
|
||||
|
||||
while (TransferInProgress);
|
||||
|
||||
/*
|
||||
* Wait for a bit of time to allow the programming to occur as reading
|
||||
* the status while programming causes it to fail because of noisy power
|
||||
* on the board containing the EEPROM, this loop does not need to be
|
||||
* very long but is longer to hopefully work for a faster processor
|
||||
*/
|
||||
while (DelayCount++ < 10000) {
|
||||
}
|
||||
|
||||
/*
|
||||
* Wait for the write command to the EEPROM to be completed, it takes
|
||||
* some time for the data to be written
|
||||
*/
|
||||
while (1) {
|
||||
/*
|
||||
* Poll the status register of the device to determine when it
|
||||
* completes by sending a read status command and receiving the
|
||||
* status byte
|
||||
*/
|
||||
TransferInProgress = TRUE;
|
||||
|
||||
XSpiPs_Transfer(SpiPtr, ReadStatusCmd, EepromStatus,
|
||||
sizeof(ReadStatusCmd));
|
||||
|
||||
/*
|
||||
* Wait for the transfer on the SPI bus to be complete before
|
||||
* proceeding
|
||||
*/
|
||||
while (TransferInProgress);
|
||||
|
||||
/*
|
||||
* If the status indicates the write is done, then stop waiting,
|
||||
* if a value of 0xFF in the status byte is read from the
|
||||
* device and this loop never exits, the device slave select is
|
||||
* possibly incorrect such that the device status is not being
|
||||
* read
|
||||
*/
|
||||
if ((EepromStatus[1] & 0x03) == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function setups the interrupt system for an Spi device.
|
||||
* This function is application specific since the actual system may or may not
|
||||
* have an interrupt controller. The Spi device could be directly connected to
|
||||
* a processor without an interrupt controller. The user should modify this
|
||||
* function to fit the application.
|
||||
*
|
||||
* @param IntcInstancePtr is a pointer to the instance of the Intc device.
|
||||
* @param SpiInstancePtr is a pointer to the instance of the Spi device.
|
||||
* @param SpiIntrId is the interrupt Id for an SPI device.
|
||||
*
|
||||
* @return XST_SUCCESS if successful, otherwise XST_FAILURE.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
static int SpiSetupIntrSystem(XScuGic *IntcInstancePtr,
|
||||
XSpiPs *SpiInstancePtr, u16 SpiIntrId)
|
||||
{
|
||||
int Status;
|
||||
|
||||
#ifndef TESTAPP_GEN
|
||||
XScuGic_Config *IntcConfig; /* Instance of the interrupt controller */
|
||||
|
||||
Xil_ExceptionInit();
|
||||
|
||||
/*
|
||||
* Initialize the interrupt controller driver so that it is ready to
|
||||
* use.
|
||||
*/
|
||||
IntcConfig = XScuGic_LookupConfig(INTC_DEVICE_ID);
|
||||
if (NULL == IntcConfig) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
Status = XScuGic_CfgInitialize(IntcInstancePtr, IntcConfig,
|
||||
IntcConfig->CpuBaseAddress);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Connect the interrupt controller interrupt handler to the hardware
|
||||
* interrupt handling logic in the processor.
|
||||
*/
|
||||
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
|
||||
(Xil_ExceptionHandler)XScuGic_InterruptHandler,
|
||||
IntcInstancePtr);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Connect the device driver handler that will be called when an
|
||||
* interrupt for the device occurs, the handler defined above performs
|
||||
* the specific interrupt processing for the device.
|
||||
*/
|
||||
Status = XScuGic_Connect(IntcInstancePtr, SpiIntrId,
|
||||
(Xil_ExceptionHandler)XSpiPs_InterruptHandler,
|
||||
(void *)SpiInstancePtr);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
/*
|
||||
* Enable the interrupt for the Spi device.
|
||||
*/
|
||||
XScuGic_Enable(IntcInstancePtr, SpiIntrId);
|
||||
|
||||
#ifndef TESTAPP_GEN
|
||||
/*
|
||||
* Enable interrupts in the Processor.
|
||||
*/
|
||||
Xil_ExceptionEnable();
|
||||
#endif
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function disables the interrupts that occur for the Spi device.
|
||||
*
|
||||
* @param IntcInstancePtr is the pointer to a ScuGic driver instance.
|
||||
* @param SpiIntrId is the interrupt Id for an SPI device.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
static void SpiDisableIntrSystem(XScuGic *IntcInstancePtr, u16 SpiIntrId)
|
||||
{
|
||||
/*
|
||||
* Disable the interrupt for the SPI device.
|
||||
*/
|
||||
XScuGic_Disable(IntcInstancePtr, SpiIntrId);
|
||||
|
||||
/*
|
||||
* Disconnect and disable the interrupt for the Spi device.
|
||||
*/
|
||||
XScuGic_Disconnect(IntcInstancePtr, SpiIntrId);
|
||||
}
|
422
XilinxProcessorIPLib/drivers/spips/examples/xspips_eeprom_polled_example.c
Executable file
422
XilinxProcessorIPLib/drivers/spips/examples/xspips_eeprom_polled_example.c
Executable file
|
@ -0,0 +1,422 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2010 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* @file xspi_eeprom_polled_example.c
|
||||
**
|
||||
* This file contains a design example using the SPI driver (XSpiPs) in
|
||||
* polled mode and hardware device with a serial EEPROM device. The
|
||||
* hardware which this example runs on must have a serial EEPROM (Microchip
|
||||
* 25XX320 or 25XX160) for it to run. This example has been tested with the
|
||||
* SPI EEPROM on the EP4.5 ARM processor.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* None.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ---- -------- -----------------------------------------------
|
||||
* 1.00 sdm 03/09/10 First release
|
||||
* 1.00 sdm 10/25/11 Updated the chip select to be used to second chip select
|
||||
*
|
||||
*</pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
#include "xparameters.h" /* EDK generated parameters */
|
||||
#include "xspips.h" /* SPI device driver */
|
||||
#include "xil_printf.h"
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
/*
|
||||
* The following constants map to the XPAR parameters created in the
|
||||
* xparameters.h file. They are defined here such that a user can easily
|
||||
* change all the needed parameters in one place.
|
||||
*/
|
||||
#define SPI_DEVICE_ID XPAR_XSPIPS_0_DEVICE_ID
|
||||
|
||||
/*
|
||||
* The following constants define the commands which may be sent to the EEPROM
|
||||
* device.
|
||||
*/
|
||||
#define WRITE_STATUS_CMD 1
|
||||
#define WRITE_CMD 2
|
||||
#define READ_CMD 3
|
||||
#define WRITE_DISABLE_CMD 4
|
||||
#define READ_STATUS_CMD 5
|
||||
#define WRITE_ENABLE_CMD 6
|
||||
|
||||
/*
|
||||
* The following constants define the offsets within a EepromBuffer data
|
||||
* type for each kind of data. Note that the read data offset is not the
|
||||
* same as the write data because the SPI driver is designed to allow full
|
||||
* duplex transfers such that the number of bytes received is the number
|
||||
* sent and received.
|
||||
*/
|
||||
#define COMMAND_OFFSET 0 /* EEPROM instruction */
|
||||
#define ADDRESS_MSB_OFFSET 1 /* MSB of address to read or write */
|
||||
#define ADDRESS_LSB_OFFSET 2 /* LSB of address to read or write */
|
||||
#define DATA_OFFSET 3
|
||||
#define WRITE_DATA_OFFSET 3 /* Start of data to write to the EEPROM */
|
||||
#define READ_DATA_OFFSET 6 /* Start of data read from the EEPROM */
|
||||
|
||||
/*
|
||||
* The following constants specify the extra bytes which are sent to the
|
||||
* EEPROM on the SPI interface, that are not data, but control information
|
||||
* which includes the command and address
|
||||
*/
|
||||
#define OVERHEAD_SIZE 3
|
||||
|
||||
/*
|
||||
* The following constants specify the page size and number of pages for the
|
||||
* EEPROM. The page size specifies a max number of bytes that can be written
|
||||
* to the EEPROM with a single transfer using the SPI driver.
|
||||
*/
|
||||
#define PAGE_SIZE 16
|
||||
#define PAGE_COUNT 128
|
||||
|
||||
/*
|
||||
* The following constants specify the max amount of data and the size of the
|
||||
* the buffer required to hold the data and overhead to transfer the data to
|
||||
* and from the EEPROM.
|
||||
*/
|
||||
#define MAX_DATA PAGE_COUNT * PAGE_SIZE
|
||||
#define BUFFER_SIZE MAX_DATA + READ_DATA_OFFSET
|
||||
|
||||
/*
|
||||
* The following constant defines the slave select signal that is used to
|
||||
* to select the EEPROM device on the SPI bus, this signal is typically
|
||||
* connected to the chip select of the device
|
||||
*/
|
||||
#define EEPROM_SPI_SELECT 0x01
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
/*
|
||||
* The following data type is used to send and receive data to the serial
|
||||
* EEPROM device connected to the SPI interface. It is an array of bytes
|
||||
* rather than a structure for portability avoiding packing issues. The
|
||||
* application must setup the data to be written in this buffer and retrieve
|
||||
* the data read from it.
|
||||
*/
|
||||
typedef u8 EepromBuffer[BUFFER_SIZE];
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
void EepromRead(XSpiPs *SpiPtr, u16 Address, int ByteCount,
|
||||
EepromBuffer Buffer);
|
||||
|
||||
void EepromWrite(XSpiPs *SpiPtr, u16 Address, u8 ByteCount,
|
||||
EepromBuffer Buffer);
|
||||
|
||||
int SpiPsEepromPolledExample(XSpiPs *SpiInstancePtr, u16 SpiDeviceId);
|
||||
|
||||
/************************** Variable Definitions *****************************/
|
||||
|
||||
/*
|
||||
* The instances to support the device drivers are global such that the
|
||||
* are initialized to zero each time the program runs. They could be local
|
||||
* but should at least be static so they are zeroed.
|
||||
*/
|
||||
static XSpiPs SpiInstance;
|
||||
|
||||
/*
|
||||
* The following variable allows a test value to be added to the values that
|
||||
* are written to the EEPROM such that unique values can be generated to
|
||||
* guarantee the writes to the EEPROM were successful
|
||||
*/
|
||||
int Test;
|
||||
|
||||
/*
|
||||
* The following variables are used to read and write to the eeprom and they
|
||||
* are global to avoid having large buffers on the stack
|
||||
*/
|
||||
EepromBuffer ReadBuffer;
|
||||
EepromBuffer WriteBuffer;
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Main function to call the Spi Eeprom example.
|
||||
*
|
||||
* @param None
|
||||
*
|
||||
* @return XST_SUCCESS if successful, otherwise XST_FAILURE.
|
||||
*
|
||||
* @note None
|
||||
*
|
||||
******************************************************************************/
|
||||
int main(void)
|
||||
{
|
||||
int Status;
|
||||
|
||||
xil_printf("SPI EEPROM Polled Mode Example Test \r\n");
|
||||
|
||||
/*
|
||||
* Run the Spi Interrupt example.
|
||||
*/
|
||||
Status = SpiPsEepromPolledExample(&SpiInstance, SPI_DEVICE_ID);
|
||||
if (Status != XST_SUCCESS) {
|
||||
xil_printf("SPI EEPROM Polled Mode Example Test Failed\r\n");
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
xil_printf("Successfully ran SPI EEPROM Polled Mode Example Test\r\n");
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* The purpose of this function is to illustrate how to use the XSpiPs
|
||||
* device driver in polled mode. This test writes and reads data from a
|
||||
* serial EEPROM. The serial EEPROM part must be present in the hardware
|
||||
* to use this example.
|
||||
*
|
||||
* @param SpiInstancePtr is a pointer to the Spi Instance.
|
||||
* @param SpiDeviceId is the Device Id of Spi.
|
||||
*
|
||||
* @return XST_SUCCESS if successful else XST_FAILURE.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* This function calls functions which contain loops that may be infinite
|
||||
* if interrupts are not working such that it may not return. If the device
|
||||
* slave select is not correct and the device is not responding on bus it will
|
||||
* read a status of 0xFF for the status register as the bus is pulled up.
|
||||
*
|
||||
*****************************************************************************/
|
||||
int SpiPsEepromPolledExample(XSpiPs *SpiInstancePtr, u16 SpiDeviceId)
|
||||
{
|
||||
int Status;
|
||||
u8 *BufferPtr;
|
||||
u8 UniqueValue;
|
||||
int Count;
|
||||
int Page;
|
||||
XSpiPs_Config *SpiConfig;
|
||||
|
||||
/*
|
||||
* Initialize the SPI driver so that it's ready to use
|
||||
*/
|
||||
SpiConfig = XSpiPs_LookupConfig(SpiDeviceId);
|
||||
if (NULL == SpiConfig) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
Status = XSpiPs_CfgInitialize(SpiInstancePtr, SpiConfig,
|
||||
SpiConfig->BaseAddress);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Perform a self-test to check hardware build
|
||||
*/
|
||||
Status = XSpiPs_SelfTest(SpiInstancePtr);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the Spi device as a master. External loopback is required.
|
||||
*/
|
||||
XSpiPs_SetOptions(SpiInstancePtr, XSPIPS_MASTER_OPTION |
|
||||
XSPIPS_FORCE_SSELECT_OPTION);
|
||||
|
||||
XSpiPs_SetClkPrescaler(SpiInstancePtr, XSPIPS_CLK_PRESCALE_64);
|
||||
|
||||
/*
|
||||
* Initialize the write buffer for a pattern to write to the EEPROM
|
||||
* and the read buffer to zero so it can be verified after the read, the
|
||||
* test value that is added to the unique value allows the value to be
|
||||
* changed in a debug environment to guarantee
|
||||
*/
|
||||
for (UniqueValue = 13, Count = 0; Count < MAX_DATA;
|
||||
Count++, UniqueValue++) {
|
||||
WriteBuffer[WRITE_DATA_OFFSET + Count] =
|
||||
(u8)(UniqueValue + Test);
|
||||
ReadBuffer[READ_DATA_OFFSET + Count] = 0xA5;
|
||||
}
|
||||
|
||||
/*
|
||||
* Assert the EEPROM chip select
|
||||
*/
|
||||
XSpiPs_SetSlaveSelect(SpiInstancePtr, EEPROM_SPI_SELECT);
|
||||
|
||||
/*
|
||||
* Write the data in the write buffer to the serial EEPROM a page at a
|
||||
* time, read the data back from the EEPROM and verify it
|
||||
*/
|
||||
UniqueValue = 13;
|
||||
for (Page = 0; Page < PAGE_COUNT; Page++) {
|
||||
EepromWrite(SpiInstancePtr, Page * PAGE_SIZE, PAGE_SIZE,
|
||||
&WriteBuffer[Page * PAGE_SIZE]);
|
||||
EepromRead(SpiInstancePtr, Page * PAGE_SIZE, PAGE_SIZE,
|
||||
ReadBuffer);
|
||||
|
||||
BufferPtr = &ReadBuffer[READ_DATA_OFFSET];
|
||||
for (Count = 0; Count < PAGE_SIZE; Count++, UniqueValue++) {
|
||||
if (BufferPtr[Count] != (u8)(UniqueValue + Test)) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This function reads from the serial EEPROM connected to the SPI interface.
|
||||
*
|
||||
* @param SpiPtr is a pointer to the SPI driver component to use.
|
||||
* @param Address contains the address to read data from in the EEPROM.
|
||||
* @param ByteCount contains the number of bytes to read.
|
||||
* @param Buffer is a buffer to read the data into.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
void EepromRead(XSpiPs *SpiPtr, u16 Address, int ByteCount,
|
||||
EepromBuffer Buffer)
|
||||
{
|
||||
/*
|
||||
* Setup the write command with the specified address and data for the
|
||||
* EEPROM
|
||||
*/
|
||||
Buffer[COMMAND_OFFSET] = READ_CMD;
|
||||
Buffer[ADDRESS_MSB_OFFSET] = (u8)((Address & 0xFF00) >> 8);
|
||||
Buffer[ADDRESS_LSB_OFFSET] = (u8)(Address & 0x00FF);
|
||||
|
||||
/*
|
||||
* Send the read command to the EEPROM to read the specified number
|
||||
* of bytes from the EEPROM, send the read command and address and
|
||||
* receive the specified number of bytes of data in the data buffer
|
||||
*/
|
||||
XSpiPs_PolledTransfer(SpiPtr, Buffer, &Buffer[DATA_OFFSET],
|
||||
ByteCount + OVERHEAD_SIZE);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
*
|
||||
* This function writes to the serial EEPROM connected to the SPI interface.
|
||||
* This function is not designed to be a driver to handle all
|
||||
* the conditions of the EEPROM device. The EEPROM contains a 32 byte write
|
||||
* buffer which can be filled and then a write is automatically performed by
|
||||
* the device. All the data put into the buffer must be in the same page of
|
||||
* the device with page boundaries being on 32 byte boundaries.
|
||||
*
|
||||
* @param SpiPtr is a pointer to the SPI driver instance to use.
|
||||
* @param Address contains the address to write data to in the EEPROM.
|
||||
* @param ByteCount contains the number of bytes to write.
|
||||
* @param Buffer is a buffer of data to write from.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
void EepromWrite(XSpiPs *SpiPtr, u16 Address, u8 ByteCount,
|
||||
EepromBuffer Buffer)
|
||||
{
|
||||
u8 WriteEnableCmd = { WRITE_ENABLE_CMD };
|
||||
u8 ReadStatusCmd[] = { READ_STATUS_CMD, 0 }; /* must send 2 bytes */
|
||||
u8 EepromStatus[2];
|
||||
int DelayCount = 0;
|
||||
|
||||
/*
|
||||
* Send the write enable command to the SEEPOM so that it can be
|
||||
* written to, this needs to be sent as a seperate transfer before
|
||||
* the write
|
||||
*/
|
||||
XSpiPs_PolledTransfer(SpiPtr, &WriteEnableCmd, NULL,
|
||||
sizeof(WriteEnableCmd));
|
||||
|
||||
/*
|
||||
* Setup the write command with the specified address and data for the
|
||||
* EEPROM
|
||||
*/
|
||||
Buffer[COMMAND_OFFSET] = WRITE_CMD;
|
||||
Buffer[ADDRESS_MSB_OFFSET] = (u8)((Address & 0xFF00) >> 8);
|
||||
Buffer[ADDRESS_LSB_OFFSET] = (u8)(Address & 0x00FF);
|
||||
|
||||
/*
|
||||
* Send the write command, address, and data to the EEPROM to be
|
||||
* written, no receive buffer is specified since there is nothing to
|
||||
* receive
|
||||
*/
|
||||
XSpiPs_PolledTransfer(SpiPtr, Buffer, NULL, ByteCount + OVERHEAD_SIZE);
|
||||
|
||||
/*
|
||||
* Wait for a bit of time to allow the programming to occur as reading
|
||||
* the status while programming causes it to fail because of noisy power
|
||||
* on the board containing the EEPROM, this loop does not need to be
|
||||
* very long but is longer to hopefully work for a faster processor
|
||||
*/
|
||||
while (DelayCount++ < 10000) {
|
||||
}
|
||||
|
||||
/*
|
||||
* Wait for the write command to the EEPROM to be completed, it takes
|
||||
* some time for the data to be written
|
||||
*/
|
||||
while (1) {
|
||||
/*
|
||||
* Poll the status register of the device to determine when it
|
||||
* completes by sending a read status command and receiving the
|
||||
* status byte
|
||||
*/
|
||||
XSpiPs_PolledTransfer(SpiPtr, ReadStatusCmd, EepromStatus,
|
||||
sizeof(ReadStatusCmd));
|
||||
|
||||
/*
|
||||
* If the status indicates the write is done, then stop waiting,
|
||||
* if a value of 0xFF in the status byte is read from the
|
||||
* device and this loop never exits, the device slave select is
|
||||
* possibly incorrect such that the device status is not being
|
||||
* read
|
||||
*/
|
||||
if ((EepromStatus[1] & 0x03) == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
976
XilinxProcessorIPLib/drivers/spips/examples/xspips_flash_intr_example.c
Executable file
976
XilinxProcessorIPLib/drivers/spips/examples/xspips_flash_intr_example.c
Executable file
|
@ -0,0 +1,976 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2010 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @file xspips_flash_intr_example.c
|
||||
*
|
||||
*
|
||||
* This file contains a design example using the SPI driver (XSpiPs) in
|
||||
* interrupt mode with a serial flash device. This examples performs
|
||||
* transfers in Manual start mode using interrupts.
|
||||
* The hardware which this example runs on, must have a serial flash
|
||||
* for it to run. This example has been tested with SST25W080.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* None.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- --- -------- -----------------------------------------------
|
||||
* 1.00 sg 1/30/13 First release
|
||||
*
|
||||
*</pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
#include "xparameters.h" /* SDK generated parameters */
|
||||
#include "xspips.h" /* SPI device driver */
|
||||
#include "xscugic.h" /* Interrupt controller device driver */
|
||||
#include "xil_exception.h"
|
||||
#include "xil_printf.h"
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
/*
|
||||
* The following constants map to the XPAR parameters created in the
|
||||
* xparameters.h file. They are defined here such that a user can easily
|
||||
* change all the needed parameters in one place.
|
||||
*/
|
||||
#define SPI_DEVICE_ID XPAR_XSPIPS_0_DEVICE_ID
|
||||
#define INTC_DEVICE_ID XPAR_SCUGIC_SINGLE_DEVICE_ID
|
||||
#define SPI_INTR_ID XPAR_XSPIPS_1_INTR
|
||||
|
||||
/*
|
||||
* The following constants define the commands which may be sent to the flash
|
||||
* device.
|
||||
*/
|
||||
#define WRITE_STATUS_CMD 0x01
|
||||
#define WRITE_CMD 0x02
|
||||
#define READ_CMD 0x03
|
||||
#define WRITE_DISABLE_CMD 0x04
|
||||
#define READ_STATUS_CMD 0x05
|
||||
#define WRITE_ENABLE_CMD 0x06
|
||||
#define FAST_READ_CMD 0x0B
|
||||
#define CHIP_ERASE_CMD 0x60
|
||||
#define BLOCK_ERASE_64K_CMD 0xD8
|
||||
#define READ_ID 0x90
|
||||
|
||||
/*
|
||||
* The following constants define the offsets within a FlashBuffer data
|
||||
* type for each kind of data. Note that the read data offset is not the
|
||||
* same as the write data because the SPI driver is designed to allow full
|
||||
* duplex transfers such that the number of bytes received is the number
|
||||
* sent and received.
|
||||
*/
|
||||
#define COMMAND_OFFSET 0 /* Flash instruction */
|
||||
#define ADDRESS_1_OFFSET 1 /* MSB byte of address to read or write */
|
||||
#define ADDRESS_2_OFFSET 2 /* Middle byte of address to read or write */
|
||||
#define ADDRESS_3_OFFSET 3 /* LSB byte of address to read or write */
|
||||
#define DATA_OFFSET 4 /* Start of Data for Read/Write */
|
||||
#define DUMMY_SIZE 1 /* Number of dummy bytes for fast read */
|
||||
#define RD_ID_SIZE 4 /* Read ID command + 3 bytes ID response */
|
||||
|
||||
|
||||
/*
|
||||
* The following constants specify the extra bytes which are sent to the
|
||||
* flash on the SPI interface, that are not data, but control information
|
||||
* which includes the command and address
|
||||
*/
|
||||
#define OVERHEAD_SIZE 4
|
||||
|
||||
#define UNIQUE_VALUE 0x55
|
||||
|
||||
/*
|
||||
* The following constants specify the max amount of data and the size of the
|
||||
* the buffer required to hold the data and overhead to transfer the data to
|
||||
* and from the flash.
|
||||
*/
|
||||
#define MAX_DATA 1024*1024
|
||||
|
||||
/*
|
||||
* The following constant defines the slave select signal that is used to
|
||||
* to select the flash device on the SPI bus, this signal is typically
|
||||
* connected to the chip select of the device
|
||||
*/
|
||||
#define FLASH_SPI_SELECT 0x01
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
static int SpiPsSetupIntrSystem(XScuGic *IntcInstancePtr,
|
||||
XSpiPs *SpiInstancePtr, u16 SpiIntrId);
|
||||
|
||||
static void SpiPsDisableIntrSystem(XScuGic *IntcInstancePtr, u16 SpiIntrId);
|
||||
|
||||
void SpiPsHandler(void *CallBackRef, u32 StatusEvent, unsigned int ByteCount);
|
||||
|
||||
void FlashErase(XSpiPs *SpiPtr);
|
||||
|
||||
void FlashWrite(XSpiPs *SpiPtr, u32 Address, u32 ByteCount, u8 Command);
|
||||
|
||||
void FlashRead(XSpiPs *SpiPtr, u32 Address, u32 ByteCount, u8 Command);
|
||||
|
||||
int FlashReadID(void);
|
||||
|
||||
int SpiPsFlashIntrExample(XScuGic *IntcInstancePtr, XSpiPs *SpiInstancePtr,
|
||||
u16 SpiDeviceId, u16 SpiIntrId);
|
||||
|
||||
/************************** Variable Definitions *****************************/
|
||||
|
||||
/*
|
||||
* The instances to support the device drivers are global such that they
|
||||
* are initialized to zero each time the program runs. They could be local
|
||||
* but should at least be static so they are zeroed.
|
||||
*/
|
||||
static XScuGic IntcInstance;
|
||||
static XSpiPs SpiInstance;
|
||||
|
||||
/*
|
||||
* The following variables are shared between non-interrupt processing and
|
||||
* interrupt processing such that they must be global.
|
||||
*/
|
||||
volatile int TransferInProgress;
|
||||
|
||||
/*
|
||||
* The following variable tracks any errors that occur during interrupt
|
||||
* processing
|
||||
*/
|
||||
int Error;
|
||||
|
||||
/*
|
||||
* Write Address Location in Serial Flash.
|
||||
*/
|
||||
static int TestAddress;
|
||||
|
||||
/*
|
||||
* The following variables are used to read and write to the eeprom and they
|
||||
* are global to avoid having large buffers on the stack
|
||||
*/
|
||||
u8 ReadBuffer[MAX_DATA + DATA_OFFSET + DUMMY_SIZE];
|
||||
u8 WriteBuffer[MAX_DATA + DATA_OFFSET];
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Main function to call the SPI Flash example.
|
||||
*
|
||||
* @param None
|
||||
*
|
||||
* @return
|
||||
* - XST_SUCCESS if successful
|
||||
* - XST_FAILURE if not successful
|
||||
*
|
||||
* @note None
|
||||
*
|
||||
******************************************************************************/
|
||||
int main(void)
|
||||
{
|
||||
int Status;
|
||||
|
||||
xil_printf("SPI FLASH Interrupt Example Test \r\n");
|
||||
|
||||
/*
|
||||
* Run the Spi Interrupt example.
|
||||
*/
|
||||
Status = SpiPsFlashIntrExample(&IntcInstance, &SpiInstance,
|
||||
SPI_DEVICE_ID, SPI_INTR_ID);
|
||||
if (Status != XST_SUCCESS) {
|
||||
xil_printf("SPI FLASH Interrupt Example Test Failed\r\n");
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
xil_printf("Successfully ran SPI FLASH Interrupt Example Test\r\n");
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* The purpose of this function is to illustrate how to use the XSpiPs
|
||||
* device driver in interrupt mode. This function writes and reads data
|
||||
* from a serial flash.
|
||||
*
|
||||
* @param IntcInstancePtr is a pointer to Interrupt Controller instance.
|
||||
*
|
||||
* @param SpiInstancePtr is a pointer to the SPI driver instance to use.
|
||||
*
|
||||
* @param SpiDeviceId is the Instance Id of SPI in the system.
|
||||
*
|
||||
* @param SpiIntrId is the Interrupt Id for SPI in the system.
|
||||
*
|
||||
* @param None.
|
||||
*
|
||||
* @return
|
||||
* - XST_SUCCESS if successful
|
||||
* - XST_FAILURE if not successful
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* This function calls other functions which contain loops that may be infinite
|
||||
* if interrupts are not working such that it may not return. If the device
|
||||
* slave select is not correct and the device is not responding on bus it will
|
||||
* read a status of 0xFF for the status register as the bus is pulled up.
|
||||
*
|
||||
*****************************************************************************/
|
||||
int SpiPsFlashIntrExample(XScuGic *IntcInstancePtr, XSpiPs *SpiInstancePtr,
|
||||
u16 SpiDeviceId, u16 SpiIntrId)
|
||||
{
|
||||
int Status;
|
||||
u8 *BufferPtr;
|
||||
u8 UniqueValue;
|
||||
u32 Count;
|
||||
XSpiPs_Config *SpiConfig;
|
||||
|
||||
/*
|
||||
* Initialize the SPI driver so that it's ready to use
|
||||
*/
|
||||
SpiConfig = XSpiPs_LookupConfig(SpiDeviceId);
|
||||
if (NULL == SpiConfig) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
Status = XSpiPs_CfgInitialize(SpiInstancePtr, SpiConfig,
|
||||
SpiConfig->BaseAddress);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Perform a self-test to check hardware build
|
||||
*/
|
||||
Status = XSpiPs_SelfTest(SpiInstancePtr);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Connect the Spi device to the interrupt subsystem such that
|
||||
* interrupts can occur. This function is application specific
|
||||
*/
|
||||
Status = SpiPsSetupIntrSystem(IntcInstancePtr, SpiInstancePtr,
|
||||
SpiIntrId);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup the handler for the SPI that will be called from the
|
||||
* interrupt context when an SPI status occurs, specify a pointer to
|
||||
* the SPI driver instance as the callback reference so the handler is
|
||||
* able to access the instance data
|
||||
*/
|
||||
XSpiPs_SetStatusHandler(SpiInstancePtr, SpiInstancePtr,
|
||||
(XSpiPs_StatusHandler) SpiPsHandler);
|
||||
|
||||
/*
|
||||
* Set the SPI device as a master with manual start and manual
|
||||
* chip select mode options
|
||||
*/
|
||||
XSpiPs_SetOptions(SpiInstancePtr, XSPIPS_MANUAL_START_OPTION | \
|
||||
XSPIPS_MASTER_OPTION | XSPIPS_FORCE_SSELECT_OPTION);
|
||||
|
||||
/*
|
||||
* Set the SPI device pre-scalar to divide by 8
|
||||
*/
|
||||
XSpiPs_SetClkPrescaler(SpiInstancePtr, XSPIPS_CLK_PRESCALE_8);
|
||||
|
||||
memset(WriteBuffer, 0x00, sizeof(WriteBuffer));
|
||||
memset(ReadBuffer, 0x00, sizeof(ReadBuffer));
|
||||
|
||||
/*
|
||||
* Initialize the write buffer for a pattern to write to the flash
|
||||
* and the read buffer to zero so it can be verified after the read, the
|
||||
* test value that is added to the unique value allows the value to be
|
||||
* changed in a debug environment to guarantee
|
||||
*/
|
||||
for (UniqueValue = UNIQUE_VALUE, Count = 0; Count < MAX_DATA;
|
||||
Count++, UniqueValue++) {
|
||||
WriteBuffer[DATA_OFFSET + Count] = (u8)(UniqueValue);
|
||||
}
|
||||
|
||||
/*
|
||||
* Assert the flash chip select
|
||||
*/
|
||||
XSpiPs_SetSlaveSelect(SpiInstancePtr, FLASH_SPI_SELECT);
|
||||
|
||||
/*
|
||||
* Read the flash ID
|
||||
*/
|
||||
Status = FlashReadID();
|
||||
if (Status != XST_SUCCESS) {
|
||||
xil_printf("SPI FLASH Interrupt Example Read ID Failed\r\n");
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Erase the flash
|
||||
*/
|
||||
FlashErase(SpiInstancePtr);
|
||||
|
||||
/*
|
||||
* Write the data in the write buffer to TestAddress in serial flash
|
||||
*/
|
||||
FlashWrite(SpiInstancePtr, TestAddress, MAX_DATA, WRITE_CMD);
|
||||
|
||||
/*
|
||||
* Read the contents of the flash from TestAddress of size MAX_DATA
|
||||
* using Normal Read command
|
||||
*/
|
||||
FlashRead(SpiInstancePtr, TestAddress, MAX_DATA, READ_CMD);
|
||||
|
||||
/*
|
||||
* Setup a pointer to the start of the data that was read into the read
|
||||
* buffer and verify the data read is the data that was written
|
||||
*/
|
||||
BufferPtr = &ReadBuffer[DATA_OFFSET];
|
||||
for (UniqueValue = UNIQUE_VALUE, Count = 0; Count < MAX_DATA;
|
||||
Count++, UniqueValue++) {
|
||||
if (BufferPtr[Count] != (u8)(UniqueValue)) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the SPI device as a master with auto start and manual
|
||||
* chip select mode options
|
||||
*/
|
||||
XSpiPs_SetOptions(SpiInstancePtr, XSPIPS_MASTER_OPTION | \
|
||||
XSPIPS_FORCE_SSELECT_OPTION);
|
||||
|
||||
memset(WriteBuffer, 0x00, sizeof(WriteBuffer));
|
||||
memset(ReadBuffer, 0x00, sizeof(ReadBuffer));
|
||||
|
||||
/*
|
||||
* Initialize the write buffer for a pattern to write to the flash
|
||||
* and the read buffer to zero so it can be verified after the read, the
|
||||
* test value that is added to the unique value allows the value to be
|
||||
* changed in a debug environment to guarantee
|
||||
*/
|
||||
for (UniqueValue = UNIQUE_VALUE, Count = 0; Count < MAX_DATA;
|
||||
Count++, UniqueValue++) {
|
||||
WriteBuffer[DATA_OFFSET + Count] = (u8)(UniqueValue);
|
||||
}
|
||||
|
||||
/*
|
||||
* Erase the flash
|
||||
*/
|
||||
FlashErase(SpiInstancePtr);
|
||||
|
||||
/*
|
||||
* Write the data in the write buffer to TestAddress in serial flash
|
||||
*/
|
||||
FlashWrite(SpiInstancePtr, TestAddress, MAX_DATA, WRITE_CMD);
|
||||
|
||||
/*
|
||||
* Read the contents of the flash from TestAddress of size MAX_DATA
|
||||
* using Normal Read command
|
||||
*/
|
||||
FlashRead(SpiInstancePtr, TestAddress, MAX_DATA, READ_CMD);
|
||||
|
||||
/*
|
||||
* Setup a pointer to the start of the data that was read into the read
|
||||
* buffer and verify the data read is the data that was written
|
||||
*/
|
||||
BufferPtr = &ReadBuffer[DATA_OFFSET];
|
||||
for (UniqueValue = UNIQUE_VALUE, Count = 0; Count < MAX_DATA;
|
||||
Count++, UniqueValue++) {
|
||||
if (BufferPtr[Count] != (u8)(UniqueValue)) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
SpiPsDisableIntrSystem(IntcInstancePtr, SpiIntrId);
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This function is the handler which performs processing for the SPI driver.
|
||||
* It is called from an interrupt context such that the amount of processing
|
||||
* performed should be minimized. It is called when a transfer of SPI data
|
||||
* completes or an error occurs.
|
||||
*
|
||||
* This handler provides an example of how to handle SPI interrupts but is
|
||||
* application specific.
|
||||
*
|
||||
* @param CallBackRef is a reference passed to the handler.
|
||||
* @param StatusEvent is the status of the SPI .
|
||||
* @param ByteCount is the number of bytes transferred.
|
||||
*
|
||||
* @return None
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
void SpiPsHandler(void *CallBackRef, u32 StatusEvent, unsigned int ByteCount)
|
||||
{
|
||||
/*
|
||||
* Indicate the transfer on the SPI bus is no longer in progress
|
||||
* regardless of the status event
|
||||
*/
|
||||
TransferInProgress = FALSE;
|
||||
|
||||
/*
|
||||
* If the event was not transfer done, then track it as an error
|
||||
*/
|
||||
if (StatusEvent != XST_SPI_TRANSFER_DONE) {
|
||||
Error++;
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
*
|
||||
* This function writes to the serial flash connected to the SPI interface.
|
||||
* The flash contains a 256 byte write buffer which can be filled and then a
|
||||
* write is automatically performed by the device. All the data put into the
|
||||
* buffer must be in the same page of the device with page boundaries being on
|
||||
* 256 byte boundaries.
|
||||
*
|
||||
* @param SpiPtr is a pointer to the SPI driver component to use.
|
||||
* @param Address contains the address to write data to in the flash.
|
||||
* @param ByteCount contains the number of bytes to write.
|
||||
* @param Command is the command used to write data to the flash. SPI
|
||||
* device supports only Page Program command to write data to the
|
||||
* flash.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
void FlashWrite(XSpiPs *SpiPtr, u32 Address, u32 ByteCount, u8 Command)
|
||||
{
|
||||
u8 WriteEnableCmd = { WRITE_ENABLE_CMD };
|
||||
u8 WriteDisableCmd = { WRITE_DISABLE_CMD };
|
||||
u8 ReadStatusCmd[] = { READ_STATUS_CMD, 0 }; /* must send 2 bytes */
|
||||
u8 FlashStatus[2];
|
||||
u32 Temp = 0;
|
||||
u32 TempAddress = Address;
|
||||
u8 TempBuffer[5];
|
||||
|
||||
if (Command == WRITE_CMD) {
|
||||
for (Temp = 0; Temp < ByteCount ; Temp++, TempAddress++) {
|
||||
/*
|
||||
* Send the write enable command to the flash so
|
||||
* that it can be written to, this needs to be sent
|
||||
* as a seperate transfer before the write
|
||||
*/
|
||||
TransferInProgress = TRUE;
|
||||
|
||||
XSpiPs_Transfer(SpiPtr, &WriteEnableCmd, NULL,
|
||||
sizeof(WriteEnableCmd));
|
||||
|
||||
/*
|
||||
* Wait for the transfer on the SPI bus to be complete before
|
||||
* proceeding
|
||||
*/
|
||||
while (TransferInProgress);
|
||||
|
||||
/*
|
||||
* Setup the write command with the specified address
|
||||
* and data for the flash
|
||||
*/
|
||||
TempBuffer[COMMAND_OFFSET] = Command;
|
||||
TempBuffer[ADDRESS_1_OFFSET] =
|
||||
(u8)((TempAddress & 0xFF0000) >> 16);
|
||||
TempBuffer[ADDRESS_2_OFFSET] =
|
||||
(u8)((TempAddress & 0xFF00) >> 8);
|
||||
TempBuffer[ADDRESS_3_OFFSET] =
|
||||
(u8)(TempAddress & 0xFF);
|
||||
TempBuffer[DATA_OFFSET] =
|
||||
WriteBuffer[DATA_OFFSET + Temp];
|
||||
|
||||
/*
|
||||
* Send the write command, address, and data to the
|
||||
* flash to be written, no receive buffer is specified
|
||||
* since there is nothing to receive
|
||||
*/
|
||||
TransferInProgress = TRUE;
|
||||
|
||||
XSpiPs_Transfer(SpiPtr, TempBuffer, NULL, 5);
|
||||
|
||||
while (TransferInProgress);
|
||||
|
||||
|
||||
/*
|
||||
* Wait for the write command to the flash to be ,
|
||||
* completed it takes some time for the data to be
|
||||
* written
|
||||
*/
|
||||
while (1) {
|
||||
/*
|
||||
* Poll the status register of the flash to
|
||||
* determine when it completes, by sending
|
||||
* a read status command and receiving the
|
||||
* status byte
|
||||
*/
|
||||
TransferInProgress = TRUE;
|
||||
|
||||
XSpiPs_Transfer(SpiPtr, ReadStatusCmd,
|
||||
FlashStatus, sizeof(ReadStatusCmd));
|
||||
|
||||
/*
|
||||
* Wait for the transfer on the SPI bus
|
||||
* to be complete before proceeding
|
||||
*/
|
||||
while (TransferInProgress);
|
||||
|
||||
/*
|
||||
* If the status indicates the write is done,
|
||||
* then stop waiting, if a value of 0xFF in
|
||||
* the status byte is read from the device
|
||||
* and this loop never exits, the device slave
|
||||
* select is possibly incorrect such that the
|
||||
* device status is not being read
|
||||
*/
|
||||
if ((FlashStatus[1] & 0x01) == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
TransferInProgress = TRUE;
|
||||
|
||||
XSpiPs_Transfer(SpiPtr, &WriteDisableCmd, NULL,
|
||||
sizeof(WriteDisableCmd));
|
||||
|
||||
/*
|
||||
* Wait for the transfer on the SPI bus to be complete
|
||||
* before proceeding
|
||||
*/
|
||||
while (TransferInProgress);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This function reads from the serial flash connected to the
|
||||
* SPI interface.
|
||||
*
|
||||
* @param SpiPtr is a pointer to the SPI driver component to use.
|
||||
* @param Address contains the address to read data from in the flash.
|
||||
* @param ByteCount contains the number of bytes to read.
|
||||
* @param Command is the command used to read data from the flash. SPI
|
||||
* device supports one of the Read, Fast Read, Dual Read and Fast
|
||||
* Read commands to read data from the flash.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
void FlashRead(XSpiPs *SpiPtr, u32 Address, u32 ByteCount, u8 Command)
|
||||
{
|
||||
/*
|
||||
* Setup the write command with the specified address and data for the
|
||||
* flash
|
||||
*/
|
||||
WriteBuffer[COMMAND_OFFSET] = Command;
|
||||
WriteBuffer[ADDRESS_1_OFFSET] = (u8)((Address & 0xFF0000) >> 16);
|
||||
WriteBuffer[ADDRESS_2_OFFSET] = (u8)((Address & 0xFF00) >> 8);
|
||||
WriteBuffer[ADDRESS_3_OFFSET] = (u8)(Address & 0xFF);
|
||||
|
||||
/*
|
||||
* Send the read command to the flash to read the specified number
|
||||
* of bytes from the flash, send the read command and address and
|
||||
* receive the specified number of bytes of data in the data buffer
|
||||
*/
|
||||
TransferInProgress = TRUE;
|
||||
|
||||
XSpiPs_Transfer(SpiPtr, WriteBuffer, ReadBuffer,
|
||||
ByteCount + OVERHEAD_SIZE);
|
||||
|
||||
/*
|
||||
* Wait for the transfer on the SPI bus to be complete before
|
||||
* proceeding
|
||||
*/
|
||||
while (TransferInProgress);
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This function reads serial flash ID connected to the SPI interface.
|
||||
*
|
||||
* @param None.
|
||||
*
|
||||
* @return
|
||||
* - XST_SUCCESS if successful
|
||||
* - XST_FAILURE if not successful
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
int FlashReadID(void)
|
||||
{
|
||||
u8 Index;
|
||||
u8 ByteCount = 4;
|
||||
u8 SendBuffer[8];
|
||||
u8 RecvBuffer[8];
|
||||
|
||||
SendBuffer[0] = READ_ID;
|
||||
SendBuffer[1] = 0;
|
||||
SendBuffer[2] = 0;
|
||||
SendBuffer[3] = 0;
|
||||
|
||||
for(Index=0; Index < ByteCount; Index++) {
|
||||
SendBuffer[4 + Index] = 0x00;
|
||||
}
|
||||
|
||||
TransferInProgress = TRUE;
|
||||
|
||||
XSpiPs_Transfer(&SpiInstance, SendBuffer, RecvBuffer,
|
||||
(4 + ByteCount));
|
||||
|
||||
while (TransferInProgress);
|
||||
|
||||
for(Index=0; Index < ByteCount; Index++) {
|
||||
xil_printf("ID : %0x\r\n", RecvBuffer[4 + Index]);
|
||||
}
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
*
|
||||
* This function erases the sectors in the serial flash connected to the
|
||||
* SPI interface.
|
||||
*
|
||||
* @param SpiPtr is a pointer to the SPI driver component to use.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
void FlashErase(XSpiPs *SpiPtr)
|
||||
{
|
||||
u8 WriteEnableCmd = { WRITE_ENABLE_CMD };
|
||||
u8 ReadStatusCmd[] = { READ_STATUS_CMD, 0 }; /* must send 2 bytes */
|
||||
/* must send 2 bytes */
|
||||
u8 WriteStatusCmd[] = { WRITE_STATUS_CMD, 0x0 };
|
||||
u8 FlashStatus[2];
|
||||
|
||||
/*
|
||||
* Send the write enable command to the flash so that it can be
|
||||
* written to, this needs to be sent as a seperate transfer
|
||||
* before the erase
|
||||
*/
|
||||
TransferInProgress = TRUE;
|
||||
|
||||
XSpiPs_Transfer(SpiPtr, &WriteEnableCmd, NULL, sizeof(WriteEnableCmd));
|
||||
/*
|
||||
* Wait for the transfer on the SPI bus to be complete before
|
||||
* proceeding
|
||||
*/
|
||||
while (TransferInProgress);
|
||||
|
||||
/*
|
||||
* Wait for write enable command to the flash to be completed
|
||||
*/
|
||||
while (1) {
|
||||
/*
|
||||
* Poll the status register of the device to determine
|
||||
* when it completes, by sending a read status command
|
||||
* and receiving the status byte
|
||||
*/
|
||||
TransferInProgress = TRUE;
|
||||
|
||||
XSpiPs_Transfer(SpiPtr, ReadStatusCmd, FlashStatus,
|
||||
sizeof(ReadStatusCmd));
|
||||
|
||||
/*
|
||||
* Wait for the transfer on the SPI bus to be complete
|
||||
* before proceeding
|
||||
*/
|
||||
while (TransferInProgress);
|
||||
|
||||
/*
|
||||
* If the status indicates the write is done, then stop
|
||||
* waiting; if a value of 0xFF in the status byte is
|
||||
* read from the device and this loop never exits, the
|
||||
* device slave select is possibly incorrect such that
|
||||
* the device status is not being read
|
||||
*/
|
||||
if ((FlashStatus[1] & 0x02) == 0x02) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Clear write protect bits using write status command to the flash
|
||||
* this needs to be sent as a seperate transfer before the erase
|
||||
*/
|
||||
TransferInProgress = TRUE;
|
||||
|
||||
XSpiPs_Transfer(SpiPtr, WriteStatusCmd, NULL, sizeof(WriteStatusCmd));
|
||||
/*
|
||||
* Wait for the transfer on the SPI bus to be complete before
|
||||
* proceeding
|
||||
*/
|
||||
while (TransferInProgress);
|
||||
|
||||
/*
|
||||
* Check for write status command to the flash to be completed
|
||||
*/
|
||||
while (1) {
|
||||
/*
|
||||
* Poll the status register of the device to determine
|
||||
* when it completes, by sending a read status command
|
||||
* and receiving the status byte
|
||||
*/
|
||||
TransferInProgress = TRUE;
|
||||
|
||||
XSpiPs_Transfer(SpiPtr, ReadStatusCmd, FlashStatus,
|
||||
sizeof(ReadStatusCmd));
|
||||
|
||||
/*
|
||||
* Wait for the transfer on the SPI bus to be complete
|
||||
* before proceeding
|
||||
*/
|
||||
while (TransferInProgress);
|
||||
|
||||
/*
|
||||
* If the status indicates the write is done, then stop
|
||||
* waiting; if a value of 0xFF in the status byte is
|
||||
* read from the device and this loop never exits, the
|
||||
* device slave select is possibly incorrect such that
|
||||
* the device status is not being read
|
||||
*/
|
||||
if ((FlashStatus[1] & 0x1C) == 0x0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Send the write enable command to the flash so that it can be
|
||||
* written to, this needs to be sent as a seperate transfer
|
||||
* before the erase
|
||||
*/
|
||||
TransferInProgress = TRUE;
|
||||
|
||||
XSpiPs_Transfer(SpiPtr, &WriteEnableCmd, NULL, sizeof(WriteEnableCmd));
|
||||
/*
|
||||
* Wait for the transfer on the SPI bus to be complete before
|
||||
* proceeding
|
||||
*/
|
||||
while (TransferInProgress);
|
||||
|
||||
/*
|
||||
* Wait for write enable command to the flash to be completed
|
||||
*/
|
||||
while (1) {
|
||||
/*
|
||||
* Poll the status register of the device to determine
|
||||
* when it completes, by sending a read status command
|
||||
* and receiving the status byte
|
||||
*/
|
||||
TransferInProgress = TRUE;
|
||||
|
||||
XSpiPs_Transfer(SpiPtr, ReadStatusCmd, FlashStatus,
|
||||
sizeof(ReadStatusCmd));
|
||||
|
||||
/*
|
||||
* Wait for the transfer on the SPI bus to be complete
|
||||
* before proceeding
|
||||
*/
|
||||
while (TransferInProgress);
|
||||
|
||||
/*
|
||||
* If the status indicates the write is done, then stop
|
||||
* waiting; if a value of 0xFF in the status byte is
|
||||
* read from the device and this loop never exits, the
|
||||
* device slave select is possibly incorrect such that
|
||||
* the device status is not being read
|
||||
*/
|
||||
if ((FlashStatus[1] & 0x02) == 0x02) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup the bulk erase or chip-erase command
|
||||
*/
|
||||
WriteBuffer[COMMAND_OFFSET] = CHIP_ERASE_CMD;
|
||||
|
||||
/*
|
||||
* Send the bulk erase command; no receive buffer is specified
|
||||
* since there is nothing to receive
|
||||
*/
|
||||
TransferInProgress = TRUE;
|
||||
|
||||
XSpiPs_Transfer(SpiPtr, WriteBuffer, NULL, 1);
|
||||
|
||||
while (TransferInProgress);
|
||||
|
||||
/*
|
||||
* Wait for the erase command to the flash to be completed
|
||||
*/
|
||||
while (1) {
|
||||
/*
|
||||
* Poll the status register of the device to determine
|
||||
* when it completes, by sending a read status command
|
||||
* and receiving the status byte
|
||||
*/
|
||||
TransferInProgress = TRUE;
|
||||
|
||||
XSpiPs_Transfer(SpiPtr, ReadStatusCmd, FlashStatus,
|
||||
sizeof(ReadStatusCmd));
|
||||
|
||||
/*
|
||||
* Wait for the transfer on the SPI bus to be complete
|
||||
* before proceeding
|
||||
*/
|
||||
while (TransferInProgress);
|
||||
|
||||
/*
|
||||
* If the status indicates the write is done, then stop
|
||||
* waiting; if a value of 0xFF in the status byte is
|
||||
* read from the device and this loop never exits, the
|
||||
* device slave select is possibly incorrect such that
|
||||
* the device status is not being read
|
||||
*/
|
||||
if ((FlashStatus[1] & 0x01) == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function setups the interrupt system for an Spi device.
|
||||
*
|
||||
* @param IntcInstancePtr is a pointer to the instance of the Intc device.
|
||||
* @param SpiInstancePtr is a pointer to the instance of the Spi device.
|
||||
* @param SpiIntrId is the interrupt Id for an SPI device.
|
||||
*
|
||||
* @return
|
||||
* - XST_SUCCESS if successful
|
||||
* - XST_FAILURE if not successful
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
static int SpiPsSetupIntrSystem(XScuGic *IntcInstancePtr,
|
||||
XSpiPs *SpiInstancePtr, u16 SpiIntrId)
|
||||
{
|
||||
int Status;
|
||||
|
||||
XScuGic_Config *IntcConfig; /* Instance of the interrupt controller */
|
||||
|
||||
Xil_ExceptionInit();
|
||||
|
||||
/*
|
||||
* Initialize the interrupt controller driver so that it is ready to
|
||||
* use.
|
||||
*/
|
||||
IntcConfig = XScuGic_LookupConfig(INTC_DEVICE_ID);
|
||||
if (NULL == IntcConfig) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
Status = XScuGic_CfgInitialize(IntcInstancePtr, IntcConfig,
|
||||
IntcConfig->CpuBaseAddress);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Connect the interrupt controller interrupt handler to the hardware
|
||||
* interrupt handling logic in the processor.
|
||||
*/
|
||||
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
|
||||
(Xil_ExceptionHandler)XScuGic_InterruptHandler,
|
||||
IntcInstancePtr);
|
||||
|
||||
/*
|
||||
* Connect the device driver handler that will be called when an
|
||||
* interrupt for the device occurs, the handler defined above performs
|
||||
* the specific interrupt processing for the device.
|
||||
*/
|
||||
Status = XScuGic_Connect(IntcInstancePtr, SpiIntrId,
|
||||
(Xil_ExceptionHandler)XSpiPs_InterruptHandler,
|
||||
(void *)SpiInstancePtr);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
/*
|
||||
* Enable the interrupt for the Spi device.
|
||||
*/
|
||||
XScuGic_Enable(IntcInstancePtr, SpiIntrId);
|
||||
|
||||
/*
|
||||
* Enable interrupts in the Processor.
|
||||
*/
|
||||
Xil_ExceptionEnable();
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function disables the interrupts that occur for the Spi device.
|
||||
*
|
||||
* @param IntcInstancePtr is the pointer to an INTC instance.
|
||||
* @param SpiIntrId is the interrupt Id for an SPI device.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
static void SpiPsDisableIntrSystem(XScuGic *IntcInstancePtr, u16 SpiIntrId)
|
||||
{
|
||||
/*
|
||||
* Disable the interrupt for the SPI device.
|
||||
*/
|
||||
XScuGic_Disable(IntcInstancePtr, SpiIntrId);
|
||||
|
||||
/*
|
||||
* Disconnect and disable the interrupt for the Spi device.
|
||||
*/
|
||||
XScuGic_Disconnect(IntcInstancePtr, SpiIntrId);
|
||||
}
|
659
XilinxProcessorIPLib/drivers/spips/examples/xspips_flash_polled_example.c
Executable file
659
XilinxProcessorIPLib/drivers/spips/examples/xspips_flash_polled_example.c
Executable file
|
@ -0,0 +1,659 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2010 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @file xspips_polled_example.c
|
||||
*
|
||||
*
|
||||
* This file contains a design example using the SPI driver (XSpiPs) in
|
||||
* polled mode with a Serial Flash device. This examples performs
|
||||
* transfers in polled mode.
|
||||
* The hardware which this example runs on, must have a Serial Flash
|
||||
* for it to run. This example has been tested with SST25W080.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* None.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- --- -------- -----------------------------------------------
|
||||
* 1.00 sg 1/30/13 First release
|
||||
*
|
||||
*</pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
#include "xparameters.h" /* SDK generated parameters */
|
||||
#include "xspips.h" /* SPI device driver */
|
||||
#include "xil_printf.h"
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
/*
|
||||
* The following constants map to the XPAR parameters created in the
|
||||
* xparameters.h file. They are defined here such that a user can easily
|
||||
* change all the needed parameters in one place.
|
||||
*/
|
||||
#define SPI_DEVICE_ID XPAR_XSPIPS_0_DEVICE_ID
|
||||
|
||||
/*
|
||||
* The following constants define the commands which may be sent to the flash
|
||||
* device.
|
||||
*/
|
||||
#define WRITE_STATUS_CMD 0x01
|
||||
#define WRITE_CMD 0x02
|
||||
#define READ_CMD 0x03
|
||||
#define WRITE_DISABLE_CMD 0x04
|
||||
#define READ_STATUS_CMD 0x05
|
||||
#define WRITE_ENABLE_CMD 0x06
|
||||
#define FAST_READ_CMD 0x0B
|
||||
#define CHIP_ERASE_CMD 0x60
|
||||
#define BULK_ERASE_CMD 0xC7
|
||||
#define BLOCK_ERASE_64K_CMD 0xD8
|
||||
#define READ_ID 0x90
|
||||
#define AAI_WRITE_CMD 0xAD
|
||||
|
||||
/*
|
||||
* The following constants define the offsets within a FlashBuffer data
|
||||
* type for each kind of data. Note that the read data offset is not the
|
||||
* same as the write data because the SPI driver is designed to allow full
|
||||
* duplex transfers such that the number of bytes received is the number
|
||||
* sent and received.
|
||||
*/
|
||||
#define COMMAND_OFFSET 0 /* Flash instruction */
|
||||
#define ADDRESS_1_OFFSET 1 /* MSB byte of address to read or write */
|
||||
#define ADDRESS_2_OFFSET 2 /* Middle byte of address to read or write */
|
||||
#define ADDRESS_3_OFFSET 3 /* LSB byte of address to read or write */
|
||||
#define DATA_OFFSET 4 /* Start of Data for Read/Write */
|
||||
#define DUMMY_SIZE 1 /* Number of dummy bytes for fast read */
|
||||
#define RD_ID_SIZE 4 /* Read ID command + 3 bytes ID response */
|
||||
|
||||
/*
|
||||
* The following constants specify the extra bytes which are sent to the
|
||||
* flash on the SPI interface, that are not data, but control information
|
||||
* which includes the command and address
|
||||
*/
|
||||
#define OVERHEAD_SIZE 4
|
||||
|
||||
#define UNIQUE_VALUE 0x05
|
||||
|
||||
/*
|
||||
* The following constants specify the max amount of data and the size of the
|
||||
* the buffer required to hold the data and overhead to transfer the data to
|
||||
* and from the flash.
|
||||
*/
|
||||
#define MAX_DATA 1024*1024
|
||||
|
||||
/*
|
||||
* The following constant defines the slave select signal that is used to
|
||||
* to select the flash device on the SPI bus, this signal is typically
|
||||
* connected to the chip select of the device
|
||||
*/
|
||||
#define FLASH_SPI_SELECT 0x01
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
void FlashErase(XSpiPs *SpiPtr);
|
||||
|
||||
void FlashWrite(XSpiPs *SpiPtr, u32 Address, u32 ByteCount, u8 Command);
|
||||
|
||||
void FlashRead(XSpiPs *SpiPtr, u32 Address, u32 ByteCount, u8 Command);
|
||||
|
||||
int SpiPsFlashPolledExample(XSpiPs *SpiInstancePtr, u16 SpiDeviceId);
|
||||
|
||||
int FlashReadID(void);
|
||||
|
||||
/************************** Variable Definitions *****************************/
|
||||
|
||||
/*
|
||||
* The instances to support the device drivers are global such that they
|
||||
* are initialized to zero each time the program runs. They could be local
|
||||
* but should at least be static so they are zeroed.
|
||||
*/
|
||||
static XSpiPs SpiInstance;
|
||||
|
||||
/*
|
||||
* Write Address Location in Serial Flash.
|
||||
*/
|
||||
static int TestAddress;
|
||||
|
||||
/*
|
||||
* The following variables are used to read and write to the eeprom and they
|
||||
* are global to avoid having large buffers on the stack
|
||||
*/
|
||||
u8 ReadBuffer[MAX_DATA + DATA_OFFSET + DUMMY_SIZE];
|
||||
u8 WriteBuffer[MAX_DATA + DATA_OFFSET];
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Main function to call the SPI Flash Polled Example.
|
||||
*
|
||||
* @param None
|
||||
*
|
||||
* @return
|
||||
* - XST_SUCCESS if successful
|
||||
* - XST_FAILURE if not successful
|
||||
*
|
||||
* @note None
|
||||
*
|
||||
******************************************************************************/
|
||||
int main(void)
|
||||
{
|
||||
int Status;
|
||||
|
||||
xil_printf("SPI SerialFlash Polled Example Test \r\n");
|
||||
|
||||
/*
|
||||
* Run the Spi Polled example.
|
||||
*/
|
||||
Status = SpiPsFlashPolledExample(&SpiInstance,SPI_DEVICE_ID);
|
||||
if (Status != XST_SUCCESS) {
|
||||
xil_printf("SPI SerialFlash Polled Example Test Failed\r\n");
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
xil_printf("Successfully ran SPI SerialFlash Polled Example Test\r\n");
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* The purpose of this function is to illustrate how to use the XSpiPs
|
||||
* device driver in polled mode. This function writes and reads data
|
||||
* from a serial flash.
|
||||
*
|
||||
* @param SpiPtr is a pointer to the SPI driver instance to use.
|
||||
*
|
||||
* @param SpiDeviceId is the Instance Id of SPI in the system.
|
||||
*
|
||||
* @return
|
||||
* - XST_SUCCESS if successful
|
||||
* - XST_FAILURE if not successful
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* If the device slave select is not correct and the device is not responding
|
||||
* on bus it will read a status of 0xFF for the status register as the bus
|
||||
* is pulled up.
|
||||
*
|
||||
*****************************************************************************/
|
||||
int SpiPsFlashPolledExample(XSpiPs *SpiInstancePtr,
|
||||
u16 SpiDeviceId)
|
||||
{
|
||||
int Status;
|
||||
u8 *BufferPtr;
|
||||
u8 UniqueValue;
|
||||
u32 Count;
|
||||
XSpiPs_Config *SpiConfig;
|
||||
|
||||
/*
|
||||
* Initialize the SPI driver so that it's ready to use
|
||||
*/
|
||||
SpiConfig = XSpiPs_LookupConfig(SpiDeviceId);
|
||||
if (NULL == SpiConfig) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
Status = XSpiPs_CfgInitialize(SpiInstancePtr, SpiConfig,
|
||||
SpiConfig->BaseAddress);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Perform a self-test to check hardware build
|
||||
*/
|
||||
Status = XSpiPs_SelfTest(SpiInstancePtr);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the SPI device as a master with manual start and manual
|
||||
* chip select mode options
|
||||
*/
|
||||
XSpiPs_SetOptions(SpiInstancePtr, XSPIPS_MANUAL_START_OPTION | \
|
||||
XSPIPS_MASTER_OPTION | XSPIPS_FORCE_SSELECT_OPTION);
|
||||
|
||||
/*
|
||||
* Set the SPI device pre-scalar to divide by 8
|
||||
*/
|
||||
XSpiPs_SetClkPrescaler(SpiInstancePtr, XSPIPS_CLK_PRESCALE_8);
|
||||
|
||||
memset(WriteBuffer, 0x00, sizeof(WriteBuffer));
|
||||
memset(ReadBuffer, 0x00, sizeof(ReadBuffer));
|
||||
|
||||
/*
|
||||
* Initialize the write buffer for a pattern to write to the Flash
|
||||
* and the read buffer to zero so it can be verified after the read, the
|
||||
* test value that is added to the unique value allows the value to be
|
||||
* changed in a debug environment to guarantee
|
||||
*/
|
||||
for (UniqueValue = UNIQUE_VALUE, Count = 0; Count < MAX_DATA;
|
||||
Count++, UniqueValue++) {
|
||||
WriteBuffer[DATA_OFFSET + Count] = (u8)(UniqueValue);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the flash chip select
|
||||
*/
|
||||
XSpiPs_SetSlaveSelect(SpiInstancePtr, FLASH_SPI_SELECT);
|
||||
|
||||
/*
|
||||
* Read the flash Id
|
||||
*/
|
||||
Status = FlashReadID();
|
||||
if (Status != XST_SUCCESS) {
|
||||
xil_printf("SPI Flash Polled Example Read ID Failed\r\n");
|
||||
return XST_FAILURE;
|
||||
}
|
||||
/*
|
||||
* Erase the flash
|
||||
*/
|
||||
FlashErase(SpiInstancePtr);
|
||||
|
||||
TestAddress = 0x0;
|
||||
/*
|
||||
* Write the data in the write buffer to TestAddress in serial flash
|
||||
*/
|
||||
FlashWrite(SpiInstancePtr, TestAddress, MAX_DATA, WRITE_CMD);
|
||||
|
||||
/*
|
||||
* Read the contents of the flash from TestAddress of size MAX_DATA
|
||||
* using Normal Read command
|
||||
*/
|
||||
FlashRead(SpiInstancePtr, TestAddress, MAX_DATA, READ_CMD);
|
||||
|
||||
/*
|
||||
* Setup a pointer to the start of the data that was read into the read
|
||||
* buffer and verify the data read is the data that was written
|
||||
*/
|
||||
BufferPtr = &ReadBuffer[DATA_OFFSET];
|
||||
for (UniqueValue = UNIQUE_VALUE, Count = 0; Count < MAX_DATA;
|
||||
Count++, UniqueValue++) {
|
||||
if (BufferPtr[Count] != (u8)(UniqueValue)) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
memset(WriteBuffer, 0x00, sizeof(WriteBuffer));
|
||||
memset(ReadBuffer, 0x00, sizeof(ReadBuffer));
|
||||
|
||||
/*
|
||||
* Initialize the write buffer for a pattern to write to the Flash
|
||||
* and the read buffer to zero so it can be verified after the read, the
|
||||
* test value that is added to the unique value allows the value to be
|
||||
* changed in a debug environment to guarantee
|
||||
*/
|
||||
for (UniqueValue = UNIQUE_VALUE, Count = 0; Count < MAX_DATA;
|
||||
Count++, UniqueValue++) {
|
||||
WriteBuffer[DATA_OFFSET + Count] = (u8)(UniqueValue);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the SPI device as a master with auto start and manual
|
||||
* chip select mode options
|
||||
*/
|
||||
XSpiPs_SetOptions(SpiInstancePtr, XSPIPS_MASTER_OPTION | \
|
||||
XSPIPS_FORCE_SSELECT_OPTION);
|
||||
|
||||
/*
|
||||
* Erase the flash
|
||||
*/
|
||||
FlashErase(SpiInstancePtr);
|
||||
|
||||
TestAddress = 0x0;
|
||||
/*
|
||||
* Write the data in the write buffer to TestAddress in serial flash
|
||||
*/
|
||||
FlashWrite(SpiInstancePtr, TestAddress, MAX_DATA, WRITE_CMD);
|
||||
|
||||
|
||||
/*
|
||||
* Read the contents of the flash from TestAddress of size MAX_DATA
|
||||
* using Normal Read command
|
||||
*/
|
||||
FlashRead(SpiInstancePtr, TestAddress, MAX_DATA, READ_CMD);
|
||||
|
||||
/*
|
||||
* Setup a pointer to the start of the data that was read into the read
|
||||
* buffer and verify the data read is the data that was written
|
||||
*/
|
||||
BufferPtr = &ReadBuffer[DATA_OFFSET];
|
||||
for (UniqueValue = UNIQUE_VALUE, Count = 0; Count < MAX_DATA;
|
||||
Count++, UniqueValue++) {
|
||||
if (BufferPtr[Count] != (u8)(UniqueValue)) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
*
|
||||
* This function writes to the desired address in serial flash connected to
|
||||
* the SPI interface.
|
||||
*
|
||||
* @param SpiPtr is a pointer to the SPI driver instance to use.
|
||||
* @param Address contains the address to write data to in the flash.
|
||||
* @param ByteCount contains the number of bytes to write.
|
||||
* @param Command is the command used to write data to the flash.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
void FlashWrite(XSpiPs *SpiPtr, u32 Address, u32 ByteCount, u8 Command)
|
||||
{
|
||||
u8 WriteEnableCmd = { WRITE_ENABLE_CMD };
|
||||
u8 WriteDisableCmd = { WRITE_DISABLE_CMD };
|
||||
u8 ReadStatusCmd[] = { READ_STATUS_CMD, 0 }; /* must send 2 bytes */
|
||||
u8 FlashStatus[2];
|
||||
u32 Temp = 0;
|
||||
u32 TempAddress = Address;
|
||||
u8 TempBuffer[5];
|
||||
|
||||
if (Command == WRITE_CMD) {
|
||||
for (Temp = 0; Temp < ByteCount ; Temp++, TempAddress++) {
|
||||
/*
|
||||
* Send the write enable command to the flash so
|
||||
* that it can be written to, this needs to be sent
|
||||
* as a seperate transfer before the write
|
||||
*/
|
||||
XSpiPs_PolledTransfer(SpiPtr, &WriteEnableCmd, NULL,
|
||||
sizeof(WriteEnableCmd));
|
||||
|
||||
/*
|
||||
* Setup the write command with the specified address
|
||||
* and data for the flash
|
||||
*/
|
||||
TempBuffer[COMMAND_OFFSET] = Command;
|
||||
TempBuffer[ADDRESS_1_OFFSET] =
|
||||
(u8)((TempAddress & 0xFF0000) >> 16);
|
||||
TempBuffer[ADDRESS_2_OFFSET] =
|
||||
(u8)((TempAddress & 0xFF00) >> 8);
|
||||
TempBuffer[ADDRESS_3_OFFSET] =
|
||||
(u8)(TempAddress & 0xFF);
|
||||
TempBuffer[DATA_OFFSET] =
|
||||
WriteBuffer[DATA_OFFSET + Temp];
|
||||
|
||||
/*
|
||||
* Send the write command, address, and data to the
|
||||
* flash to be written, no receive buffer is specified
|
||||
* since there is nothing to receive
|
||||
*/
|
||||
XSpiPs_PolledTransfer(SpiPtr, TempBuffer, NULL, 5);
|
||||
|
||||
/*
|
||||
* Wait for the write command to the flash to be ,
|
||||
* completed it takes some time for the data to be
|
||||
* written
|
||||
*/
|
||||
while (1) {
|
||||
/*
|
||||
* Poll the status register of the flash to
|
||||
* determine when it completes, by sending
|
||||
* a read status command and receiving the
|
||||
* status byte
|
||||
*/
|
||||
|
||||
XSpiPs_PolledTransfer(SpiPtr, ReadStatusCmd,
|
||||
FlashStatus, sizeof(ReadStatusCmd));
|
||||
|
||||
/*
|
||||
* If the status indicates the write is done,
|
||||
* then stop waiting, if a value of 0xFF in
|
||||
* the status byte is read from the device
|
||||
* and this loop never exits, the device slave
|
||||
* select is possibly incorrect such that the
|
||||
* device status is not being read
|
||||
*/
|
||||
if ((FlashStatus[1] & 0x01) == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
XSpiPs_PolledTransfer(SpiPtr, &WriteDisableCmd,
|
||||
NULL, sizeof(WriteDisableCmd));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This function reads from the serial flash connected to the
|
||||
* SPI interface.
|
||||
*
|
||||
* @param SpiPtr is a pointer to the SPI driver instance to use.
|
||||
* @param Address contains the address to read data from in the flash.
|
||||
* @param ByteCount contains the number of bytes to read.
|
||||
* @param Command is the command used to read data from the flash. SPI
|
||||
* device supports one of the Read, Fast Read commands to read
|
||||
* data from the flash.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
void FlashRead(XSpiPs *SpiPtr, u32 Address, u32 ByteCount, u8 Command)
|
||||
{
|
||||
/*
|
||||
* Setup the read command with the specified address and data for the
|
||||
* flash
|
||||
*/
|
||||
WriteBuffer[COMMAND_OFFSET] = Command;
|
||||
WriteBuffer[ADDRESS_1_OFFSET] = (u8)((Address & 0xFF0000) >> 16);
|
||||
WriteBuffer[ADDRESS_2_OFFSET] = (u8)((Address & 0xFF00) >> 8);
|
||||
WriteBuffer[ADDRESS_3_OFFSET] = (u8)(Address & 0xFF);
|
||||
|
||||
XSpiPs_PolledTransfer(SpiPtr, WriteBuffer, ReadBuffer,
|
||||
ByteCount + OVERHEAD_SIZE);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This function reads serial flash ID connected to the SPI interface.
|
||||
*
|
||||
* @param None.
|
||||
*
|
||||
* @return
|
||||
* - XST_SUCCESS if successful
|
||||
* - XST_FAILURE if not successful
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
int FlashReadID(void)
|
||||
{
|
||||
u8 Index;
|
||||
int Status;
|
||||
u8 ByteCount = 4;
|
||||
u8 SendBuffer[8];
|
||||
u8 RecvBuffer[8];
|
||||
|
||||
SendBuffer[0] = READ_ID;
|
||||
SendBuffer[1] = 0;
|
||||
SendBuffer[2] = 0;
|
||||
SendBuffer[3] = 0;
|
||||
|
||||
for(Index=0; Index < ByteCount; Index++) {
|
||||
SendBuffer[4 + Index] = 0x00;
|
||||
}
|
||||
|
||||
Status = XSpiPs_PolledTransfer(&SpiInstance, SendBuffer, RecvBuffer,
|
||||
(4 + ByteCount));
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
for(Index=0; Index < ByteCount; Index++) {
|
||||
xil_printf("ID : %0x\r\n", RecvBuffer[4 + Index]);
|
||||
}
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
*
|
||||
* This function erases the sectors in the serial flash connected to the
|
||||
* SPI interface.
|
||||
*
|
||||
* @param SpiPtr is a pointer to the SPI driver instance to use.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
void FlashErase(XSpiPs *SpiPtr)
|
||||
{
|
||||
u8 WriteEnableCmd = { WRITE_ENABLE_CMD };
|
||||
/* must send 2 bytes */
|
||||
u8 ReadStatusCmd[] = { READ_STATUS_CMD, 0x0 };
|
||||
/* must send 2 bytes */
|
||||
u8 WriteStatusCmd[] = { WRITE_STATUS_CMD, 0x0 };
|
||||
u8 FlashStatus[3];
|
||||
|
||||
/*
|
||||
* Send the write enable command to the flash so that it can be
|
||||
* written to, this needs to be sent as a separate transfer
|
||||
* before the erase
|
||||
*/
|
||||
XSpiPs_PolledTransfer(SpiPtr, &WriteEnableCmd, NULL,
|
||||
sizeof(WriteEnableCmd));
|
||||
|
||||
while (1) {
|
||||
XSpiPs_PolledTransfer(SpiPtr, ReadStatusCmd, FlashStatus,
|
||||
sizeof(ReadStatusCmd));
|
||||
|
||||
/*
|
||||
* If the status indicates the write enabled, then stop
|
||||
* waiting; if a value of 0xFF in the status byte is
|
||||
* read from the device and this loop never exits, the
|
||||
* device slave select is possibly incorrect such that
|
||||
* the device status is not being read
|
||||
*/
|
||||
if ((FlashStatus[1] & 0x02) == 0x02) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Clear write protect bits using write status command to the flash
|
||||
* so that it can be written to, this needs to be sent as a
|
||||
* separate transfer before the erase
|
||||
*/
|
||||
XSpiPs_PolledTransfer(SpiPtr, WriteStatusCmd, NULL,
|
||||
sizeof(WriteStatusCmd));
|
||||
while (1) {
|
||||
XSpiPs_PolledTransfer(SpiPtr, ReadStatusCmd, FlashStatus,
|
||||
sizeof(ReadStatusCmd));
|
||||
/*
|
||||
* If the status indicates the WP bits cleared, then stop
|
||||
* waiting; if a value of 0xFF in the status byte is
|
||||
* read from the device and this loop never exits, the
|
||||
* device slave select is possibly incorrect such that
|
||||
* the device status is not being read
|
||||
*/
|
||||
if ((FlashStatus[1] & 0x1C) == 0x0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Send the write enable command to the flash so that it can be
|
||||
* written to, this needs to be sent as a separate transfer
|
||||
* before the erase
|
||||
*/
|
||||
XSpiPs_PolledTransfer(SpiPtr, &WriteEnableCmd, NULL,
|
||||
sizeof(WriteEnableCmd));
|
||||
|
||||
while (1) {
|
||||
XSpiPs_PolledTransfer(SpiPtr, ReadStatusCmd, FlashStatus,
|
||||
sizeof(ReadStatusCmd));
|
||||
|
||||
/*
|
||||
* If the status indicates the write enabled, then stop
|
||||
* waiting; if a value of 0xFF in the status byte is
|
||||
* read from the device and this loop never exits, the
|
||||
* device slave select is possibly incorrect such that
|
||||
* the device status is not being read
|
||||
*/
|
||||
if ((FlashStatus[1] & 0x02) == 0x02) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Performs chip erase.
|
||||
*/
|
||||
WriteBuffer[COMMAND_OFFSET] = CHIP_ERASE_CMD;
|
||||
|
||||
XSpiPs_PolledTransfer(SpiPtr, WriteBuffer, NULL, 1);
|
||||
|
||||
/*
|
||||
* Wait for the erase command to the flash to be completed
|
||||
*/
|
||||
while (1) {
|
||||
XSpiPs_PolledTransfer(SpiPtr, ReadStatusCmd, FlashStatus,
|
||||
sizeof(ReadStatusCmd));
|
||||
|
||||
/*
|
||||
* If the status indicates the write is done, then stop
|
||||
* waiting; if a value of 0xFF in the status byte is
|
||||
* read from the device and this loop never exits, the
|
||||
* device slave select is possibly incorrect such that
|
||||
* the device status is not being read
|
||||
*/
|
||||
if ((FlashStatus[1] & 0x01) == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
156
XilinxProcessorIPLib/drivers/spips/examples/xspips_selftest_example.c
Executable file
156
XilinxProcessorIPLib/drivers/spips/examples/xspips_selftest_example.c
Executable file
|
@ -0,0 +1,156 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2010 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
/******************************************************************************/
|
||||
/**
|
||||
* @file xspips_selftest_example.c
|
||||
*
|
||||
* This file contains an example for using the SPI Hardware, it does a simple
|
||||
* hardware connection check.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* None
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ------ -------- -----------------------------------------------
|
||||
* 1.00 drg/jz 01/25/10 First release.
|
||||
* </pre>
|
||||
*
|
||||
*******************************************************************************/
|
||||
|
||||
/***************************** Include Files **********************************/
|
||||
|
||||
#include "xparameters.h"
|
||||
#include "xspips.h"
|
||||
#include "xil_printf.h"
|
||||
|
||||
/************************** Constant Definitions ******************************/
|
||||
|
||||
/*
|
||||
* The following constants map to the XPAR parameters created in the
|
||||
* xparameters.h file. They are defined here such that a user can easily
|
||||
* change all the needed parameters in one place.
|
||||
*/
|
||||
#define SPI_DEVICE_ID XPAR_XSPIPS_0_DEVICE_ID
|
||||
|
||||
/**************************** Type Definitions ********************************/
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions **********************/
|
||||
|
||||
/************************** Function Prototypes *******************************/
|
||||
|
||||
int SpiPsSelfTestExample(u16 DeviceId);
|
||||
|
||||
/************************** Variable Definitions ******************************/
|
||||
|
||||
XSpiPs Spi; /* The instance of the SPI device */
|
||||
|
||||
/******************************************************************************/
|
||||
/**
|
||||
* Main function to call the Spi SelfTest example.
|
||||
*
|
||||
* @param None
|
||||
*
|
||||
* @return XST_SUCCESS if successful, XST_FAILURE if unsuccessful
|
||||
*
|
||||
* @note None
|
||||
*
|
||||
*******************************************************************************/
|
||||
#ifndef TESTAPP_GEN
|
||||
int main(void)
|
||||
{
|
||||
int Status;
|
||||
|
||||
xil_printf("SPI Selftest Example \r\n");
|
||||
|
||||
/*
|
||||
* Call the example , specify the device ID that is generated in
|
||||
* xparameters.h
|
||||
*/
|
||||
Status = SpiPsSelfTestExample(SPI_DEVICE_ID);
|
||||
if (Status != XST_SUCCESS) {
|
||||
xil_printf("SPI Selftest Example Failed\r\n");
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
xil_printf("Successfully ran SPI Selftest Example\r\n");
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function does a selftest on the SPI device and XSpiPs driver as an
|
||||
* example. The purpose of this function is to illustrate the usage of the
|
||||
* XSpiPs driver.
|
||||
*
|
||||
*
|
||||
* @param DeviceId is the XPAR_<SPIPS_instance>_DEVICE_ID value from
|
||||
* xparameters.h
|
||||
*
|
||||
* @return XST_SUCCESS if successful, XST_FAILURE if unsuccessful
|
||||
*
|
||||
* @note None
|
||||
*
|
||||
****************************************************************************/
|
||||
int SpiPsSelfTestExample(u16 DeviceId)
|
||||
{
|
||||
int Status;
|
||||
XSpiPs_Config *SpiConfig;
|
||||
|
||||
/*
|
||||
* Initialize the SPI device.
|
||||
*/
|
||||
SpiConfig = XSpiPs_LookupConfig(DeviceId);
|
||||
if (NULL == SpiConfig) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
Status = XSpiPs_CfgInitialize(&Spi, SpiConfig, SpiConfig->BaseAddress);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Perform a self-test to check hardware build.
|
||||
*/
|
||||
Status = XSpiPs_SelfTest(&Spi);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
320
XilinxProcessorIPLib/drivers/spips/examples/xspips_slave_polled_example.c
Executable file
320
XilinxProcessorIPLib/drivers/spips/examples/xspips_slave_polled_example.c
Executable file
|
@ -0,0 +1,320 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @file xspips_slave_polled_example.c
|
||||
*
|
||||
*
|
||||
* This file contains a design example using the SPI controller in slave mode.
|
||||
* This examples performs transfers in polled mode and has been tested with
|
||||
* Aardvark Analyzer as Master. This example echoes data which it receives
|
||||
* from the master. The slave controller expects MAX_DATA bytes of data from
|
||||
* the master to transmit onto the SPI bus which the slave will receive into
|
||||
* its Rx buffer. It will poll until the Rx FIFO is filled with the Threshold
|
||||
* limit of data which is set to MAX_DATA. On sending data, the master will
|
||||
* receive dummy bytes in response. Master has to send MAX_DATA dummy bytes
|
||||
* to read back the echoed data.
|
||||
*
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* The slave mode test needs an external master to send data to the Spi device.
|
||||
* This example has been tested with Aardvark Analyzer as Master.
|
||||
* The Clock Polarity and Phase should match between master and the slave.
|
||||
*
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- --- -------- -----------------------------------------------
|
||||
* 2.0 sb 08/22/14 First release
|
||||
*
|
||||
*</pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
#include "xparameters.h" /* SDK generated parameters */
|
||||
#include "xspips.h" /* SPI device driver */
|
||||
#include "xil_printf.h"
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
/*
|
||||
* The following constant map to the XPAR parameters created in the
|
||||
* xparameters.h file. They are defined here such that a user can easily
|
||||
* change all the needed parameters in one place.
|
||||
*/
|
||||
#define SPI_DEVICE_ID XPAR_XSPIPS_0_DEVICE_ID
|
||||
|
||||
/*
|
||||
* The following constant specify the max amount of data the slave is
|
||||
* expecting to receive from the master.
|
||||
*/
|
||||
#define MAX_DATA 100
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
#define SpiPs_RecvByte(BaseAddress) \
|
||||
(u8)XSpiPs_In32((BaseAddress) + XSPIPS_RXD_OFFSET)
|
||||
|
||||
#define SpiPs_SendByte(BaseAddress, Data) \
|
||||
XSpiPs_Out32((BaseAddress) + XSPIPS_TXD_OFFSET, (Data))
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
void SpiSlaveRead(int ByteCount);
|
||||
|
||||
void SpiSlaveWrite(u8 *Sendbuffer, int ByteCount);
|
||||
|
||||
int SpiPsSlavePolledExample(u16 SpiDeviceId);
|
||||
|
||||
/************************** Variable Definitions *****************************/
|
||||
|
||||
/*
|
||||
* The instances to support the device drivers are global such that they
|
||||
* are initialized to zero each time the program runs. They could be local
|
||||
* but should at least be static so they are zeroed.
|
||||
*/
|
||||
static XSpiPs SpiInstance;
|
||||
|
||||
/*
|
||||
* The ReadBuffer is used to read to the data which it received from the SPI
|
||||
* Bus which master has sent.
|
||||
*/
|
||||
u8 ReadBuffer[MAX_DATA];
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Main function to call the SPI Slave Example.
|
||||
*
|
||||
* @param None
|
||||
*
|
||||
* @return
|
||||
* - XST_SUCCESS if successful
|
||||
* - XST_FAILURE if not successful
|
||||
*
|
||||
* @note None
|
||||
*
|
||||
******************************************************************************/
|
||||
int main(void)
|
||||
{
|
||||
int Status;
|
||||
|
||||
xil_printf("Running SpiPS Slave Polled Example \r\n");
|
||||
|
||||
/*
|
||||
* Run the SpiPs Slave Polled example.
|
||||
*/
|
||||
Status = SpiPsSlavePolledExample(SPI_DEVICE_ID);
|
||||
if (Status != XST_SUCCESS) {
|
||||
xil_printf("SpiPs Slave Polled Example Failed \r\n");
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
xil_printf("Successfully ran SpiPs Slave Polled Example \r\n");
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* The purpose of this function is to illustrate how to use the XSpiPs
|
||||
* device driver in Slave mode. This function reads data from a SPI Master
|
||||
* and will echo it back to the Master.
|
||||
*
|
||||
* @param SpiDeviceId is the Instance Id of SPI in the system.
|
||||
*
|
||||
* @return
|
||||
* - XST_SUCCESS if successful
|
||||
* - XST_FAILURE if not successful
|
||||
*
|
||||
* @note None
|
||||
*
|
||||
*
|
||||
*****************************************************************************/
|
||||
int SpiPsSlavePolledExample(u16 SpiDeviceId)
|
||||
{
|
||||
int Status;
|
||||
u8 *BufferPtr;
|
||||
XSpiPs_Config *SpiConfig;
|
||||
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
|
||||
/*
|
||||
* The SPI device is a slave by default and the clock phase
|
||||
* have to be set according to its master. In this example, CPOL is set
|
||||
* to quiescent high and CPHA is set to 1.
|
||||
*/
|
||||
Status = XSpiPs_SetOptions((&SpiInstance), (XSPIPS_CR_CPHA_MASK) | \
|
||||
(XSPIPS_CR_CPOL_MASK));
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
memset(ReadBuffer, 0x00, sizeof(ReadBuffer));
|
||||
|
||||
/*
|
||||
* Set the Rx FIFO Threshold to the Max Data
|
||||
*/
|
||||
XSpiPs_SetRXWatermark((&SpiInstance),MAX_DATA);
|
||||
|
||||
/*
|
||||
* Enable the device.
|
||||
*/
|
||||
XSpiPs_Enable((&SpiInstance));
|
||||
|
||||
/*
|
||||
* Read the contents of the Receive buffer
|
||||
* Master is expected to send MAX_DATA number of bytes
|
||||
*/
|
||||
SpiSlaveRead(MAX_DATA);
|
||||
|
||||
/*
|
||||
* Setup a pointer to the start of the data that was read into the read
|
||||
* buffer and the same back
|
||||
*/
|
||||
BufferPtr = ReadBuffer;
|
||||
|
||||
/*
|
||||
* Send the data received back to Master
|
||||
* Master is expected to send MAX_DATA number of dummy bytes for
|
||||
* the slave to be able to echo previously received data.
|
||||
*/
|
||||
SpiSlaveWrite(BufferPtr, MAX_DATA);
|
||||
|
||||
/*
|
||||
* Disable the device.
|
||||
*/
|
||||
XSpiPs_Disable((&SpiInstance));
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This function reads from the Rx buffer
|
||||
*
|
||||
* @param ByteCount is the number of bytes to be read from Rx buffer.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
void SpiSlaveRead(int ByteCount)
|
||||
{
|
||||
int Count;
|
||||
u32 StatusReg;
|
||||
|
||||
StatusReg = XSpiPs_ReadReg(SpiInstance.Config.BaseAddress,
|
||||
XSPIPS_SR_OFFSET);
|
||||
|
||||
/*
|
||||
* Polling the Rx Buffer for Data
|
||||
*/
|
||||
do{
|
||||
StatusReg = XSpiPs_ReadReg(SpiInstance.Config.BaseAddress,
|
||||
XSPIPS_SR_OFFSET);
|
||||
}while(!(StatusReg & XSPIPS_IXR_RXNEMPTY_MASK));
|
||||
|
||||
/*
|
||||
* Reading the Rx Buffer
|
||||
*/
|
||||
for(Count = 0; Count < ByteCount; Count++){
|
||||
ReadBuffer[Count] = SpiPs_RecvByte(
|
||||
SpiInstance.Config.BaseAddress);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This function writes Data into the Tx buffer
|
||||
*
|
||||
* @param Sendbuffer is the buffer whose data is to be sent onto the
|
||||
* Tx FIFO.
|
||||
* @param ByteCount is the number of bytes to be read from Rx buffer.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
void SpiSlaveWrite(u8 *Sendbuffer, int ByteCount)
|
||||
{
|
||||
u32 StatusReg;
|
||||
int TransCount = 0;
|
||||
|
||||
StatusReg = XSpiPs_ReadReg(SpiInstance.Config.BaseAddress,
|
||||
XSPIPS_SR_OFFSET);
|
||||
|
||||
/*
|
||||
* Fill the TXFIFO with as many bytes as it will take (or as
|
||||
* many as we have to send).
|
||||
*/
|
||||
while ((ByteCount > 0) &&
|
||||
(TransCount < XSPIPS_FIFO_DEPTH)) {
|
||||
SpiPs_SendByte(SpiInstance.Config.BaseAddress,
|
||||
*Sendbuffer);
|
||||
Sendbuffer++;
|
||||
++TransCount;
|
||||
ByteCount--;
|
||||
}
|
||||
|
||||
/*
|
||||
* Wait for the transfer to finish by polling Tx fifo status.
|
||||
*/
|
||||
do {
|
||||
StatusReg = XSpiPs_ReadReg(
|
||||
SpiInstance.Config.BaseAddress,
|
||||
XSPIPS_SR_OFFSET);
|
||||
} while ((StatusReg & XSPIPS_IXR_TXOW_MASK) == 0);
|
||||
|
||||
}
|
40
XilinxProcessorIPLib/drivers/spips/src/Makefile
Executable file
40
XilinxProcessorIPLib/drivers/spips/src/Makefile
Executable file
|
@ -0,0 +1,40 @@
|
|||
COMPILER=
|
||||
ARCHIVER=
|
||||
CP=cp
|
||||
COMPILER_FLAGS=
|
||||
EXTRA_COMPILER_FLAGS=
|
||||
LIB=libxil.a
|
||||
|
||||
CC_FLAGS = $(COMPILER_FLAGS)
|
||||
ECC_FLAGS = $(EXTRA_COMPILER_FLAGS)
|
||||
|
||||
RELEASEDIR=../../../lib
|
||||
INCLUDEDIR=../../../include
|
||||
INCLUDES=-I./. -I${INCLUDEDIR}
|
||||
|
||||
OUTS = *.o
|
||||
|
||||
LIBSOURCES:=*.c
|
||||
INCLUDEFILES:=*.h
|
||||
|
||||
OBJECTS = $(addsuffix .o, $(basename $(wildcard *.c)))
|
||||
|
||||
libs: banner xspips_libs clean
|
||||
|
||||
%.o: %.c
|
||||
${COMPILER} $(CC_FLAGS) $(ECC_FLAGS) $(INCLUDES) -o $@ $<
|
||||
|
||||
banner:
|
||||
echo "Compiling spips"
|
||||
|
||||
xspips_libs: ${OBJECTS}
|
||||
$(ARCHIVER) -r ${RELEASEDIR}/${LIB} ${OBJECTS}
|
||||
|
||||
.PHONY: include
|
||||
include: xspips_includes
|
||||
|
||||
xspips_includes:
|
||||
${CP} ${INCLUDEFILES} ${INCLUDEDIR}
|
||||
|
||||
clean:
|
||||
rm -rf ${OBJECTS}
|
1106
XilinxProcessorIPLib/drivers/spips/src/xspips.c
Executable file
1106
XilinxProcessorIPLib/drivers/spips/src/xspips.c
Executable file
File diff suppressed because it is too large
Load diff
689
XilinxProcessorIPLib/drivers/spips/src/xspips.h
Executable file
689
XilinxProcessorIPLib/drivers/spips/src/xspips.h
Executable file
|
@ -0,0 +1,689 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2010 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @file xspips.h
|
||||
*
|
||||
* This file contains the implementation of the XSpiPs driver. It works for
|
||||
* both the master and slave mode. User documentation for the driver functions
|
||||
* is contained in this file in the form of comment blocks at the front of each
|
||||
* function.
|
||||
*
|
||||
* An SPI device connects to an SPI bus through a 4-wire serial interface.
|
||||
* The SPI bus is a full-duplex, synchronous bus that facilitates communication
|
||||
* between one master and one slave. The device is always full-duplex,
|
||||
* which means that for every byte sent, one is received, and vice-versa.
|
||||
* The master controls the clock, so it can regulate when it wants to
|
||||
* send or receive data. The slave is under control of the master, it must
|
||||
* respond quickly since it has no control of the clock and must send/receive
|
||||
* data as fast or as slow as the master does.
|
||||
*
|
||||
* <b>Initialization & Configuration</b>
|
||||
*
|
||||
* The XSpiPs_Config structure is used by the driver to configure itself. This
|
||||
* configuration structure is typically created by the tool-chain based on HW
|
||||
* build properties.
|
||||
*
|
||||
* To support multiple runtime loading and initialization strategies employed by
|
||||
* various operating systems, the driver instance can be initialized in the
|
||||
* following way:
|
||||
* - XSpiPs_LookupConfig(DeviceId) - Use the devide identifier to find the
|
||||
* static configuration structure defined in xspips_g.c. This is setup by
|
||||
* the tools. For some operating systems the config structure will be
|
||||
* initialized by the software and this call is not needed.
|
||||
* - XSpiPs_CfgInitialize(InstancePtr, CfgPtr, EffectiveAddr) - Uses a
|
||||
* configuration structure provided by the caller. If running in a system
|
||||
* with address translation, the provided virtual memory base address
|
||||
* replaces the physical address present in the configuration structure.
|
||||
*
|
||||
* <b>Multiple Masters</b>
|
||||
*
|
||||
* More than one master can exist, but arbitration is the responsibility of
|
||||
* the higher layer software. The device driver does not perform any type of
|
||||
* arbitration.
|
||||
*
|
||||
* <b>Multiple Slaves</b>
|
||||
*
|
||||
* Contention between multiple masters is detected by the hardware, in which
|
||||
* case a mode fault occurs on the device. The device is disabled immediately
|
||||
* by hardware, and the current word transfer is stopped. The Aborted word
|
||||
* transfer due to the mode fault is resumed once the devie is enabled again.
|
||||
*
|
||||
* <b>Modes of Operation</b>
|
||||
*
|
||||
* There are four modes to perform a data transfer and the selection of a mode
|
||||
* is based on Chip Select(CS) and Start. These two options individually, can
|
||||
* be controlled either by software(Manual) or hardware(Auto).
|
||||
* - Auto CS: Chip select is automatically asserted as soon as the first word
|
||||
* is written into the TXFIFO and deasserted when the TXFIFO becomes
|
||||
* empty
|
||||
* - Manual CS: Software must assert and deassert CS.
|
||||
* - Auto Start: Data transmission starts as soon as there is data in the
|
||||
* TXFIFO and stalls when the TXFIFO is empty
|
||||
* - Manual Start: Software must start data transmission at the beginning of
|
||||
* the transaction or whenever the TXFIFO has become empty
|
||||
*
|
||||
* The preferred combination is Manual CS and Auto Start.
|
||||
* In this combination, the software asserts CS before loading any data into
|
||||
* TXFIFO. In Auto Start mode, whenever data is in TXFIFO, controller sends it
|
||||
* out until TXFIFO becomes empty. The software reads the RXFIFO whenever the
|
||||
* data is available. If no further data, software disables CS.
|
||||
*
|
||||
* Risks/challenges of other combinations:
|
||||
* - Manual CS and Manual Start: Manual Start bit should be set after each
|
||||
* TXFIFO write otherwise there could be a race condition where the TXFIFO
|
||||
* becomes empty before the new word is written. In that case the
|
||||
* transmission stops.
|
||||
* - Auto CS with Manual or Auto Start: It is very difficult for software to
|
||||
* keep the TXFIFO filled. Whenever the TXFIFO runs empty, CS is deasserted.
|
||||
* This results in a single transaction to be split into multiple pieces each
|
||||
* with its own chip select. This will result in garbage data to be sent.
|
||||
*
|
||||
* <b>Interrupts</b>
|
||||
*
|
||||
* The user must connect the interrupt handler of the driver,
|
||||
* XSpiPs_InterruptHandler, to an interrupt system such that it will be
|
||||
* called when an interrupt occurs. This function does not save and restore
|
||||
* the processor context such that the user must provide this processing.
|
||||
*
|
||||
* The driver handles the following interrupts:
|
||||
* - Data Transmit Register/FIFO Underflow
|
||||
* - Data Receive Register/FIFO Full
|
||||
* - Data Receive Register/FIFO Not Empty
|
||||
* - Data Transmit Register/FIFO Full
|
||||
* - Data Transmit Register/FIFO Overwater
|
||||
* - Mode Fault Error
|
||||
* - Data Receive Register/FIFO Overrun
|
||||
*
|
||||
* The Data Transmit Register/FIFO Overwater interrupt -- indicates that the
|
||||
* SPI device has transmitted the data available to transmit, and now its data
|
||||
* register and FIFO is ready to accept more data. The driver uses this
|
||||
* interrupt to indicate progress while sending data. The driver may have
|
||||
* more data to send, in which case the data transmit register and FIFO is
|
||||
* filled for subsequent transmission. When this interrupt arrives and all
|
||||
* the data has been sent, the driver invokes the status callback with a
|
||||
* value of XST_SPI_TRANSFER_DONE to inform the upper layer software that
|
||||
* all data has been sent.
|
||||
*
|
||||
* The Data Transmit Register/FIFO Underflow interrupt -- indicates that,
|
||||
* as slave, the SPI device was required to transmit but there was no data
|
||||
* available to transmit in the transmit register (or FIFO). This may not
|
||||
* be an error if the master is not expecting data. But in the case where
|
||||
* the master is expecting data, this serves as a notification of such a
|
||||
* condition. The driver reports this condition to the upper layer
|
||||
* software through the status handler.
|
||||
*
|
||||
* The Data Receive Register/FIFO Overrun interrupt -- indicates that the SPI
|
||||
* device received data and subsequently dropped the data because the data
|
||||
* receive register and FIFO was full. The interrupt applies to both master
|
||||
* and slave operation. The driver reports this condition to the upper layer
|
||||
* software through the status handler. This likely indicates a problem with
|
||||
* the higher layer protocol, or a problem with the slave performance.
|
||||
*
|
||||
* The Mode Fault Error interrupt -- indicates that while configured as a
|
||||
* master, the device was selected as a slave by another master. This can be
|
||||
* used by the application for arbitration in a multimaster environment or to
|
||||
* indicate a problem with arbitration. When this interrupt occurs, the
|
||||
* driver invokes the status callback with a status value of
|
||||
* XST_SPI_MODE_FAULT. It is up to the application to resolve the conflict.
|
||||
* When configured as a slave, Mode Fault Error interrupt indicates that a slave
|
||||
* device was selected as a slave by a master, but the slave device was
|
||||
* disabled. When configured as a master, Mode Fault Error interrupt indicates
|
||||
* that another SPI device is acting as a master on the bus.
|
||||
*
|
||||
*
|
||||
* <b>Polled Operation</b>
|
||||
*
|
||||
* Transfer in polled mode is supported through a separate interface function
|
||||
* XSpiPs_PolledTransfer(). Unlike the transfer function in the interrupt mode,
|
||||
* this function blocks until all data has been sent/received.
|
||||
*
|
||||
* <b>Device Busy</b>
|
||||
*
|
||||
* Some operations are disallowed when the device is busy. The driver tracks
|
||||
* whether a device is busy. The device is considered busy when a data transfer
|
||||
* request is outstanding, and is considered not busy only when that transfer
|
||||
* completes (or is aborted with a mode fault error). This applies to both
|
||||
* master and slave devices.
|
||||
*
|
||||
* <b>Device Configuration</b>
|
||||
*
|
||||
* The device can be configured in various ways during the FPGA implementation
|
||||
* process. Configuration parameters are stored in the xspips_g.c file or
|
||||
* passed in via XSpiPs_CfgInitialize(). A table is defined where each entry
|
||||
* contains configuration information for an SPI device, including the base
|
||||
* address for the device.
|
||||
*
|
||||
* <b>RTOS Independence</b>
|
||||
*
|
||||
* This driver is intended to be RTOS and processor independent. It works with
|
||||
* physical addresses only. Any needs for dynamic memory management, threads or
|
||||
* thread mutual exclusion, virtual memory, or cache control must be satisfied
|
||||
* by the layer above this driver.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ------ -------- -----------------------------------------------
|
||||
* 1.00 drg/jz 01/25/10 First release
|
||||
* 1.00 sdm 10/25/11 Removed the Divide by 2 in the SPI Clock Prescaler
|
||||
* options as this is not supported in the device.
|
||||
* 1.01 sg 03/07/12 Updated the code to always clear the relevant bits
|
||||
* before writing to config register.
|
||||
* Always clear the slave select bits before write and
|
||||
* clear the bits to no slave at the end of transfer
|
||||
* Modified the Polled transfer transmit/receive logic.
|
||||
* Tx should wait on TXOW Interrupt and Rx on RXNEMTY.
|
||||
* 1.02 sg 05/31/12 Updated XSPIPS_FIFO_DEPTH to 128 from 32 to match HW
|
||||
* for CR 658289
|
||||
* 1.03 sg 09/21/12 Added memory barrier dmb in polled transfer and
|
||||
* interrupt handler to overcome the clock domain
|
||||
* crossing issue in the controller. For CR #679252.
|
||||
* 1.04a sg 01/30/13 Created XSPIPS_MANUAL_START_OPTION. Created macros
|
||||
* XSpiPs_IsMaster, XSpiPs_IsManualStart and
|
||||
* XSpiPs_IsManualChipSelect. Changed SPI
|
||||
* Enable/Disable macro argument from BaseAddress to
|
||||
* Instance Pointer. Added DelayNss argument to SetDelays
|
||||
* and GetDelays API's. Added macros to set/get the
|
||||
* RX Watermark value.Created macros XSpiPs_IsMaster,
|
||||
* XSpiPs_IsManualStart and XSpiPs_IsManualChipSelect.
|
||||
* Changed SPI transfer logic for polled and interrupt
|
||||
* modes to be based on filled tx fifo count and receive
|
||||
* based on it. RXNEMPTY interrupt is not used.
|
||||
* SetSlaveSelect API logic is modified to drive the bit
|
||||
* position low based on the slave select value
|
||||
* requested. GetSlaveSelect API will return the value
|
||||
* based on bit position that is low.
|
||||
* Created XSPIPS_CR_MODF_GEN_EN_MASK macro and added it
|
||||
* to XSPIPS_CR_RESET_STATE. Created
|
||||
* XSPIPS_IXR_WR_TO_CLR_MASK for interrupts which need
|
||||
* write-to-clear. Added shift and mask macros for d_nss
|
||||
* parameter. Added Rx Watermark mask.
|
||||
* 1.05a hk 26/04/13 Added disable and enable in XSpiPs_SetOptions when
|
||||
* CPOL/CPHA bits are set/reset. Fix for CR#707669.
|
||||
* 1.06a hk 08/22/13 Changed GetSlaveSelect function. CR# 727866.
|
||||
* Added masking ConfigReg before writing in SetSlaveSel
|
||||
* Added extended slave select support - CR#722569.
|
||||
* Added prototypes of reset API and related constant
|
||||
* definitions.
|
||||
* Added check for MODF in polled transfer function.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef XSPIPS_H /* prevent circular inclusions */
|
||||
#define XSPIPS_H /* by using protection macros */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
#include "xstatus.h"
|
||||
#include "xspips_hw.h"
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
/** @name Configuration options
|
||||
*
|
||||
* The following options are supported to enable/disable certain features of
|
||||
* an SPI device. Each of the options is a bit mask, so more than one may be
|
||||
* specified.
|
||||
*
|
||||
* <b>The Master option</b> configures the SPI device as a master.
|
||||
* By default, the device is a slave.
|
||||
*
|
||||
* The <b>Active Low Clock option</b> configures the device's clock polarity.
|
||||
* Setting this option means the clock is active low and the SCK signal idles
|
||||
* high. By default, the clock is active high and SCK idles low.
|
||||
*
|
||||
* The <b>Clock Phase option</b> configures the SPI device for one of two
|
||||
* transfer formats. A clock phase of 0, the default, means data is valid on
|
||||
* the first SCK edge (rising or falling) after the slave select (SS) signal
|
||||
* has been asserted. A clock phase of 1 means data is valid on the second SCK
|
||||
* edge (rising or falling) after SS has been asserted.
|
||||
*
|
||||
* The <b>Slave Select Decode Enable option</b> selects how the SPI_SS_outN are
|
||||
* controlled by the SPI Slave Select Decode bits.
|
||||
* 0: Use this setting for the standard configuration of up to three slave
|
||||
* select outputs. Only one of the three slave select outputs will be low.
|
||||
* (Default)
|
||||
* 1: Use this setting for the optional configuration of an additional decoder
|
||||
* to support 8 slave select outputs. SPI_SS_outN reflects the value in the
|
||||
* register.
|
||||
*
|
||||
* The <b>SPI Force Slave Select option</b> is used to enable manual control of
|
||||
* the signals SPI_SS_outN.
|
||||
* 0: The SPI_SS_outN signals are controlled by the SPI controller during
|
||||
* transfers. (Default)
|
||||
* 1: The SPI_SS_outN signal indicated by the Slave Select Control bit is
|
||||
* forced active (driven low) regardless of any transfers in progress.
|
||||
*
|
||||
* NOTE: The driver will handle setting and clearing the Slave Select when
|
||||
* the user sets the "FORCE_SSELECT_OPTION". Using this option will allow the
|
||||
* SPI clock to be set to a faster speed. If the SPI clock is too fast, the
|
||||
* processor cannot empty and refill the FIFOs before the TX FIFO is empty
|
||||
* When the SPI hardware is controlling the Slave Select signals, this
|
||||
* will cause slave to be de-selected and terminate the transfer.
|
||||
*
|
||||
* The <b>Manual Start option</b> is used to enable manual control of
|
||||
* the Start command to perform data transfer.
|
||||
* 0: The Start command is controlled by the SPI controller during
|
||||
* transfers(Default). Data transmission starts as soon as there is data in
|
||||
* the TXFIFO and stalls when the TXFIFO is empty
|
||||
* 1: The Start command must be issued by software to perform data transfer.
|
||||
* Bit 15 of Configuration register is used to issue Start command. This bit
|
||||
* must be set whenever TXFIFO is filled with new data.
|
||||
*
|
||||
* NOTE: The driver will set the Manual Start Enable bit in Configuration
|
||||
* Register, if Manual Start option is selected. Software will issue
|
||||
* Manual Start command whenever TXFIFO is filled with data. When there is
|
||||
* no further data, driver will clear the Manual Start Enable bit.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
#define XSPIPS_MASTER_OPTION 0x1 /**< Master mode option */
|
||||
#define XSPIPS_CLK_ACTIVE_LOW_OPTION 0x2 /**< Active Low Clock option */
|
||||
#define XSPIPS_CLK_PHASE_1_OPTION 0x4 /**< Clock Phase one option */
|
||||
#define XSPIPS_DECODE_SSELECT_OPTION 0x8 /**< Select 16 slaves Option */
|
||||
#define XSPIPS_FORCE_SSELECT_OPTION 0x10 /**< Force Slave Select */
|
||||
#define XSPIPS_MANUAL_START_OPTION 0x20 /**< Manual Start mode option */
|
||||
/*@}*/
|
||||
|
||||
|
||||
/** @name SPI Clock Prescaler options
|
||||
* The SPI Clock Prescaler Configuration bits are used to program master mode
|
||||
* bit rate. The bit rate can be programmed in divide-by-two decrements from
|
||||
* pclk/4 to pclk/256.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define XSPIPS_CLK_PRESCALE_4 0x01 /**< PCLK/4 Prescaler */
|
||||
#define XSPIPS_CLK_PRESCALE_8 0x02 /**< PCLK/8 Prescaler */
|
||||
#define XSPIPS_CLK_PRESCALE_16 0x03 /**< PCLK/16 Prescaler */
|
||||
#define XSPIPS_CLK_PRESCALE_32 0x04 /**< PCLK/32 Prescaler */
|
||||
#define XSPIPS_CLK_PRESCALE_64 0x05 /**< PCLK/64 Prescaler */
|
||||
#define XSPIPS_CLK_PRESCALE_128 0x06 /**< PCLK/128 Prescaler */
|
||||
#define XSPIPS_CLK_PRESCALE_256 0x07 /**< PCLK/256 Prescaler */
|
||||
/*@}*/
|
||||
|
||||
|
||||
/** @name Callback events
|
||||
*
|
||||
* These constants specify the handler events that are passed to
|
||||
* a handler from the driver. These constants are not bit masks such that
|
||||
* only one will be passed at a time to the handler.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
#define XSPIPS_EVENT_MODE_FAULT 1 /**< Mode fault error */
|
||||
#define XSPIPS_EVENT_TRANSFER_DONE 2 /**< Transfer done */
|
||||
#define XSPIPS_EVENT_TRANSMIT_UNDERRUN 3 /**< TX FIFO empty */
|
||||
#define XSPIPS_EVENT_RECEIVE_OVERRUN 4 /**< Receive data loss because
|
||||
RX FIFO full */
|
||||
/*@}*/
|
||||
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
/**
|
||||
* The handler data type allows the user to define a callback function to
|
||||
* handle the asynchronous processing for the SPI device. The application
|
||||
* using this driver is expected to define a handler of this type to support
|
||||
* interrupt driven mode. The handler executes in an interrupt context, so
|
||||
* only minimal processing should be performed.
|
||||
*
|
||||
* @param CallBackRef is the callback reference passed in by the upper
|
||||
* layer when setting the callback functions, and passed back to
|
||||
* the upper layer when the callback is invoked. Its type is
|
||||
* not important to the driver, so it is a void pointer.
|
||||
* @param StatusEvent holds one or more status events that have occurred.
|
||||
* See the XSpiPs_SetStatusHandler() for details on the status
|
||||
* events that can be passed in the callback.
|
||||
* @param ByteCount indicates how many bytes of data were successfully
|
||||
* transferred. This may be less than the number of bytes
|
||||
* requested if the status event indicates an error.
|
||||
*/
|
||||
typedef void (*XSpiPs_StatusHandler) (void *CallBackRef, u32 StatusEvent,
|
||||
unsigned ByteCount);
|
||||
|
||||
/**
|
||||
* This typedef contains configuration information for the device.
|
||||
*/
|
||||
typedef struct {
|
||||
u16 DeviceId; /**< Unique ID of device */
|
||||
u32 BaseAddress; /**< Base address of the device */
|
||||
u32 InputClockHz; /**< Input clock frequency */
|
||||
} XSpiPs_Config;
|
||||
|
||||
/**
|
||||
* The XSpiPs driver instance data. The user is required to allocate a
|
||||
* variable of this type for every SPI device in the system. A pointer
|
||||
* to a variable of this type is then passed to the driver API functions.
|
||||
*/
|
||||
typedef struct {
|
||||
XSpiPs_Config Config; /**< Configuration structure */
|
||||
u32 IsReady; /**< Device is initialized and ready */
|
||||
|
||||
u8 *SendBufferPtr; /**< Buffer to send (state) */
|
||||
u8 *RecvBufferPtr; /**< Buffer to receive (state) */
|
||||
unsigned RequestedBytes; /**< Number of bytes to transfer (state) */
|
||||
unsigned RemainingBytes; /**< Number of bytes left to transfer(state) */
|
||||
u32 IsBusy; /**< A transfer is in progress (state) */
|
||||
u32 SlaveSelect; /**< The slave select value when
|
||||
XSPIPS_FORCE_SSELECT_OPTION is set */
|
||||
|
||||
XSpiPs_StatusHandler StatusHandler;
|
||||
void *StatusRef; /**< Callback reference for status handler */
|
||||
|
||||
} XSpiPs;
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
/****************************************************************************/
|
||||
/*
|
||||
*
|
||||
* Check in OptionsTable if Manual Start Option is enabled or disabled.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XSpiPs instance.
|
||||
*
|
||||
* @return
|
||||
* - TRUE if option is set
|
||||
* - FALSE if option is not set
|
||||
*
|
||||
* @note C-Style signature:
|
||||
* u8 XSpiPs_IsManualStart(XSpiPs *InstancePtr);
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XSpiPs_IsManualStart(InstancePtr) \
|
||||
((XSpiPs_GetOptions(InstancePtr) & \
|
||||
XSPIPS_MANUAL_START_OPTION) ? TRUE : FALSE)
|
||||
|
||||
/****************************************************************************/
|
||||
/*
|
||||
*
|
||||
* Check in OptionsTable if Manual Chip Select Option is enabled or disabled.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XSpiPs instance.
|
||||
*
|
||||
* @return
|
||||
* - TRUE if option is set
|
||||
* - FALSE if option is not set
|
||||
*
|
||||
* @note C-Style signature:
|
||||
* u8 XSpiPs_IsManualChipSelect(XSpiPs *InstancePtr);
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XSpiPs_IsManualChipSelect(InstancePtr) \
|
||||
((XSpiPs_GetOptions(InstancePtr) & \
|
||||
XSPIPS_FORCE_SSELECT_OPTION) ? TRUE : FALSE)
|
||||
|
||||
/****************************************************************************/
|
||||
/*
|
||||
*
|
||||
* Check in OptionsTable if Decode Slave Select option is enabled or disabled.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XSpiPs instance.
|
||||
*
|
||||
* @return
|
||||
* - TRUE if option is set
|
||||
* - FALSE if option is not set
|
||||
*
|
||||
* @note C-Style signature:
|
||||
* u8 XSpiPs_IsDecodeSSelect(XSpiPs *InstancePtr);
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XSpiPs_IsDecodeSSelect(InstancePtr) \
|
||||
((XSpiPs_GetOptions(InstancePtr) & \
|
||||
XSPIPS_DECODE_SSELECT_OPTION) ? TRUE : FALSE)
|
||||
|
||||
/****************************************************************************/
|
||||
/*
|
||||
*
|
||||
* Check in OptionsTable if Master Option is enabled or disabled.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XSpiPs instance.
|
||||
*
|
||||
* @return
|
||||
* - TRUE if option is set
|
||||
* - FALSE if option is not set
|
||||
*
|
||||
* @note C-Style signature:
|
||||
* u8 XSpiPs_IsMaster(XSpiPs *InstancePtr);
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XSpiPs_IsMaster(InstancePtr) \
|
||||
((XSpiPs_GetOptions(InstancePtr) & \
|
||||
XSPIPS_MASTER_OPTION) ? TRUE : FALSE)
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Set the contents of the slave idle count register.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XSpiPs instance.
|
||||
* @param RegisterValue is the value to be writen, valid values are
|
||||
* 0-255.
|
||||
*
|
||||
* @return None
|
||||
*
|
||||
* @note
|
||||
* C-Style signature:
|
||||
* void XSpiPs_SetSlaveIdle(XSpiPs *InstancePtr, u32 RegisterValue)
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XSpiPs_SetSlaveIdle(InstancePtr, RegisterValue) \
|
||||
XSpiPs_Out32(((InstancePtr)->Config.BaseAddress) + \
|
||||
XSPIPS_SICR_OFFSET, (RegisterValue))
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Get the contents of the slave idle count register. Use the XSPIPS_SICR_*
|
||||
* constants defined in xspips_hw.h to interpret the bit-mask returned.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XSpiPs instance.
|
||||
*
|
||||
* @return 8-bit value representing the contents of the SIC register.
|
||||
*
|
||||
* @note C-Style signature:
|
||||
* u32 XSpiPs_GetSlaveIdle(XSpiPs *InstancePtr)
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XSpiPs_GetSlaveIdle(InstancePtr) \
|
||||
XSpiPs_In32(((InstancePtr)->Config.BaseAddress) + \
|
||||
XSPIPS_SICR_OFFSET)
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Set the contents of the transmit FIFO watermark register.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XSpiPs instance.
|
||||
* @param RegisterValue is the value to be written, valid values
|
||||
* are 1-128.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note
|
||||
* C-Style signature:
|
||||
* void XSpiPs_SetTXWatermark(XSpiPs *InstancePtr, u32 RegisterValue)
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XSpiPs_SetTXWatermark(InstancePtr, RegisterValue) \
|
||||
XSpiPs_Out32(((InstancePtr)->Config.BaseAddress) + \
|
||||
XSPIPS_TXWR_OFFSET, (RegisterValue))
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Get the contents of the transmit FIFO watermark register.
|
||||
* Use the XSPIPS_TXWR_* constants defined xspips_hw.h to interpret
|
||||
* the bit-mask returned.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XSpiPs instance.
|
||||
*
|
||||
* @return 8-bit value representing the contents of the TXWR register.
|
||||
*
|
||||
* @note C-Style signature:
|
||||
* u32 XSpiPs_GetTXWatermark(u32 *InstancePtr)
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XSpiPs_GetTXWatermark(InstancePtr) \
|
||||
XSpiPs_In32((InstancePtr->Config.BaseAddress) + XSPIPS_TXWR_OFFSET)
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Set the contents of the receive FIFO watermark register.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XSpiPs instance.
|
||||
* @param RegisterValue is the value to be written, valid values
|
||||
* are 1-128.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note
|
||||
* C-Style signature:
|
||||
* void XSpiPs_SetRXWatermark(XSpiPs *InstancePtr, u32 RegisterValue)
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XSpiPs_SetRXWatermark(InstancePtr, RegisterValue) \
|
||||
XSpiPs_Out32(((InstancePtr)->Config.BaseAddress) + \
|
||||
XSPIPS_RXWR_OFFSET, (RegisterValue))
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Get the contents of the receive FIFO watermark register.
|
||||
* Use the XSPIPS_RXWR_* constants defined xspips_hw.h to interpret
|
||||
* the bit-mask returned.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XSpiPs instance.
|
||||
*
|
||||
* @return A 8-bit value representing the contents of the RXWR register.
|
||||
*
|
||||
* @note C-Style signature:
|
||||
* u32 XSpiPs_GetRXWatermark(u32 *InstancePtr)
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XSpiPs_GetRXWatermark(InstancePtr) \
|
||||
XSpiPs_In32((InstancePtr->Config.BaseAddress) + XSPIPS_RXWR_OFFSET)
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Enable the device and uninhibit master transactions.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XSpiPs instance.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note C-Style signature:
|
||||
* void XSpiPs_Enable(u32 *InstancePtr)
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XSpiPs_Enable(InstancePtr) \
|
||||
XSpiPs_Out32((InstancePtr->Config.BaseAddress) + XSPIPS_ER_OFFSET, \
|
||||
XSPIPS_ER_ENABLE_MASK)
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Disable the device.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XSpiPs instance.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note C-Style signature:
|
||||
* void XSpiPs_Disable(u32 *InstancePtr)
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XSpiPs_Disable(InstancePtr) \
|
||||
XSpiPs_Out32((InstancePtr->Config.BaseAddress) + XSPIPS_ER_OFFSET, 0)
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
/*
|
||||
* Initialization function, implemented in xspips_sinit.c
|
||||
*/
|
||||
XSpiPs_Config *XSpiPs_LookupConfig(u16 DeviceId);
|
||||
|
||||
/*
|
||||
* Functions implemented in xspips.c
|
||||
*/
|
||||
int XSpiPs_CfgInitialize(XSpiPs *InstancePtr, XSpiPs_Config * Config,
|
||||
u32 EffectiveAddr);
|
||||
|
||||
void XSpiPs_Reset(XSpiPs *InstancePtr);
|
||||
|
||||
int XSpiPs_Transfer(XSpiPs *InstancePtr, u8 *SendBufPtr, u8 *RecvBufPtr,
|
||||
unsigned ByteCount);
|
||||
|
||||
int XSpiPs_PolledTransfer(XSpiPs *InstancePtr, u8 *SendBufPtr,
|
||||
u8 *RecvBufPtr, unsigned ByteCount);
|
||||
|
||||
void XSpiPs_SetStatusHandler(XSpiPs *InstancePtr, void *CallBackRef,
|
||||
XSpiPs_StatusHandler FuncPtr);
|
||||
void XSpiPs_InterruptHandler(void *InstancePtr);
|
||||
|
||||
void XSpiPs_Abort(XSpiPs *InstancePtr);
|
||||
|
||||
int XSpiPs_SetSlaveSelect(XSpiPs *InstancePtr, u8 SelectValue);
|
||||
u8 XSpiPs_GetSlaveSelect(XSpiPs *InstancePtr);
|
||||
|
||||
/*
|
||||
* Functions for selftest, in xspips_selftest.c
|
||||
*/
|
||||
int XSpiPs_SelfTest(XSpiPs *InstancePtr);
|
||||
|
||||
/*
|
||||
* Functions for options, in xspips_options.c
|
||||
*/
|
||||
int XSpiPs_SetOptions(XSpiPs *InstancePtr, u32 Options);
|
||||
u32 XSpiPs_GetOptions(XSpiPs *InstancePtr);
|
||||
|
||||
int XSpiPs_SetClkPrescaler(XSpiPs *InstancePtr, u8 Prescaler);
|
||||
u8 XSpiPs_GetClkPrescaler(XSpiPs *InstancePtr);
|
||||
|
||||
int XSpiPs_SetDelays(XSpiPs *InstancePtr, u8 DelayNss, u8 DelayBtwn,
|
||||
u8 DelayAfter, u8 DelayInit);
|
||||
void XSpiPs_GetDelays(XSpiPs *InstancePtr, u8 *DelayNss, u8 *DelayBtwn,
|
||||
u8 *DelayAfter, u8 *DelayInit);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* end of protection macro */
|
86
XilinxProcessorIPLib/drivers/spips/src/xspips_g.c
Executable file
86
XilinxProcessorIPLib/drivers/spips/src/xspips_g.c
Executable file
|
@ -0,0 +1,86 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2010 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @file xspips_g.c
|
||||
*
|
||||
* This file contains a configuration table that specifies the configuration of
|
||||
* SPI devices in the system.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ------ -------- -----------------------------------------------
|
||||
* 1.00 drg/jz 01/25/10 First release
|
||||
* 2.00 hk 22/01/14 Added check for picking second instance
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
#include "xspips.h"
|
||||
#include "xparameters.h"
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
|
||||
/************************** Variable Prototypes ******************************/
|
||||
|
||||
/**
|
||||
* This table contains configuration information for each SPI device
|
||||
* in the system.
|
||||
*/
|
||||
XSpiPs_Config XSpiPs_ConfigTable[XPAR_XSPIPS_NUM_INSTANCES] = {
|
||||
{
|
||||
XPAR_XSPIPS_0_DEVICE_ID, /* Device ID for instance */
|
||||
XPAR_XSPIPS_0_BASEADDR, /* Device base address */
|
||||
XPAR_XSPIPS_0_CLOCK_HZ
|
||||
},
|
||||
#ifdef XPAR_XSPIPS_1_DEVICE_ID
|
||||
{
|
||||
XPAR_XSPIPS_1_DEVICE_ID, /* Device ID for instance */
|
||||
XPAR_XSPIPS_1_BASEADDR, /* Device base address */
|
||||
XPAR_XSPIPS_1_CLOCK_HZ
|
||||
}
|
||||
#endif
|
||||
};
|
125
XilinxProcessorIPLib/drivers/spips/src/xspips_hw.c
Executable file
125
XilinxProcessorIPLib/drivers/spips/src/xspips_hw.c
Executable file
|
@ -0,0 +1,125 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2013 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @file xspips_hw.c
|
||||
*
|
||||
* Contains the reset and post boot rom state initialization.
|
||||
* Function prototypes in xspips_hw.h
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ------ -------- -----------------------------------------------
|
||||
* 1.06a hk 08/22/13 First release.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
#include "xspips_hw.h"
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
|
||||
/************************** Variable Definitions *****************************/
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Resets the spi module
|
||||
*
|
||||
* @param None
|
||||
*
|
||||
* @return None
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
void XSpiPs_ResetHw(u32 BaseAddress)
|
||||
{
|
||||
|
||||
/*
|
||||
* Disable Interrupts
|
||||
*/
|
||||
XSpiPs_WriteReg(BaseAddress, XSPIPS_IDR_OFFSET,
|
||||
XSPIPS_IXR_DISABLE_ALL_MASK);
|
||||
|
||||
/*
|
||||
* Disable device
|
||||
*/
|
||||
XSpiPs_WriteReg(BaseAddress, XSPIPS_ER_OFFSET,
|
||||
0);
|
||||
/*
|
||||
* Write default value to RX and TX threshold registers
|
||||
* RX threshold should be set to 1 here as the corresponding
|
||||
* status bit is used to clear the FIFO next
|
||||
*/
|
||||
XSpiPs_WriteReg(BaseAddress, XSPIPS_TXWR_OFFSET,
|
||||
(XSPIPS_TXWR_RESET_VALUE & XSPIPS_TXWR_MASK));
|
||||
XSpiPs_WriteReg(BaseAddress, XSPIPS_RXWR_OFFSET,
|
||||
(XSPIPS_RXWR_RESET_VALUE & XSPIPS_RXWR_MASK));
|
||||
|
||||
/*
|
||||
* Clear RXFIFO
|
||||
*/
|
||||
while ((XSpiPs_ReadReg(BaseAddress,XSPIPS_SR_OFFSET) &
|
||||
XSPIPS_IXR_RXNEMPTY_MASK) != 0) {
|
||||
XSpiPs_ReadReg(BaseAddress, XSPIPS_RXD_OFFSET);
|
||||
}
|
||||
|
||||
/*
|
||||
* Clear status register by writing 1 to the write to clear bits
|
||||
*/
|
||||
XSpiPs_WriteReg(BaseAddress, XSPIPS_SR_OFFSET,
|
||||
XSPIPS_IXR_WR_TO_CLR_MASK);
|
||||
|
||||
/*
|
||||
* Write default value to configuration register
|
||||
* De-select all slaves
|
||||
*/
|
||||
XSpiPs_WriteReg(BaseAddress, XSPIPS_CR_OFFSET,
|
||||
XSPIPS_CR_RESET_STATE |
|
||||
XSPIPS_CR_SSCTRL_MASK);
|
||||
|
||||
}
|
309
XilinxProcessorIPLib/drivers/spips/src/xspips_hw.h
Executable file
309
XilinxProcessorIPLib/drivers/spips/src/xspips_hw.h
Executable file
|
@ -0,0 +1,309 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2010 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @file xspips_hw.h
|
||||
*
|
||||
* This header file contains the identifiers and basic driver functions (or
|
||||
* macros) that can be used to access the device. Other driver functions
|
||||
* are defined in xspips.h.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ------ -------- -----------------------------------------------
|
||||
* 1.00 drg/jz 01/25/10 First release
|
||||
* 1.02a sg 05/31/12 Updated XSPIPS_FIFO_DEPTH to 128 from 32 to match HW
|
||||
* for CR 658289
|
||||
* 1.04a sg 01/30/13 Created XSPIPS_CR_MODF_GEN_EN_MASK macro and added it
|
||||
* to XSPIPS_CR_RESET_STATE. Created
|
||||
* XSPIPS_IXR_WR_TO_CLR_MASK for interrupts which need
|
||||
* write-to-clear. Added shift and mask macros for d_nss
|
||||
* parameter. Added Rx Watermark mask.
|
||||
* 1.06a hk 08/22/13 Added prototypes of reset API and related constant
|
||||
* definitions.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef XSPIPS_HW_H /* prevent circular inclusions */
|
||||
#define XSPIPS_HW_H /* by using protection macros */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
#include "xil_types.h"
|
||||
#include "xil_assert.h"
|
||||
#include "xil_io.h"
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
/** @name Register Map
|
||||
*
|
||||
* Register offsets from the base address of an SPI device.
|
||||
* @{
|
||||
*/
|
||||
#define XSPIPS_CR_OFFSET 0x00 /**< Configuration */
|
||||
#define XSPIPS_SR_OFFSET 0x04 /**< Interrupt Status */
|
||||
#define XSPIPS_IER_OFFSET 0x08 /**< Interrupt Enable */
|
||||
#define XSPIPS_IDR_OFFSET 0x0c /**< Interrupt Disable */
|
||||
#define XSPIPS_IMR_OFFSET 0x10 /**< Interrupt Enabled Mask */
|
||||
#define XSPIPS_ER_OFFSET 0x14 /**< Enable/Disable Register */
|
||||
#define XSPIPS_DR_OFFSET 0x18 /**< Delay Register */
|
||||
#define XSPIPS_TXD_OFFSET 0x1C /**< Data Transmit Register */
|
||||
#define XSPIPS_RXD_OFFSET 0x20 /**< Data Receive Register */
|
||||
#define XSPIPS_SICR_OFFSET 0x24 /**< Slave Idle Count */
|
||||
#define XSPIPS_TXWR_OFFSET 0x28 /**< Transmit FIFO Watermark */
|
||||
#define XSPIPS_RXWR_OFFSET 0x2C /**< Receive FIFO Watermark */
|
||||
/* @} */
|
||||
|
||||
/** @name Configuration Register
|
||||
*
|
||||
* This register contains various control bits that
|
||||
* affects the operation of an SPI device. Read/Write.
|
||||
* @{
|
||||
*/
|
||||
#define XSPIPS_CR_MODF_GEN_EN_MASK 0x00020000 /**< Modefail Generation
|
||||
Enable */
|
||||
#define XSPIPS_CR_MANSTRT_MASK 0x00010000 /**< Manual Transmission Start */
|
||||
#define XSPIPS_CR_MANSTRTEN_MASK 0x00008000 /**< Manual Transmission Start
|
||||
Enable */
|
||||
#define XSPIPS_CR_SSFORCE_MASK 0x00004000 /**< Force Slave Select */
|
||||
#define XSPIPS_CR_SSCTRL_MASK 0x00003C00 /**< Slave Select Decode */
|
||||
#define XSPIPS_CR_SSCTRL_SHIFT 10 /**< Slave Select Decode shift */
|
||||
#define XSPIPS_CR_SSCTRL_MAXIMUM 0xF /**< Slave Select maximum value */
|
||||
#define XSPIPS_CR_SSDECEN_MASK 0x00000200 /**< Slave Select Decode Enable */
|
||||
|
||||
#define XSPIPS_CR_PRESC_MASK 0x00000038 /**< Prescaler Setting */
|
||||
#define XSPIPS_CR_PRESC_SHIFT 3 /**< Prescaler shift */
|
||||
#define XSPIPS_CR_PRESC_MAXIMUM 0x07 /**< Prescaler maximum value */
|
||||
|
||||
#define XSPIPS_CR_CPHA_MASK 0x00000004 /**< Phase Configuration */
|
||||
#define XSPIPS_CR_CPOL_MASK 0x00000002 /**< Polarity Configuration */
|
||||
|
||||
#define XSPIPS_CR_MSTREN_MASK 0x00000001 /**< Master Mode Enable */
|
||||
#define XSPIPS_CR_RESET_STATE 0x00020000 /**< Mode Fail Generation Enable */
|
||||
/* @} */
|
||||
|
||||
|
||||
/** @name SPI Interrupt Registers
|
||||
*
|
||||
* <b>SPI Status Register</b>
|
||||
*
|
||||
* This register holds the interrupt status flags for an SPI device. Some
|
||||
* of the flags are level triggered, which means that they are set as long
|
||||
* as the interrupt condition exists. Other flags are edge triggered,
|
||||
* which means they are set once the interrupt condition occurs and remain
|
||||
* set until they are cleared by software. The interrupts are cleared by
|
||||
* writing a '1' to the interrupt bit position in the Status Register.
|
||||
* Read/Write.
|
||||
*
|
||||
* <b>SPI Interrupt Enable Register</b>
|
||||
*
|
||||
* This register is used to enable chosen interrupts for an SPI device.
|
||||
* Writing a '1' to a bit in this register sets the corresponding bit in the
|
||||
* SPI Interrupt Mask register. Write only.
|
||||
*
|
||||
* <b>SPI Interrupt Disable Register </b>
|
||||
*
|
||||
* This register is used to disable chosen interrupts for an SPI device.
|
||||
* Writing a '1' to a bit in this register clears the corresponding bit in the
|
||||
* SPI Interrupt Mask register. Write only.
|
||||
*
|
||||
* <b>SPI Interrupt Mask Register</b>
|
||||
*
|
||||
* This register shows the enabled/disabled interrupts of an SPI device.
|
||||
* Read only.
|
||||
*
|
||||
* All four registers have the same bit definitions. They are only defined once
|
||||
* for each of the Interrupt Enable Register, Interrupt Disable Register,
|
||||
* Interrupt Mask Register, and Channel Interrupt Status Register
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define XSPIPS_IXR_TXUF_MASK 0x00000040 /**< Tx FIFO Underflow */
|
||||
#define XSPIPS_IXR_RXFULL_MASK 0x00000020 /**< Rx FIFO Full */
|
||||
#define XSPIPS_IXR_RXNEMPTY_MASK 0x00000010 /**< Rx FIFO Not Empty */
|
||||
#define XSPIPS_IXR_TXFULL_MASK 0x00000008 /**< Tx FIFO Full */
|
||||
#define XSPIPS_IXR_TXOW_MASK 0x00000004 /**< Tx FIFO Overwater */
|
||||
#define XSPIPS_IXR_MODF_MASK 0x00000002 /**< Mode Fault */
|
||||
#define XSPIPS_IXR_RXOVR_MASK 0x00000001 /**< Rx FIFO Overrun */
|
||||
#define XSPIPS_IXR_DFLT_MASK 0x00000027 /**< Default interrupts
|
||||
mask */
|
||||
#define XSPIPS_IXR_WR_TO_CLR_MASK 0x00000043 /**< Interrupts which
|
||||
need write to clear */
|
||||
#define XSPIPS_ISR_RESET_STATE 0x04 /**< Default to tx/rx
|
||||
* reg empty */
|
||||
#define XSPIPS_IXR_DISABLE_ALL_MASK 0x00000043 /**< Disable all
|
||||
* interrupts */
|
||||
/* @} */
|
||||
|
||||
|
||||
/** @name Enable Register
|
||||
*
|
||||
* This register is used to enable or disable an SPI device.
|
||||
* Read/Write
|
||||
* @{
|
||||
*/
|
||||
#define XSPIPS_ER_ENABLE_MASK 0x00000001 /**< SPI Enable Bit Mask */
|
||||
/* @} */
|
||||
|
||||
|
||||
/** @name Delay Register
|
||||
*
|
||||
* This register is used to program timing delays in
|
||||
* slave mode. Read/Write
|
||||
* @{
|
||||
*/
|
||||
#define XSPIPS_DR_NSS_MASK 0xFF000000 /**< Delay for slave select
|
||||
* de-assertion between
|
||||
* word transfers mask */
|
||||
#define XSPIPS_DR_NSS_SHIFT 24 /**< Delay for slave select
|
||||
* de-assertion between
|
||||
* word transfers shift */
|
||||
#define XSPIPS_DR_BTWN_MASK 0x00FF0000 /**< Delay Between Transfers mask */
|
||||
#define XSPIPS_DR_BTWN_SHIFT 16 /**< Delay Between Transfers shift */
|
||||
#define XSPIPS_DR_AFTER_MASK 0x0000FF00 /**< Delay After Transfers mask */
|
||||
#define XSPIPS_DR_AFTER_SHIFT 8 /**< Delay After Transfers shift */
|
||||
#define XSPIPS_DR_INIT_MASK 0x000000FF /**< Delay Initially mask */
|
||||
/* @} */
|
||||
|
||||
|
||||
/** @name Slave Idle Count Registers
|
||||
*
|
||||
* This register defines the number of pclk cycles the slave waits for a the
|
||||
* SPI clock to become stable in quiescent state before it can detect the start
|
||||
* of the next transfer in CPHA = 1 mode.
|
||||
* Read/Write
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
#define XSPIPS_SICR_MASK 0x000000FF /**< Slave Idle Count Mask */
|
||||
/* @} */
|
||||
|
||||
|
||||
|
||||
/** @name Transmit FIFO Watermark Register
|
||||
*
|
||||
* This register defines the watermark setting for the Transmit FIFO. The
|
||||
* transmit FIFO is 128 bytes deep, so the register is 7 bits. Valid values
|
||||
* are 1 to 128.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
#define XSPIPS_TXWR_MASK 0x0000007F /**< Transmit Watermark Mask */
|
||||
#define XSPIPS_TXWR_RESET_VALUE 0x00000001 /**< Transmit Watermark
|
||||
* register reset value */
|
||||
/* @} */
|
||||
|
||||
/** @name Receive FIFO Watermark Register
|
||||
*
|
||||
* This register defines the watermark setting for the Receive FIFO. The
|
||||
* receive FIFO is 128 bytes deep, so the register is 7 bits. Valid values
|
||||
* are 1 to 128.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
#define XSPIPS_RXWR_MASK 0x0000007F /**< Receive Watermark Mask */
|
||||
#define XSPIPS_RXWR_RESET_VALUE 0x00000001 /**< Receive Watermark
|
||||
* register reset value */
|
||||
/* @} */
|
||||
|
||||
/** @name FIFO Depth
|
||||
*
|
||||
* This macro provides the depth of transmit FIFO and receive FIFO.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
#define XSPIPS_FIFO_DEPTH 128 /**< FIFO depth of Tx and Rx */
|
||||
/* @} */
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
#define XSpiPs_In32 Xil_In32
|
||||
#define XSpiPs_Out32 Xil_Out32
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
* Read a register.
|
||||
*
|
||||
* @param BaseAddress contains the base address of the device.
|
||||
* @param RegOffset contains the offset from the 1st register of the
|
||||
* device to the target register.
|
||||
*
|
||||
* @return The value read from the register.
|
||||
*
|
||||
* @note C-Style signature:
|
||||
* u32 XSpiPs_ReadReg(u32 BaseAddress. int RegOffset)
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XSpiPs_ReadReg(BaseAddress, RegOffset) \
|
||||
XSpiPs_In32((BaseAddress) + (RegOffset))
|
||||
|
||||
/***************************************************************************/
|
||||
/**
|
||||
* Write to a register.
|
||||
*
|
||||
* @param BaseAddress contains the base address of the device.
|
||||
* @param RegOffset contains the offset from the 1st register of the
|
||||
* device to target register.
|
||||
* @param RegisterValue is the value to be written to the register.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note C-Style signature:
|
||||
* void XSpiPs_WriteReg(u32 BaseAddress, int RegOffset,
|
||||
* u32 RegisterValue)
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XSpiPs_WriteReg(BaseAddress, RegOffset, RegisterValue) \
|
||||
XSpiPs_Out32((BaseAddress) + (RegOffset), (RegisterValue))
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
void XSpiPs_ResetHw(u32 BaseAddress);
|
||||
|
||||
/************************** Variable Definitions *****************************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* end of protection macro */
|
420
XilinxProcessorIPLib/drivers/spips/src/xspips_options.c
Executable file
420
XilinxProcessorIPLib/drivers/spips/src/xspips_options.c
Executable file
|
@ -0,0 +1,420 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2010 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @file xspips_options.c
|
||||
*
|
||||
* Contains functions for the configuration of the XSpiPs driver.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ------ -------- -----------------------------------------------
|
||||
* 1.00 drg/jz 01/25/10 First release
|
||||
* 1.00 sdm 10/25/11 Removed the Divide by 2 in the SPI Clock Prescaler
|
||||
* options as this is not supported in the device
|
||||
* 1.04a sg 01/30/13 Added XSPIPS_MANUAL_START_OPTION. SetDelays and
|
||||
* GetDelays API's include DelayNss parameter.
|
||||
* 1.05a hk 26/04/13 Added disable and enable in XSpiPs_SetOptions when
|
||||
* CPOL/CPHA bits are set/reset. Fix for CR#707669.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
#include "xspips.h"
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
|
||||
/************************** Variable Definitions *****************************/
|
||||
|
||||
/*
|
||||
* Create the table of options which are processed to get/set the device
|
||||
* options. These options are table driven to allow easy maintenance and
|
||||
* expansion of the options.
|
||||
*/
|
||||
typedef struct {
|
||||
u32 Option;
|
||||
u32 Mask;
|
||||
} OptionsMap;
|
||||
|
||||
static OptionsMap OptionsTable[] = {
|
||||
{XSPIPS_MASTER_OPTION, XSPIPS_CR_MSTREN_MASK},
|
||||
{XSPIPS_CLK_ACTIVE_LOW_OPTION, XSPIPS_CR_CPOL_MASK},
|
||||
{XSPIPS_CLK_PHASE_1_OPTION, XSPIPS_CR_CPHA_MASK},
|
||||
{XSPIPS_DECODE_SSELECT_OPTION, XSPIPS_CR_SSDECEN_MASK},
|
||||
{XSPIPS_FORCE_SSELECT_OPTION, XSPIPS_CR_SSFORCE_MASK},
|
||||
{XSPIPS_MANUAL_START_OPTION, XSPIPS_CR_MANSTRTEN_MASK}
|
||||
};
|
||||
|
||||
#define XSPIPS_NUM_OPTIONS (sizeof(OptionsTable) / sizeof(OptionsMap))
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function sets the options for the SPI device driver. The options control
|
||||
* how the device behaves relative to the SPI bus. The device must be idle
|
||||
* rather than busy transferring data before setting these device options.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XSpiPs instance.
|
||||
* @param Options contains the specified options to be set. This is a bit
|
||||
* mask where a 1 means to turn the option on, and a 0 means to
|
||||
* turn the option off. One or more bit values may be contained in
|
||||
* the mask. See the bit definitions named XSPIPS_*_OPTIONS in the
|
||||
* file xspips.h.
|
||||
*
|
||||
* @return
|
||||
* - XST_SUCCESS if options are successfully set.
|
||||
* - XST_DEVICE_BUSY if the device is currently transferring data.
|
||||
* The transfer must complete or be aborted before setting options.
|
||||
*
|
||||
* @note
|
||||
* This function is not thread-safe.
|
||||
*
|
||||
******************************************************************************/
|
||||
int XSpiPs_SetOptions(XSpiPs *InstancePtr, u32 Options)
|
||||
{
|
||||
u32 ConfigReg;
|
||||
unsigned int Index;
|
||||
u32 CurrentConfigReg;
|
||||
|
||||
Xil_AssertNonvoid(InstancePtr != NULL);
|
||||
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
|
||||
/*
|
||||
* Do not allow the slave select to change while a transfer is in
|
||||
* progress. Not thread-safe.
|
||||
*/
|
||||
if (InstancePtr->IsBusy) {
|
||||
return XST_DEVICE_BUSY;
|
||||
}
|
||||
|
||||
ConfigReg = XSpiPs_ReadReg(InstancePtr->Config.BaseAddress,
|
||||
XSPIPS_CR_OFFSET);
|
||||
|
||||
CurrentConfigReg = ConfigReg;
|
||||
|
||||
/*
|
||||
* Loop through the options table, turning the option on or off
|
||||
* depending on whether the bit is set in the incoming options flag.
|
||||
*/
|
||||
for (Index = 0; Index < XSPIPS_NUM_OPTIONS; Index++) {
|
||||
if (Options & OptionsTable[Index].Option) {
|
||||
/* Turn it on */
|
||||
ConfigReg |= OptionsTable[Index].Mask;
|
||||
}
|
||||
else {
|
||||
/* Turn it off */
|
||||
ConfigReg &= ~(OptionsTable[Index].Mask);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* If CPOL-CPHA bits are toggled from previous state,
|
||||
* disable before writing the configuration register and then enable.
|
||||
*/
|
||||
if( ((CurrentConfigReg & XSPIPS_CR_CPOL_MASK) !=
|
||||
(ConfigReg & XSPIPS_CR_CPOL_MASK)) ||
|
||||
((CurrentConfigReg & XSPIPS_CR_CPHA_MASK) !=
|
||||
(ConfigReg & XSPIPS_CR_CPHA_MASK)) ) {
|
||||
XSpiPs_Disable(InstancePtr);
|
||||
}
|
||||
|
||||
/*
|
||||
* Now write the Config register. Leave it to the upper layers
|
||||
* to restart the device.
|
||||
*/
|
||||
XSpiPs_WriteReg(InstancePtr->Config.BaseAddress,
|
||||
XSPIPS_CR_OFFSET, ConfigReg);
|
||||
|
||||
/*
|
||||
* Enable
|
||||
*/
|
||||
if( ((CurrentConfigReg & XSPIPS_CR_CPOL_MASK) !=
|
||||
(ConfigReg & XSPIPS_CR_CPOL_MASK)) ||
|
||||
((CurrentConfigReg & XSPIPS_CR_CPHA_MASK) !=
|
||||
(ConfigReg & XSPIPS_CR_CPHA_MASK)) ) {
|
||||
XSpiPs_Enable(InstancePtr);
|
||||
}
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function gets the options for the SPI device. The options control how
|
||||
* the device behaves relative to the SPI bus.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XSpiPs instance.
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* Options contains the specified options currently set. This is a bit value
|
||||
* where a 1 means the option is on, and a 0 means the option is off.
|
||||
* See the bit definitions named XSPIPS_*_OPTIONS in file xspips.h.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
u32 XSpiPs_GetOptions(XSpiPs *InstancePtr)
|
||||
{
|
||||
u32 OptionsFlag = 0;
|
||||
u32 ConfigReg;
|
||||
unsigned int Index;
|
||||
|
||||
Xil_AssertNonvoid(InstancePtr != NULL);
|
||||
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
|
||||
/*
|
||||
* Get the current options
|
||||
*/
|
||||
ConfigReg =
|
||||
XSpiPs_ReadReg(InstancePtr->Config.BaseAddress,
|
||||
XSPIPS_CR_OFFSET);
|
||||
|
||||
/*
|
||||
* Loop through the options table to grab options
|
||||
*/
|
||||
for (Index = 0; Index < XSPIPS_NUM_OPTIONS; Index++) {
|
||||
if (ConfigReg & OptionsTable[Index].Mask) {
|
||||
OptionsFlag |= OptionsTable[Index].Option;
|
||||
}
|
||||
}
|
||||
|
||||
return OptionsFlag;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function sets the clock prescaler for an SPI device. The device
|
||||
* must be idle rather than busy transferring data before setting these device
|
||||
* options.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XSpiPs instance.
|
||||
* @param Prescaler is the value that determine how much the clock should
|
||||
* be divided by. Use the XSPIPS_CLK_PRESCALE_* constants defined
|
||||
* in xspips.h for this setting.
|
||||
*
|
||||
* @return
|
||||
* - XST_SUCCESS if options are successfully set.
|
||||
* - XST_DEVICE_BUSY if the device is currently transferring data.
|
||||
* The transfer must complete or be aborted before setting options.
|
||||
*
|
||||
* @note
|
||||
* This function is not thread-safe.
|
||||
*
|
||||
******************************************************************************/
|
||||
int XSpiPs_SetClkPrescaler(XSpiPs *InstancePtr, u8 Prescaler)
|
||||
{
|
||||
u32 ConfigReg;
|
||||
|
||||
Xil_AssertNonvoid(InstancePtr != NULL);
|
||||
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
Xil_AssertNonvoid((Prescaler > 0) && (Prescaler <= XSPIPS_CR_PRESC_MAXIMUM));
|
||||
|
||||
/*
|
||||
* Do not allow the prescaler to be changed while a transfer is in
|
||||
* progress. Not thread-safe.
|
||||
*/
|
||||
if (InstancePtr->IsBusy) {
|
||||
return XST_DEVICE_BUSY;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read the Config register, mask out the interesting bits, and set
|
||||
* them with the shifted value passed into the function. Write the
|
||||
* results back to the Config register.
|
||||
*/
|
||||
ConfigReg = XSpiPs_ReadReg(InstancePtr->Config.BaseAddress,
|
||||
XSPIPS_CR_OFFSET);
|
||||
|
||||
ConfigReg &= ~XSPIPS_CR_PRESC_MASK;
|
||||
ConfigReg |= (u32) (Prescaler & XSPIPS_CR_PRESC_MAXIMUM) <<
|
||||
XSPIPS_CR_PRESC_SHIFT;
|
||||
|
||||
XSpiPs_WriteReg(InstancePtr->Config.BaseAddress,
|
||||
XSPIPS_CR_OFFSET,
|
||||
ConfigReg);
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function gets the clock prescaler of an SPI device.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XSpiPs instance.
|
||||
*
|
||||
* @return The prescaler value.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
*
|
||||
******************************************************************************/
|
||||
u8 XSpiPs_GetClkPrescaler(XSpiPs *InstancePtr)
|
||||
{
|
||||
u32 ConfigReg;
|
||||
|
||||
Xil_AssertNonvoid(InstancePtr != NULL);
|
||||
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
|
||||
ConfigReg = XSpiPs_ReadReg(InstancePtr->Config.BaseAddress,
|
||||
XSPIPS_CR_OFFSET);
|
||||
|
||||
ConfigReg &= XSPIPS_CR_PRESC_MASK;
|
||||
|
||||
return (u8)(ConfigReg >> XSPIPS_CR_PRESC_SHIFT);
|
||||
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function sets the delay register for the SPI device driver.
|
||||
* The delay register controls the Delay Between Transfers, Delay After
|
||||
* Transfers, and the Delay Initially. The default value is 0x0. The range of
|
||||
* each delay value is 0-255.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XSpiPs instance.
|
||||
* @param DelayNss is the delay for which the chip select outputs will
|
||||
* be de-asserted between words when CPHA=0.
|
||||
* @param DelayBtwn is the delay between one Slave Select being
|
||||
* de-activated and the activation of another slave. The delay is
|
||||
* the number of master clock periods given by DelayBtwn + 2.
|
||||
* @param DelayAfter define the delay between the last bit of the current
|
||||
* byte transfer and the first bit of the next byte transfer.
|
||||
* The delay in number of master clock periods is given as:
|
||||
* CPHA=0:DelayInit+DelayAfter+3
|
||||
* CPHA=1:DelayAfter+1
|
||||
* @param DelayInit is the delay between asserting the slave select signal
|
||||
* and the first bit transfer. The delay int number of master clock
|
||||
* periods is DelayInit+1.
|
||||
*
|
||||
* @return
|
||||
* - XST_SUCCESS if delays are successfully set.
|
||||
* - XST_DEVICE_BUSY if the device is currently transferring data.
|
||||
* The transfer must complete or be aborted before setting options.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
int XSpiPs_SetDelays(XSpiPs *InstancePtr, u8 DelayNss, u8 DelayBtwn,
|
||||
u8 DelayAfter, u8 DelayInit)
|
||||
{
|
||||
u32 DelayRegister;
|
||||
|
||||
Xil_AssertNonvoid(InstancePtr != NULL);
|
||||
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
|
||||
/*
|
||||
* Do not allow the delays to change while a transfer is in
|
||||
* progress. Not thread-safe.
|
||||
*/
|
||||
if (InstancePtr->IsBusy) {
|
||||
return XST_DEVICE_BUSY;
|
||||
}
|
||||
|
||||
/* Shift, Mask and OR the values to build the register settings */
|
||||
DelayRegister = (u32) DelayNss << XSPIPS_DR_NSS_SHIFT;
|
||||
DelayRegister |= (u32) DelayBtwn << XSPIPS_DR_BTWN_SHIFT;
|
||||
DelayRegister |= (u32) DelayAfter << XSPIPS_DR_AFTER_SHIFT;
|
||||
DelayRegister |= (u32) DelayInit;
|
||||
|
||||
XSpiPs_WriteReg(InstancePtr->Config.BaseAddress,
|
||||
XSPIPS_DR_OFFSET, DelayRegister);
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function gets the delay settings for an SPI device.
|
||||
* The delay register controls the Delay Between Transfers, Delay After
|
||||
* Transfers, and the Delay Initially. The default value is 0x0.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XSpiPs instance.
|
||||
* @param DelayNss is a pointer to the delay for which the chip select
|
||||
* outputs will be de-asserted between words when CPHA=0.
|
||||
* @param DelayBtwn is a pointer to the Delay Between transfers value.
|
||||
* This is a return parameter.
|
||||
* @param DelayAfter is a pointer to the Delay After transfer value.
|
||||
* This is a return parameter.
|
||||
* @param DelayInit is a pointer to the Delay Initially value. This is
|
||||
* a return parameter.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
void XSpiPs_GetDelays(XSpiPs *InstancePtr,u8 *DelayNss, u8 *DelayBtwn,
|
||||
u8 *DelayAfter, u8 *DelayInit)
|
||||
{
|
||||
u32 DelayRegister;
|
||||
|
||||
Xil_AssertVoid(InstancePtr != NULL);
|
||||
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
|
||||
DelayRegister = XSpiPs_ReadReg(InstancePtr->Config.BaseAddress,
|
||||
XSPIPS_DR_OFFSET);
|
||||
|
||||
*DelayInit = (u8)(DelayRegister & XSPIPS_DR_INIT_MASK);
|
||||
|
||||
*DelayAfter = (u8)((DelayRegister & XSPIPS_DR_AFTER_MASK) >>
|
||||
XSPIPS_DR_AFTER_SHIFT);
|
||||
|
||||
*DelayBtwn = (u8)((DelayRegister & XSPIPS_DR_BTWN_MASK) >>
|
||||
XSPIPS_DR_BTWN_SHIFT);
|
||||
|
||||
*DelayNss = (u8)((DelayRegister & XSPIPS_DR_NSS_MASK) >>
|
||||
XSPIPS_DR_NSS_SHIFT);
|
||||
|
||||
}
|
155
XilinxProcessorIPLib/drivers/spips/src/xspips_selftest.c
Executable file
155
XilinxProcessorIPLib/drivers/spips/src/xspips_selftest.c
Executable file
|
@ -0,0 +1,155 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2010 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @file xspips_selftest.c
|
||||
*
|
||||
* This component contains the implementation of selftest functions for an SPI
|
||||
* device.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ------ -------- ----------------------------------------------
|
||||
* 1.00 drg/jz 01/25/10 First release
|
||||
* 1.04a sg 01/30/13 SetDelays test includes DelayTestNss parameter.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
#include "xspips.h"
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
|
||||
/************************** Variable Definitions *****************************/
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Runs a self-test on the driver/device. The self-test is destructive in that
|
||||
* a reset of the device is performed in order to check the reset values of
|
||||
* the registers and to get the device into a known state.
|
||||
*
|
||||
* Upon successful return from the self-test, the device is reset.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XSpiPs instance.
|
||||
*
|
||||
* @return
|
||||
* - XST_SUCCESS if successful
|
||||
* - XST_REGISTER_ERROR indicates a register did not read or write
|
||||
* correctly.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
int XSpiPs_SelfTest(XSpiPs *InstancePtr)
|
||||
{
|
||||
int Status;
|
||||
u32 Register;
|
||||
u8 DelayTestNss;
|
||||
u8 DelayTestBtwn;
|
||||
u8 DelayTestAfter;
|
||||
u8 DelayTestInit;
|
||||
|
||||
Xil_AssertNonvoid(InstancePtr != NULL);
|
||||
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
|
||||
/*
|
||||
* Reset the SPI device to leave it in a known good state
|
||||
*/
|
||||
XSpiPs_Reset(InstancePtr);
|
||||
|
||||
/*
|
||||
* All the SPI registers should be in their default state right now.
|
||||
*/
|
||||
Register = XSpiPs_ReadReg(InstancePtr->Config.BaseAddress,
|
||||
XSPIPS_CR_OFFSET);
|
||||
if (Register != XSPIPS_CR_RESET_STATE) {
|
||||
return XST_REGISTER_ERROR;
|
||||
}
|
||||
|
||||
Register = XSpiPs_ReadReg(InstancePtr->Config.BaseAddress,
|
||||
XSPIPS_SR_OFFSET);
|
||||
if (Register != XSPIPS_ISR_RESET_STATE) {
|
||||
return XST_REGISTER_ERROR;
|
||||
}
|
||||
|
||||
DelayTestNss = 0x5A;
|
||||
DelayTestBtwn = 0xA5;
|
||||
DelayTestAfter = 0xAA;
|
||||
DelayTestInit = 0x55;
|
||||
|
||||
/*
|
||||
* Write and read the delay register, just to be sure there is some
|
||||
* hardware out there.
|
||||
*/
|
||||
Status = XSpiPs_SetDelays(InstancePtr, DelayTestNss, DelayTestBtwn,
|
||||
DelayTestAfter, DelayTestInit);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
XSpiPs_GetDelays(InstancePtr, &DelayTestNss, &DelayTestBtwn,
|
||||
&DelayTestAfter, &DelayTestInit);
|
||||
if ((0x5A != DelayTestNss) || (0xA5 != DelayTestBtwn) ||
|
||||
(0xAA != DelayTestAfter) || (0x55 != DelayTestInit)) {
|
||||
return XST_REGISTER_ERROR;
|
||||
}
|
||||
|
||||
Status = XSpiPs_SetDelays(InstancePtr, 0, 0, 0, 0);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
/*
|
||||
* Reset the SPI device to leave it in a known good state
|
||||
*/
|
||||
XSpiPs_Reset(InstancePtr);
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
96
XilinxProcessorIPLib/drivers/spips/src/xspips_sinit.c
Executable file
96
XilinxProcessorIPLib/drivers/spips/src/xspips_sinit.c
Executable file
|
@ -0,0 +1,96 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2010 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @file xspips_sinit.c
|
||||
*
|
||||
* The implementation of the XSpiPs driver's static initialization
|
||||
* functionality.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ------ -------- -----------------------------------------------
|
||||
* 1.00 drg/jz 01/25/10 First release
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
#include "xstatus.h"
|
||||
#include "xspips.h"
|
||||
#include "xparameters.h"
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
/************************** Variable Definitions *****************************/
|
||||
extern XSpiPs_Config XSpiPs_ConfigTable[];
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Looks up the device configuration based on the unique device ID. A table
|
||||
* contains the configuration info for each device in the system.
|
||||
*
|
||||
* @param DeviceId contains the ID of the device to look up the
|
||||
* configuration for.
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* A pointer to the configuration found or NULL if the specified device ID was
|
||||
* not found. See xspips.h for the definition of XSpiPs_Config.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
XSpiPs_Config *XSpiPs_LookupConfig(u16 DeviceId)
|
||||
{
|
||||
XSpiPs_Config *CfgPtr = NULL;
|
||||
int Index;
|
||||
|
||||
for (Index = 0; Index < XPAR_XSPIPS_NUM_INSTANCES; Index++) {
|
||||
if (XSpiPs_ConfigTable[Index].DeviceId == DeviceId) {
|
||||
CfgPtr = &XSpiPs_ConfigTable[Index];
|
||||
break;
|
||||
}
|
||||
}
|
||||
return CfgPtr;
|
||||
}
|
Loading…
Add table
Reference in a new issue