iicps_v3_0: Added new version for iicps.
This patch add new version for iicps driver which supports both zynq and Alto. Signed-off-by: P L Sai Krishna <lakshmis@xilinx.com>
This commit is contained in:
parent
4b2b01d3e5
commit
3f029f1c87
27 changed files with 7158 additions and 1 deletions
42
XilinxProcessorIPLib/drivers/iicps/data/iicps.mdd
Executable file
42
XilinxProcessorIPLib/drivers/iicps/data/iicps.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 iicps
|
||||
|
||||
OPTION supported_peripherals = (ps7_i2c ps8_i2c pss_i2c);
|
||||
OPTION driver_state = ACTIVE;
|
||||
OPTION copyfiles = all;
|
||||
OPTION VERSION = 3.0;
|
||||
OPTION NAME = iicps;
|
||||
|
||||
END driver
|
52
XilinxProcessorIPLib/drivers/iicps/data/iicps.tcl
Executable file
52
XilinxProcessorIPLib/drivers/iicps/data/iicps.tcl
Executable file
|
@ -0,0 +1,52 @@
|
|||
###############################################################################
|
||||
#
|
||||
# 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
|
||||
# 2.0 adk 12/10/13 Updated as per the New Tcl API's
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
#uses "xillib.tcl"
|
||||
|
||||
proc generate {drv_handle} {
|
||||
xdefine_zynq_include_file $drv_handle "xparameters.h" "XIicPs" "NUM_INSTANCES" "DEVICE_ID" "C_S_AXI_BASEADDR" "C_S_AXI_HIGHADDR" "C_I2C_CLK_FREQ_HZ"
|
||||
|
||||
xdefine_zynq_config_file $drv_handle "xiicps_g.c" "XIicPs" "DEVICE_ID" "C_S_AXI_BASEADDR" "C_I2C_CLK_FREQ_HZ"
|
||||
|
||||
xdefine_zynq_canonical_xpars $drv_handle "xparameters.h" "XIicPs" "DEVICE_ID" "C_S_AXI_BASEADDR" "C_S_AXI_HIGHADDR" "C_I2C_CLK_FREQ_HZ"
|
||||
|
||||
}
|
41
XilinxProcessorIPLib/drivers/iicps/data/iicps_header.h
Normal file
41
XilinxProcessorIPLib/drivers/iicps/data/iicps_header.h
Normal file
|
@ -0,0 +1,41 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* 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 IICPS_HEADER_H /* prevent circular inclusions */
|
||||
#define IICPS_HEADER_H /* by using protection macros */
|
||||
|
||||
#include "xil_types.h"
|
||||
#include "xil_assert.h"
|
||||
#include "xstatus.h"
|
||||
|
||||
int IicPsSelfTestExample(u16 DeviceId);
|
||||
|
||||
#endif
|
138
XilinxProcessorIPLib/drivers/iicps/data/iicps_tapp.tcl
Executable file
138
XilinxProcessorIPLib/drivers/iicps/data/iicps_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 {xiicps.h iicps_header.h}
|
||||
}
|
||||
return $inc_file_lines
|
||||
}
|
||||
|
||||
proc gen_src_files {swproj mhsinst} {
|
||||
if {$swproj == 0} {
|
||||
return ""
|
||||
}
|
||||
if {$swproj == 1} {
|
||||
|
||||
set inc_file_lines {examples/xiicps_selftest_example.c data/iicps_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 [common::get_property NAME $mhsinst]
|
||||
set deviceid [::hsi::utils::get_ip_param_name $mhsinst "DEVICE_ID"]
|
||||
set stdout [common::get_property CONFIG.STDOUT [hsi::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 = IicPsSelfTestExample(${deviceid});
|
||||
|
||||
}"
|
||||
|
||||
|
||||
} else {
|
||||
|
||||
append testfunc_call "
|
||||
|
||||
{
|
||||
int Status;
|
||||
|
||||
print(\"\\r\\n Running IicPsSelfTestExample() for ${ipname}...\\r\\n\");
|
||||
|
||||
Status = IicPsSelfTestExample(${deviceid});
|
||||
|
||||
if (Status == 0) {
|
||||
print(\"IicPsSelfTestExample PASSED\\r\\n\");
|
||||
}
|
||||
else {
|
||||
print(\"IicPsSelfTestExample FAILED\\r\\n\");
|
||||
}
|
||||
}"
|
||||
|
||||
}
|
||||
|
||||
return $testfunc_call
|
||||
}
|
25
XilinxProcessorIPLib/drivers/iicps/examples/index.html
Executable file
25
XilinxProcessorIPLib/drivers/iicps/examples/index.html
Executable file
|
@ -0,0 +1,25 @@
|
|||
<!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 iicps_v2_4 </h1>
|
||||
<HR>
|
||||
<ul>
|
||||
<li>xiicps_eeprom_intr_example.c <a href="xiicps_eeprom_intr_example.c">(source)</a> </li>
|
||||
<li>xiicps_eeprom_polled_example.c <a href="xiicps_eeprom_polled_example.c">(source)</a> </li>
|
||||
<li>xiicps_intr_master_example.c <a href="xiicps_intr_master_example.c">(source)</a> </li>
|
||||
<li>xiicps_intr_slave_example.c <a href="xiicps_intr_slave_example.c">(source)</a> </li>
|
||||
<li>xiicps_polled_master_example.c <a href="xiicps_polled_master_example.c">(source)</a> </li>
|
||||
<li>xiicps_polled_slave_example.c <a href="xiicps_polled_slave_example.c">(source)</a> </li>
|
||||
<li>xiicps_selftest_example.c <a href="xiicps_selftest_example.c">(source)</a> </li>
|
||||
<li>xiicps_slave_monitor_example.c <a href="xiicps_slave_monitor_example.c">(source)</a> </li>
|
||||
<li>xiicps_slave_monitor_example.c <a href="xiicps_repeated_start_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>
|
|
@ -0,0 +1,597 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* 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 xiicps_eeprom_intr_example.c
|
||||
*
|
||||
* This file consists of a interrutp mode design example which uses the Xilinx
|
||||
* PS IIC device and XIicPs driver to exercise the EEPROM.
|
||||
*
|
||||
* The XIicPs_MasterSend() API is used to transmit the data and the
|
||||
* XIicPs_MasterRecv() API is used to receive the data.
|
||||
*
|
||||
* The example is tested with a 2Kb/8Kb serial IIC EEPROM (ST M24C02/M24C08).
|
||||
* The WP pin of this EEPROM is hardwired to ground on the HW in which this
|
||||
* was tested.
|
||||
*
|
||||
* The AddressType should be u8 as the address pointer in the on-board
|
||||
* EEPROM is 1 bytes.
|
||||
*
|
||||
* This code assumes that no Operating System is being used.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* None.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ---- -------- ---------------------------------------------------------
|
||||
* 1.00a sdm 03/15/10 First release
|
||||
* 1.01a sg 04/13/12 Added MuxInit function for initializing the IIC Mux
|
||||
* on the ZC702 board and to configure it for accessing
|
||||
* the IIC EEPROM.
|
||||
* Updated to use usleep instead of delay loop
|
||||
* 1.04a hk 09/03/13 Removed GPIO code to pull MUX out of reset - CR#722425.
|
||||
* 2.3 sk 10/07/14 Removed multiple initializations for read buffer.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
#include "xparameters.h"
|
||||
#include "sleep.h"
|
||||
#include "xiicps.h"
|
||||
#include "xscugic.h"
|
||||
#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 IIC_DEVICE_ID XPAR_XIICPS_0_DEVICE_ID
|
||||
#define INTC_DEVICE_ID XPAR_SCUGIC_SINGLE_DEVICE_ID
|
||||
#define IIC_INTR_ID XPAR_XIICPS_0_INTR
|
||||
|
||||
/*
|
||||
* The following constant defines the address of the IIC Slave device on the
|
||||
* IIC bus. Note that since the address is only 7 bits, this constant is the
|
||||
* address divided by 2.
|
||||
*/
|
||||
#define IIC_SLAVE_ADDR 0x54
|
||||
#define IIC_SCLK_RATE 100000
|
||||
#define IIC_MUX_ADDRESS 0x74
|
||||
/*
|
||||
* The page size determines how much data should be written at a time.
|
||||
* The write function should be called with this as a maximum byte count.
|
||||
*/
|
||||
#define PAGE_SIZE 16
|
||||
|
||||
/*
|
||||
* The Starting address in the IIC EEPROM on which this test is performed.
|
||||
*/
|
||||
#define EEPROM_START_ADDRESS 0
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
/*
|
||||
* The AddressType should be u8 as the address pointer in the on-board
|
||||
* EEPROM is 1 byte.
|
||||
*/
|
||||
typedef u8 AddressType;
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
int IicPsEepromIntrExample(void);
|
||||
int EepromWriteData(u16 ByteCount);
|
||||
int MuxInit(void);
|
||||
int EepromReadData(u8 *BufferPtr, u16 ByteCount);
|
||||
|
||||
static int SetupInterruptSystem(XIicPs * IicInstPtr);
|
||||
|
||||
static void Handler(void *CallBackRef, u32 Event);
|
||||
|
||||
/************************** Variable Definitions *****************************/
|
||||
|
||||
XIicPs IicInstance; /* The instance of the IIC device. */
|
||||
XScuGic InterruptController; /* The instance of the Interrupt Controller. */
|
||||
|
||||
/*
|
||||
* Write buffer for writing a page.
|
||||
*/
|
||||
u8 WriteBuffer[sizeof(AddressType) + PAGE_SIZE];
|
||||
|
||||
u8 ReadBuffer[PAGE_SIZE]; /* Read buffer for reading a page. */
|
||||
|
||||
volatile u8 TransmitComplete; /* Flag to check completion of Transmission */
|
||||
volatile u8 ReceiveComplete; /* Flag to check completion of Reception */
|
||||
volatile u32 TotalErrorCount;
|
||||
|
||||
/************************** Function Definitions *****************************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* Main function to call the Iic EEPROM interrupt example.
|
||||
*
|
||||
* @param None.
|
||||
*
|
||||
* @return XST_SUCCESS if successful else XST_FAILURE.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
int main(void)
|
||||
{
|
||||
int Status;
|
||||
|
||||
xil_printf("IIC EEPROM Interrupt Example Test \r\n");
|
||||
|
||||
/*
|
||||
* Run the Iic EEPROM interrupt mode example.
|
||||
*/
|
||||
Status = IicPsEepromIntrExample();
|
||||
if (Status != XST_SUCCESS) {
|
||||
xil_printf("IIC EEPROM Interrupt Example Test Failed\r\n");
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
xil_printf("Successfully ran IIC EEPROM Interrupt Example Test\r\n");
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* This function writes, reads, and verifies the data to the IIC EEPROM. It
|
||||
* does the write as a single page write, performs a buffered read.
|
||||
*
|
||||
* @param None.
|
||||
*
|
||||
* @return XST_SUCCESS if successful else XST_FAILURE.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
int IicPsEepromIntrExample(void)
|
||||
{
|
||||
u32 Index;
|
||||
int Status;
|
||||
XIicPs_Config *ConfigPtr; /* Pointer to configuration data */
|
||||
AddressType Address = EEPROM_START_ADDRESS;
|
||||
|
||||
/*
|
||||
* Initialize the IIC driver so that it is ready to use.
|
||||
*/
|
||||
ConfigPtr = XIicPs_LookupConfig(IIC_DEVICE_ID);
|
||||
if (ConfigPtr == NULL) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
Status = XIicPs_CfgInitialize(&IicInstance, ConfigPtr,
|
||||
ConfigPtr->BaseAddress);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup the Interrupt System.
|
||||
*/
|
||||
Status = SetupInterruptSystem(&IicInstance);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup the handlers for the IIC that will be called from the
|
||||
* interrupt context when data has been sent and received, specify a
|
||||
* pointer to the IIC driver instance as the callback reference so
|
||||
* the handlers are able to access the instance data.
|
||||
*/
|
||||
XIicPs_SetStatusHandler(&IicInstance, (void *) &IicInstance, Handler);
|
||||
|
||||
/*
|
||||
* Set the IIC serial clock rate.
|
||||
*/
|
||||
XIicPs_SetSClk(&IicInstance, IIC_SCLK_RATE);
|
||||
|
||||
/*
|
||||
* Set the channel value in IIC Mux.
|
||||
*/
|
||||
Status = MuxInit();
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize the data to write and the read buffer.
|
||||
*/
|
||||
if (sizeof(Address) == 1) {
|
||||
WriteBuffer[0] = (u8) (Address);
|
||||
} else {
|
||||
WriteBuffer[0] = (u8) (Address >> 8);
|
||||
WriteBuffer[1] = (u8) (Address);
|
||||
}
|
||||
|
||||
for (Index = 0; Index < PAGE_SIZE; Index++) {
|
||||
WriteBuffer[sizeof(Address) + Index] = 0xFF;
|
||||
ReadBuffer[Index] = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write to the EEPROM.
|
||||
*/
|
||||
Status = EepromWriteData(sizeof(Address) + PAGE_SIZE);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read from the EEPROM.
|
||||
*/
|
||||
Status = EepromReadData(ReadBuffer, PAGE_SIZE);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Verify the data read against the data written.
|
||||
*/
|
||||
for (Index = 0; Index < PAGE_SIZE; Index++) {
|
||||
if (ReadBuffer[Index] != WriteBuffer[Index + sizeof(Address)]) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize the data to write and the read buffer.
|
||||
*/
|
||||
if (sizeof(Address) == 1) {
|
||||
WriteBuffer[0] = (u8) (Address);
|
||||
} else {
|
||||
WriteBuffer[0] = (u8) (Address >> 8);
|
||||
WriteBuffer[1] = (u8) (Address);
|
||||
}
|
||||
|
||||
for (Index = 0; Index < PAGE_SIZE; Index++) {
|
||||
WriteBuffer[sizeof(Address) + Index] = Index + 10;
|
||||
ReadBuffer[Index] = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write to the EEPROM.
|
||||
*/
|
||||
Status = EepromWriteData(sizeof(Address) + PAGE_SIZE);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read from the EEPROM.
|
||||
*/
|
||||
Status = EepromReadData(ReadBuffer, PAGE_SIZE);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Verify the data read against the data written.
|
||||
*/
|
||||
for (Index = 0; Index < PAGE_SIZE; Index++) {
|
||||
if (ReadBuffer[Index] != WriteBuffer[Index + sizeof(Address)]) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* This function writes a buffer of data to the IIC serial EEPROM.
|
||||
*
|
||||
* @param ByteCount contains the number of bytes in the buffer to be
|
||||
* written.
|
||||
*
|
||||
* @return XST_SUCCESS if successful else XST_FAILURE.
|
||||
*
|
||||
* @note The Byte count should not exceed the page size of the EEPROM as
|
||||
* noted by the constant PAGE_SIZE.
|
||||
*
|
||||
******************************************************************************/
|
||||
int EepromWriteData(u16 ByteCount)
|
||||
{
|
||||
|
||||
TransmitComplete = FALSE;
|
||||
|
||||
/*
|
||||
* Send the Data.
|
||||
*/
|
||||
XIicPs_MasterSend(&IicInstance, WriteBuffer,
|
||||
ByteCount, IIC_SLAVE_ADDR);
|
||||
|
||||
/*
|
||||
* Wait for the entire buffer to be sent, letting the interrupt
|
||||
* processing work in the background, this function may get
|
||||
* locked up in this loop if the interrupts are not working
|
||||
* correctly.
|
||||
*/
|
||||
while (TransmitComplete == FALSE) {
|
||||
if (0 != TotalErrorCount) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Wait until bus is idle to start another transfer.
|
||||
*/
|
||||
while (XIicPs_BusIsBusy(&IicInstance));
|
||||
|
||||
/*
|
||||
* Wait for a bit of time to allow the programming to complete
|
||||
*/
|
||||
usleep(250000);
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* This function reads data from the IIC serial EEPROM into a specified buffer.
|
||||
*
|
||||
* @param BufferPtr contains the address of the data buffer to be filled.
|
||||
* @param ByteCount contains the number of bytes in the buffer to be read.
|
||||
*
|
||||
* @return XST_SUCCESS if successful else XST_FAILURE.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
int EepromReadData(u8 *BufferPtr, u16 ByteCount)
|
||||
{
|
||||
int Status;
|
||||
AddressType Address = EEPROM_START_ADDRESS;
|
||||
|
||||
/*
|
||||
* Position the Pointer in EEPROM.
|
||||
*/
|
||||
if (sizeof(Address) == 1) {
|
||||
WriteBuffer[0] = (u8) (Address);
|
||||
}
|
||||
else {
|
||||
WriteBuffer[0] = (u8) (Address >> 8);
|
||||
WriteBuffer[1] = (u8) (Address);
|
||||
}
|
||||
|
||||
Status = EepromWriteData(sizeof(Address));
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
ReceiveComplete = FALSE;
|
||||
|
||||
/*
|
||||
* Receive the Data.
|
||||
*/
|
||||
XIicPs_MasterRecv(&IicInstance, BufferPtr,
|
||||
ByteCount, IIC_SLAVE_ADDR);
|
||||
|
||||
while (ReceiveComplete == FALSE) {
|
||||
if (0 != TotalErrorCount) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Wait until bus is idle to start another transfer.
|
||||
*/
|
||||
while (XIicPs_BusIsBusy(&IicInstance));
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function setups the interrupt system such that interrupts can occur
|
||||
* for the IIC.
|
||||
*
|
||||
* @param IicPsPtr contains a pointer to the instance of the Iic
|
||||
* which is going to be connected to the interrupt controller.
|
||||
*
|
||||
* @return XST_SUCCESS if successful, otherwise XST_FAILURE.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
*******************************************************************************/
|
||||
static int SetupInterruptSystem(XIicPs *IicPsPtr)
|
||||
{
|
||||
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(&InterruptController, 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_IRQ_INT,
|
||||
(Xil_ExceptionHandler)XScuGic_InterruptHandler,
|
||||
&InterruptController);
|
||||
|
||||
/*
|
||||
* 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(&InterruptController, IIC_INTR_ID,
|
||||
(Xil_InterruptHandler)XIicPs_MasterInterruptHandler,
|
||||
(void *)IicPsPtr);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
/*
|
||||
* Enable the interrupt for the Iic device.
|
||||
*/
|
||||
XScuGic_Enable(&InterruptController, IIC_INTR_ID);
|
||||
|
||||
|
||||
/*
|
||||
* Enable interrupts in the Processor.
|
||||
*/
|
||||
Xil_ExceptionEnable();
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function is the handler which performs processing to handle data events
|
||||
* from the IIC. It is called from an interrupt context such that the amount
|
||||
* of processing performed should be minimized.
|
||||
*
|
||||
* This handler provides an example of how to handle data for the IIC and
|
||||
* is application specific.
|
||||
*
|
||||
* @param CallBackRef contains a callback reference from the driver, in
|
||||
* this case it is the instance pointer for the IIC driver.
|
||||
* @param Event contains the specific kind of event that has occurred.
|
||||
* @param EventData contains the number of bytes sent or received for sent
|
||||
* and receive events.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
*******************************************************************************/
|
||||
void Handler(void *CallBackRef, u32 Event)
|
||||
{
|
||||
/*
|
||||
* All of the data transfer has been finished.
|
||||
*/
|
||||
if (0 != (Event & XIICPS_EVENT_COMPLETE_RECV)){
|
||||
ReceiveComplete = TRUE;
|
||||
} else if (0 != (Event & XIICPS_EVENT_COMPLETE_SEND)) {
|
||||
TransmitComplete = TRUE;
|
||||
} else if (0 == (Event & XIICPS_EVENT_SLAVE_RDY)){
|
||||
/*
|
||||
* If it is other interrupt but not slave ready interrupt, it is
|
||||
* an error.
|
||||
* Data was received with an error.
|
||||
*/
|
||||
TotalErrorCount++;
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* This function initializes the IIC MUX to select EEPROM.
|
||||
*
|
||||
* @param None.
|
||||
*
|
||||
* @return XST_SUCCESS if pass, otherwise XST_FAILURE.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
****************************************************************************/
|
||||
int MuxInit(void)
|
||||
{
|
||||
u8 WriteBuffer;
|
||||
u8 MuxIicAddr = IIC_MUX_ADDRESS;
|
||||
u8 Buffer = 0;
|
||||
|
||||
/*
|
||||
* Channel select value for EEPROM.
|
||||
*/
|
||||
WriteBuffer = 0x04;
|
||||
|
||||
TransmitComplete = FALSE;
|
||||
|
||||
/*
|
||||
* Send the Data.
|
||||
*/
|
||||
XIicPs_MasterSend(&IicInstance, &WriteBuffer,1, MuxIicAddr);
|
||||
while (TransmitComplete == FALSE) {
|
||||
if (0 != TotalErrorCount) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Wait until bus is idle to start another transfer.
|
||||
*/
|
||||
while (XIicPs_BusIsBusy(&IicInstance));
|
||||
|
||||
ReceiveComplete = FALSE;
|
||||
|
||||
/*
|
||||
* Receive the Data.
|
||||
*/
|
||||
XIicPs_MasterRecv(&IicInstance, &Buffer,1, MuxIicAddr);
|
||||
while (ReceiveComplete == FALSE) {
|
||||
if (0 != TotalErrorCount) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Wait until bus is idle to start another transfer.
|
||||
*/
|
||||
while (XIicPs_BusIsBusy(&IicInstance));
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
|
@ -0,0 +1,436 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* 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 xiicps_eeprom_polled_example.c
|
||||
*
|
||||
* This file consists of a polled mode design example which uses the Xilinx PS
|
||||
* IIC device and XIicPs driver to exercise the EEPROM.
|
||||
*
|
||||
* The XIicPs_MasterSendPolled() API is used to transmit the data and
|
||||
* XIicPs_MasterRecvPolled() API is used to receive the data.
|
||||
*
|
||||
* The example is tested with a 2Kb/8Kb serial IIC EEPROM (ST M24C02/M24C08).
|
||||
* The WP pin of this EEPROM is hardwired to ground in the HW in which this
|
||||
* was tested.
|
||||
*
|
||||
* The AddressType should be u8 as the address pointer in the on-board
|
||||
* EEPROM is 1 bytes.
|
||||
*
|
||||
* This code assumes that no Operating System is being used.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* None.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ---- -------- ---------------------------------------------------------
|
||||
* 1.00a sdm 03/15/10 First release
|
||||
* 1.01a sg 04/13/12 Added MuxInit function for initializing the IIC Mux
|
||||
* on the ZC702 board and to configure it for accessing
|
||||
* the IIC EEPROM.
|
||||
* Updated to use usleep instead of delay loop
|
||||
* 1.04a hk 09/03/13 Removed GPIO code to pull MUX out of reset - CR#722425.
|
||||
* 2.3 sk 10/07/14 Removed multiple initializations for read buffer.
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
#include "xparameters.h"
|
||||
#include "sleep.h"
|
||||
#include "xiicps.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 IIC_DEVICE_ID XPAR_XIICPS_0_DEVICE_ID
|
||||
|
||||
/*
|
||||
* The following constant defines the address of the IIC Slave device on the
|
||||
* IIC bus. Note that since the address is only 7 bits, this constant is the
|
||||
* address divided by 2.
|
||||
*/
|
||||
#define IIC_SLAVE_ADDR 0x54
|
||||
#define IIC_SCLK_RATE 100000
|
||||
#define IIC_MUX_ADDRESS 0x74
|
||||
|
||||
/*
|
||||
* The page size determines how much data should be written at a time.
|
||||
* The write function should be called with this as a maximum byte count.
|
||||
*/
|
||||
#define PAGE_SIZE 16
|
||||
|
||||
/*
|
||||
* The Starting address in the IIC EEPROM on which this test is performed.
|
||||
*/
|
||||
#define EEPROM_START_ADDRESS 128
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
/*
|
||||
* The AddressType should be u8 as the address pointer in the on-board
|
||||
* EEPROM is 1 bytes.
|
||||
*/
|
||||
typedef u8 AddressType;
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
int IicPsEepromPolledExample(void);
|
||||
int EepromWriteData(u16 ByteCount);
|
||||
int MuxInit(void);
|
||||
int EepromReadData(u8 *BufferPtr, u16 ByteCount);
|
||||
|
||||
/************************** Variable Definitions *****************************/
|
||||
|
||||
XIicPs IicInstance; /* The instance of the IIC device. */
|
||||
|
||||
/*
|
||||
* Write buffer for writing a page.
|
||||
*/
|
||||
u8 WriteBuffer[sizeof(AddressType) + PAGE_SIZE];
|
||||
|
||||
u8 ReadBuffer[PAGE_SIZE]; /* Read buffer for reading a page. */
|
||||
|
||||
/************************** Function Definitions *****************************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* Main function to call the Iic EEPROM polled example.
|
||||
*
|
||||
* @param None.
|
||||
*
|
||||
* @return XST_SUCCESS if successful else XST_FAILURE.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
int main(void)
|
||||
{
|
||||
int Status;
|
||||
|
||||
xil_printf("IIC EEPROM Polled Mode Example Test \r\n");
|
||||
|
||||
/*
|
||||
* Run the Iic EEPROM Polled Mode example.
|
||||
*/
|
||||
Status = IicPsEepromPolledExample();
|
||||
if (Status != XST_SUCCESS) {
|
||||
xil_printf("IIC EEPROM Polled Mode Example Test Failed\r\n");
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
xil_printf("Successfully ran IIC EEPROM Polled Mode Example Test\r\n");
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* This function writes, reads, and verifies the data to the IIC EEPROM. It
|
||||
* does the write as a single page write, performs a buffered read.
|
||||
*
|
||||
* @param None.
|
||||
*
|
||||
* @return XST_SUCCESS if successful else XST_FAILURE.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
int IicPsEepromPolledExample(void)
|
||||
{
|
||||
u32 Index;
|
||||
int Status;
|
||||
XIicPs_Config *ConfigPtr; /* Pointer to configuration data */
|
||||
AddressType Address = EEPROM_START_ADDRESS;
|
||||
|
||||
/*
|
||||
* Initialize the IIC driver so that it is ready to use.
|
||||
*/
|
||||
ConfigPtr = XIicPs_LookupConfig(IIC_DEVICE_ID);
|
||||
if (ConfigPtr == NULL) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
Status = XIicPs_CfgInitialize(&IicInstance, ConfigPtr,
|
||||
ConfigPtr->BaseAddress);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the IIC serial clock rate.
|
||||
*/
|
||||
XIicPs_SetSClk(&IicInstance, IIC_SCLK_RATE);
|
||||
|
||||
/*
|
||||
* Set the channel value in IIC Mux.
|
||||
*/
|
||||
Status = MuxInit();
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize the data to write and the read buffer.
|
||||
*/
|
||||
if (sizeof(Address) == 1) {
|
||||
WriteBuffer[0] = (u8) (Address);
|
||||
} else {
|
||||
WriteBuffer[0] = (u8) (Address >> 8);
|
||||
WriteBuffer[1] = (u8) (Address);
|
||||
}
|
||||
|
||||
for (Index = 0; Index < PAGE_SIZE; Index++) {
|
||||
WriteBuffer[sizeof(Address) + Index] = 0xFF;
|
||||
ReadBuffer[Index] = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write to the EEPROM.
|
||||
*/
|
||||
Status = EepromWriteData(sizeof(Address) + PAGE_SIZE);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read from the EEPROM.
|
||||
*/
|
||||
Status = EepromReadData(ReadBuffer, PAGE_SIZE);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Verify the data read against the data written.
|
||||
*/
|
||||
for (Index = 0; Index < PAGE_SIZE; Index++) {
|
||||
if (ReadBuffer[Index] != WriteBuffer[Index + sizeof(Address)]) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize the data to write and the read buffer.
|
||||
*/
|
||||
if (sizeof(Address) == 1) {
|
||||
WriteBuffer[0] = (u8) (Address);
|
||||
} else {
|
||||
WriteBuffer[0] = (u8) (Address >> 8);
|
||||
WriteBuffer[1] = (u8) (Address);
|
||||
}
|
||||
|
||||
for (Index = 0; Index < PAGE_SIZE; Index++) {
|
||||
WriteBuffer[sizeof(Address) + Index] = Index + 10;
|
||||
ReadBuffer[Index] = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write to the EEPROM.
|
||||
*/
|
||||
Status = EepromWriteData(sizeof(Address) + PAGE_SIZE);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read from the EEPROM.
|
||||
*/
|
||||
Status = EepromReadData(ReadBuffer, PAGE_SIZE);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Verify the data read against the data written.
|
||||
*/
|
||||
for (Index = 0; Index < PAGE_SIZE; Index++) {
|
||||
if (ReadBuffer[Index] != WriteBuffer[Index + sizeof(Address)]) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* This function writes a buffer of data to the IIC serial EEPROM.
|
||||
*
|
||||
* @param ByteCount contains the number of bytes in the buffer to be
|
||||
* written.
|
||||
*
|
||||
* @return XST_SUCCESS if successful else XST_FAILURE.
|
||||
*
|
||||
* @note The Byte count should not exceed the page size of the EEPROM as
|
||||
* noted by the constant PAGE_SIZE.
|
||||
*
|
||||
******************************************************************************/
|
||||
int EepromWriteData(u16 ByteCount)
|
||||
{
|
||||
int Status;
|
||||
|
||||
/*
|
||||
* Send the Data.
|
||||
*/
|
||||
Status = XIicPs_MasterSendPolled(&IicInstance, WriteBuffer,
|
||||
ByteCount, IIC_SLAVE_ADDR);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Wait until bus is idle to start another transfer.
|
||||
*/
|
||||
while (XIicPs_BusIsBusy(&IicInstance));
|
||||
|
||||
/*
|
||||
* Wait for a bit of time to allow the programming to complete
|
||||
*/
|
||||
usleep(250000);
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* This function reads data from the IIC serial EEPROM into a specified buffer.
|
||||
*
|
||||
* @param BufferPtr contains the address of the data buffer to be filled.
|
||||
* @param ByteCount contains the number of bytes in the buffer to be read.
|
||||
*
|
||||
* @return XST_SUCCESS if successful else XST_FAILURE.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
int EepromReadData(u8 *BufferPtr, u16 ByteCount)
|
||||
{
|
||||
int Status;
|
||||
AddressType Address = EEPROM_START_ADDRESS;
|
||||
|
||||
/*
|
||||
* Position the Pointer in EEPROM.
|
||||
*/
|
||||
if (sizeof(Address) == 1) {
|
||||
WriteBuffer[0] = (u8) (Address);
|
||||
}
|
||||
else {
|
||||
WriteBuffer[0] = (u8) (Address >> 8);
|
||||
WriteBuffer[1] = (u8) (Address);
|
||||
}
|
||||
|
||||
Status = EepromWriteData(sizeof(Address));
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Receive the Data.
|
||||
*/
|
||||
Status = XIicPs_MasterRecvPolled(&IicInstance, BufferPtr,
|
||||
ByteCount, IIC_SLAVE_ADDR);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Wait until bus is idle to start another transfer.
|
||||
*/
|
||||
while (XIicPs_BusIsBusy(&IicInstance));
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* This function initializes the IIC MUX to select EEPROM.
|
||||
*
|
||||
* @param None.
|
||||
*
|
||||
* @return XST_SUCCESS if pass, otherwise XST_FAILURE.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
****************************************************************************/
|
||||
int MuxInit(void)
|
||||
{
|
||||
u8 WriteBuffer;
|
||||
u8 MuxIicAddr = IIC_MUX_ADDRESS;
|
||||
u8 Buffer = 0;
|
||||
int Status = 0;
|
||||
|
||||
/*
|
||||
* Channel select value for EEPROM.
|
||||
*/
|
||||
WriteBuffer = 0x04;
|
||||
|
||||
/*
|
||||
* Send the Data.
|
||||
*/
|
||||
Status = XIicPs_MasterSendPolled(&IicInstance, &WriteBuffer,1,
|
||||
MuxIicAddr);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Wait until bus is idle to start another transfer.
|
||||
*/
|
||||
while (XIicPs_BusIsBusy(&IicInstance));
|
||||
|
||||
/*
|
||||
* Receive the Data.
|
||||
*/
|
||||
Status = XIicPs_MasterRecvPolled(&IicInstance, &Buffer,1, MuxIicAddr);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Wait until bus is idle to start another transfer.
|
||||
*/
|
||||
while (XIicPs_BusIsBusy(&IicInstance));
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
|
@ -0,0 +1,403 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* 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 xiicps_intr_master_example.c
|
||||
*
|
||||
* Design example to use the IIC device as master in interrupt-driven mode.
|
||||
*
|
||||
* It continuously sends 18 buffers to slave.
|
||||
*
|
||||
* <pre> MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- --- -------- -----------------------------------------------
|
||||
* 1.00a jz 01/30/10 First release
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/***************************** Include Files **********************************/
|
||||
#include "xparameters.h"
|
||||
#include "xiicps.h"
|
||||
#include "xscugic.h"
|
||||
#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 IIC_DEVICE_ID XPAR_XIICPS_0_DEVICE_ID
|
||||
#define INTC_DEVICE_ID XPAR_SCUGIC_SINGLE_DEVICE_ID
|
||||
#define IIC_INT_VEC_ID XPAR_XIICPS_0_INTR
|
||||
|
||||
/*
|
||||
* The slave address to send to and receive from.
|
||||
*/
|
||||
#define IIC_SLAVE_ADDR 0x55
|
||||
#define IIC_SCLK_RATE 100000
|
||||
|
||||
|
||||
/*
|
||||
* The following constant controls the length of the buffers to be sent
|
||||
* and received with the IIC.
|
||||
*/
|
||||
#define TEST_BUFFER_SIZE 250
|
||||
#define NUMBER_OF_SIZES 18
|
||||
|
||||
/**************************** Type Definitions ********************************/
|
||||
|
||||
/************************** Function Prototypes *******************************/
|
||||
|
||||
int IicPsMasterIntrExample(u16 DeviceId);
|
||||
static int SetupInterruptSystem(XIicPs *IicPsPtr);
|
||||
|
||||
void Handler(void *CallBackRef, u32 Event);
|
||||
|
||||
/************************** Variable Definitions ******************************/
|
||||
|
||||
XIicPs Iic; /* Instance of the IIC Device */
|
||||
XScuGic InterruptController; /* Instance of the Interrupt Controller */
|
||||
|
||||
/*
|
||||
* The following buffers are used in this example to send and receive data
|
||||
* with the IIC. They are defined as global so that they are not on the stack.
|
||||
*/
|
||||
u8 SendBuffer[TEST_BUFFER_SIZE]; /* Buffer for Transmitting Data */
|
||||
u8 RecvBuffer[TEST_BUFFER_SIZE]; /* Buffer for Receiving Data */
|
||||
|
||||
/*
|
||||
* The following counters are used to determine when the entire buffer has
|
||||
* been sent and received.
|
||||
*/
|
||||
volatile u32 SendComplete;
|
||||
volatile u32 RecvComplete;
|
||||
volatile u32 TotalErrorCount;
|
||||
|
||||
/******************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Main function to call the example.
|
||||
*
|
||||
* @param None.
|
||||
*
|
||||
* @return XST_SUCCESS if successful, XST_FAILURE if unsuccessful.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
*******************************************************************************/
|
||||
int main(void)
|
||||
{
|
||||
int Status;
|
||||
|
||||
xil_printf("IIC Master Interrupt Example Test \r\n");
|
||||
|
||||
/*
|
||||
* Run the Iic Master Interrupt example , specify the Device ID that is
|
||||
* generated in xparameters.h
|
||||
*/
|
||||
Status = IicPsMasterIntrExample(IIC_DEVICE_ID);
|
||||
if (Status != XST_SUCCESS) {
|
||||
xil_printf("IIC Master Interrupt Example Test Failed\r\n");
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
xil_printf("Successfully ran IIC Master Interrupt Example Test\r\n");
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function does a minimal test on the Iic device and driver as a
|
||||
* design example. The purpose of this function is to illustrate
|
||||
* how to use the XIicPs driver.
|
||||
*
|
||||
* This function sends data and expects to receive the same data through the IIC
|
||||
* using the Aardvark test hardware.
|
||||
*
|
||||
* This function uses interrupt driver mode of the IIC.
|
||||
*
|
||||
* @param DeviceId is the Device ID of the IicPs Device and is the
|
||||
* XPAR_<IICPS_instance>_DEVICE_ID value from xparameters.h
|
||||
*
|
||||
* @return XST_SUCCESS if successful, otherwise XST_FAILURE.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* This function contains an infinite loop such that if interrupts are not
|
||||
* working it may never return.
|
||||
*
|
||||
*******************************************************************************/
|
||||
int IicPsMasterIntrExample(u16 DeviceId)
|
||||
{
|
||||
int Status;
|
||||
XIicPs_Config *Config;
|
||||
int Index;
|
||||
int tmp;
|
||||
int BufferSizes[NUMBER_OF_SIZES] = {1, 2, 19, 31, 32, 33, 62, 63, 64,
|
||||
65, 66, 94, 95, 96, 97, 98, 99, 250};
|
||||
|
||||
/*
|
||||
* Initialize the IIC driver so that it's ready to use
|
||||
* Look up the configuration in the config table, then initialize it.
|
||||
*/
|
||||
Config = XIicPs_LookupConfig(DeviceId);
|
||||
if (NULL == Config) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
Status = XIicPs_CfgInitialize(&Iic, Config, Config->BaseAddress);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Perform a self-test to ensure that the hardware was built correctly.
|
||||
*/
|
||||
Status = XIicPs_SelfTest(&Iic);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Connect the IIC to the interrupt subsystem such that interrupts can
|
||||
* occur. This function is application specific.
|
||||
*/
|
||||
Status = SetupInterruptSystem(&Iic);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup the handlers for the IIC that will be called from the
|
||||
* interrupt context when data has been sent and received, specify a
|
||||
* pointer to the IIC driver instance as the callback reference so
|
||||
* the handlers are able to access the instance data.
|
||||
*/
|
||||
XIicPs_SetStatusHandler(&Iic, (void *) &Iic, Handler);
|
||||
|
||||
/*
|
||||
* Set the IIC serial clock rate.
|
||||
*/
|
||||
XIicPs_SetSClk(&Iic, IIC_SCLK_RATE);
|
||||
|
||||
/*
|
||||
* Initialize the send buffer bytes with a pattern to send and the
|
||||
* the receive buffer bytes to zero to allow the receive data to be
|
||||
* verified.
|
||||
*/
|
||||
for (Index = 0; Index < TEST_BUFFER_SIZE; Index++) {
|
||||
SendBuffer[Index] = (Index % TEST_BUFFER_SIZE);
|
||||
RecvBuffer[Index] = 0;
|
||||
}
|
||||
|
||||
for(Index = 0; Index < NUMBER_OF_SIZES; Index++) {
|
||||
|
||||
/* Wait for bus to become idle
|
||||
*/
|
||||
while (XIicPs_BusIsBusy(&Iic)) {
|
||||
/* NOP */
|
||||
}
|
||||
|
||||
SendComplete = FALSE;
|
||||
|
||||
/*
|
||||
* Send the buffer, errors are reported by TotalErrorCount.
|
||||
*/
|
||||
XIicPs_MasterSend(&Iic, SendBuffer, BufferSizes[Index],
|
||||
IIC_SLAVE_ADDR);
|
||||
|
||||
/*
|
||||
* Wait for the entire buffer to be sent, letting the interrupt
|
||||
* processing work in the background, this function may get
|
||||
* locked up in this loop if the interrupts are not working
|
||||
* correctly.
|
||||
*/
|
||||
while (!SendComplete) {
|
||||
if (0 != TotalErrorCount) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Wait bus activities to finish.
|
||||
*/
|
||||
while (XIicPs_BusIsBusy(&Iic)) {
|
||||
/* NOP */
|
||||
}
|
||||
|
||||
/*
|
||||
* Receive data from slave, errors are reported through
|
||||
* TotalErrorCount.
|
||||
*/
|
||||
RecvComplete = FALSE;
|
||||
XIicPs_MasterRecv(&Iic, RecvBuffer, BufferSizes[Index],
|
||||
IIC_SLAVE_ADDR);
|
||||
|
||||
while (!RecvComplete) {
|
||||
if (0 != TotalErrorCount) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check for received data.
|
||||
*/
|
||||
for(tmp = 0; tmp < BufferSizes[Index]; tmp ++) {
|
||||
|
||||
/*
|
||||
* Aardvark as slave can only set up to 64 bytes for
|
||||
* output.
|
||||
*/
|
||||
if (RecvBuffer[tmp] != tmp % 64) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
}
|
||||
}
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function is the handler which performs processing to handle data events
|
||||
* from the IIC. It is called from an interrupt context such that the amount
|
||||
* of processing performed should be minimized.
|
||||
*
|
||||
* This handler provides an example of how to handle data for the IIC and
|
||||
* is application specific.
|
||||
*
|
||||
* @param CallBackRef contains a callback reference from the driver, in
|
||||
* this case it is the instance pointer for the IIC driver.
|
||||
* @param Event contains the specific kind of event that has occurred.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
*******************************************************************************/
|
||||
void Handler(void *CallBackRef, u32 Event)
|
||||
{
|
||||
/*
|
||||
* All of the data transfer has been finished.
|
||||
*/
|
||||
if (0 != (Event & XIICPS_EVENT_COMPLETE_RECV)){
|
||||
RecvComplete = TRUE;
|
||||
} else if (0 != (Event & XIICPS_EVENT_COMPLETE_SEND)) {
|
||||
SendComplete = TRUE;
|
||||
} else if (0 == (Event & XIICPS_EVENT_SLAVE_RDY)){
|
||||
/*
|
||||
* If it is other interrupt but not slave ready interrupt, it is
|
||||
* an error.
|
||||
* Data was received with an error.
|
||||
*/
|
||||
TotalErrorCount++;
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function setups the interrupt system such that interrupts can occur
|
||||
* for the IIC. This function is application specific since the actual
|
||||
* system may or may not have an interrupt controller. The IIC could be
|
||||
* directly connected to a processor without an interrupt controller. The
|
||||
* user should modify this function to fit the application.
|
||||
*
|
||||
* @param IicPsPtr contains a pointer to the instance of the Iic
|
||||
* which is going to be connected to the interrupt controller.
|
||||
*
|
||||
* @return XST_SUCCESS if successful, otherwise XST_FAILURE.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
*******************************************************************************/
|
||||
static int SetupInterruptSystem(XIicPs *IicPsPtr)
|
||||
{
|
||||
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(&InterruptController, 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_IRQ_INT,
|
||||
(Xil_ExceptionHandler)XScuGic_InterruptHandler,
|
||||
&InterruptController);
|
||||
|
||||
/*
|
||||
* 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(&InterruptController, IIC_INT_VEC_ID,
|
||||
(Xil_InterruptHandler)XIicPs_MasterInterruptHandler,
|
||||
(void *)IicPsPtr);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
/*
|
||||
* Enable the interrupt for the Iic device.
|
||||
*/
|
||||
XScuGic_Enable(&InterruptController, IIC_INT_VEC_ID);
|
||||
|
||||
|
||||
/*
|
||||
* Enable interrupts in the Processor.
|
||||
*/
|
||||
Xil_ExceptionEnable();
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
|
@ -0,0 +1,397 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* 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 xiicps_intr_slave_example.c
|
||||
*
|
||||
* A design example of using the IIC device as slave for interrupt-driven
|
||||
* transfers using the external Aardvark IIC analyzer as the master.
|
||||
*
|
||||
* This example uses buffer size of 250. Set the send buffer of the
|
||||
* Aardvark device as continuous data from 0x00 to 0xF9.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
* <pre> MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- --- -------- -----------------------------------------------
|
||||
* 1.00a jz 01/30/10 First release
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/***************************** Include Files **********************************/
|
||||
#include "xparameters.h"
|
||||
#include "xiicps.h"
|
||||
#include "xscugic.h"
|
||||
#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 IIC_DEVICE_ID XPAR_XIICPS_0_DEVICE_ID
|
||||
#define INTC_DEVICE_ID XPAR_SCUGIC_SINGLE_DEVICE_ID
|
||||
#define IIC_INT_VEC_ID XPAR_XIICPS_0_INTR
|
||||
|
||||
/*
|
||||
* The slave address to send to and receive from.
|
||||
*/
|
||||
#define IIC_SLAVE_ADDR 0x45
|
||||
#define IIC_SCLK_RATE 400000
|
||||
|
||||
/*
|
||||
* The following constant controls the length of the buffers to be sent
|
||||
* and received with the IIC.
|
||||
*/
|
||||
#define TEST_BUFFER_SIZE 250
|
||||
|
||||
/**************************** Type Definitions ********************************/
|
||||
|
||||
|
||||
/************************** Function Prototypes *******************************/
|
||||
|
||||
int IicPsSlaveIntrExample(u16 DeviceId);
|
||||
static int SetupInterruptSystem(XIicPs *IicPsPtr);
|
||||
|
||||
void Handler(void *CallBackRef, u32 Event);
|
||||
|
||||
/************************** Variable Definitions ******************************/
|
||||
|
||||
XIicPs Iic; /* Instance of the IIC Device */
|
||||
XScuGic InterruptController; /* Instance of the Interrupt Controller */
|
||||
|
||||
/*
|
||||
* The following buffers are used in this example to send and receive data
|
||||
* with the IIC. The buffers are defined as global so that they are not on the
|
||||
* stack.
|
||||
*/
|
||||
u8 SendBuffer[TEST_BUFFER_SIZE]; /* Buffer for Transmitting Data */
|
||||
u8 RecvBuffer[TEST_BUFFER_SIZE]; /* Buffer for Receiving Data */
|
||||
|
||||
/*
|
||||
* The following counters are used to determine when the entire buffer has
|
||||
* been sent and received.
|
||||
*/
|
||||
volatile u32 SendComplete;
|
||||
volatile u32 RecvComplete;
|
||||
volatile u32 TotalErrorCount;
|
||||
|
||||
/******************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Main function to call the interrupt example in the slave mode.
|
||||
*
|
||||
* @param None
|
||||
*
|
||||
* @return
|
||||
* - XST_SUCCESS if successful.
|
||||
* - XST_FAILURE if unsuccessful.
|
||||
*
|
||||
* @note None
|
||||
*
|
||||
*******************************************************************************/
|
||||
int main(void)
|
||||
{
|
||||
int Status;
|
||||
|
||||
xil_printf("IIC Slave Interrupt Example Test \r\n");
|
||||
|
||||
/*
|
||||
* Run the Iic Slave Interrupt example , specify the Device ID that is
|
||||
* generated in xparameters.h.
|
||||
*/
|
||||
Status = IicPsSlaveIntrExample(IIC_DEVICE_ID);
|
||||
if (Status != XST_SUCCESS) {
|
||||
xil_printf("IIC Slave Interrupt Example Test Failed\r\n");
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
xil_printf("Successfully ran IIC Slave Interrupt Example Test\r\n");
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function does a minimal test on the Iic device and driver as a
|
||||
* design example. The purpose of this function is to illustrate
|
||||
* how to use the XIicPs component.
|
||||
*
|
||||
* This function sends data and expects to receive the same data through the IIC
|
||||
* using the Aardvark test hardware.
|
||||
*
|
||||
* This function uses interrupt driver mode of the IIC.
|
||||
*
|
||||
* @param DeviceId is the Device ID of the IicPs Device and is the
|
||||
* XPAR_<IICPS_instance>_DEVICE_ID value from xparameters.h
|
||||
*
|
||||
* @return XST_SUCCESS if successful, otherwise XST_FAILURE.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* This function contains an infinite loop such that if interrupts are not
|
||||
* working it may never return.
|
||||
*
|
||||
*******************************************************************************/
|
||||
int IicPsSlaveIntrExample(u16 DeviceId)
|
||||
{
|
||||
int Status;
|
||||
XIicPs_Config *Config;
|
||||
int Index;
|
||||
|
||||
/*
|
||||
* Initialize the IIC driver so that it's ready to use
|
||||
* Look up the configuration in the config table,
|
||||
* then initialize it.
|
||||
*/
|
||||
Config = XIicPs_LookupConfig(DeviceId);
|
||||
if (NULL == Config) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
Status = XIicPs_CfgInitialize(&Iic, Config, Config->BaseAddress);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Perform a self-test to ensure that the hardware was built correctly.
|
||||
*/
|
||||
Status = XIicPs_SelfTest(&Iic);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Connect the IIC to the interrupt subsystem such that interrupts can
|
||||
* occur. This function is application specific.
|
||||
*/
|
||||
Status = SetupInterruptSystem(&Iic);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup the handlers for the IIC that will be called from the
|
||||
* interrupt context when data has been sent and received, specify a
|
||||
* pointer to the IIC driver instance as the callback reference so
|
||||
* the handlers are able to access the instance data.
|
||||
*/
|
||||
XIicPs_SetStatusHandler(&Iic, (void *) &Iic, Handler);
|
||||
XIicPs_SetupSlave(&Iic, IIC_SLAVE_ADDR);
|
||||
|
||||
/*
|
||||
* Set the IIC serial clock rate.
|
||||
*/
|
||||
XIicPs_SetSClk(&Iic, IIC_SCLK_RATE);
|
||||
|
||||
/*
|
||||
* Initialize the send buffer bytes with a pattern to send and the
|
||||
* the receive buffer bytes to zero to allow the receive data to be
|
||||
* verified.
|
||||
*/
|
||||
for (Index = 0; Index < TEST_BUFFER_SIZE; Index++) {
|
||||
SendBuffer[Index] = (Index % TEST_BUFFER_SIZE);
|
||||
RecvBuffer[Index] = 0;
|
||||
}
|
||||
|
||||
TotalErrorCount = 0;
|
||||
SendComplete = FALSE;
|
||||
|
||||
/*
|
||||
* Send the buffer using the IIC and ignore the number of bytes sent.
|
||||
* In case of error, the interrupt handler will inform us through event
|
||||
* flag.
|
||||
*/
|
||||
XIicPs_SlaveSend(&Iic, SendBuffer, TEST_BUFFER_SIZE);
|
||||
|
||||
/*
|
||||
* Wait for the entire buffer to be sent, let the interrupt
|
||||
* processing work in the background, this function may get locked
|
||||
* up in this loop if the interrupts are not working correctly.
|
||||
*/
|
||||
while (!SendComplete) {
|
||||
if (0 != TotalErrorCount) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Wait until the bus transfer finishes.
|
||||
*/
|
||||
while (XIicPs_BusIsBusy(&Iic)) {
|
||||
/* NOP */
|
||||
}
|
||||
|
||||
/*
|
||||
* Receive data from master.
|
||||
* Receive errors will be singalled through event flag.
|
||||
*/
|
||||
RecvComplete = FALSE;
|
||||
XIicPs_SlaveRecv(&Iic, RecvBuffer, TEST_BUFFER_SIZE);
|
||||
|
||||
while (!RecvComplete) {
|
||||
if (0 != TotalErrorCount) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Verify received data.
|
||||
*/
|
||||
for(Index = 0; Index < TEST_BUFFER_SIZE; Index ++) {
|
||||
if (RecvBuffer[Index] != Index) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
}
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function is the handler which performs processing to handle data events
|
||||
* from the IIC. It is called from an interrupt context such that the amount
|
||||
* of processing performed should be minimized.
|
||||
*
|
||||
* This handler provides an example of how to handle data for the IIC and
|
||||
* is application specific.
|
||||
*
|
||||
* @param CallBackRef contains a callback reference from the driver,
|
||||
* in this case it is the instance pointer for the IIC driver.
|
||||
* @param Event contains the specific kind of event that has occurred.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
*******************************************************************************/
|
||||
void Handler(void *CallBackRef, u32 Event)
|
||||
{
|
||||
/*
|
||||
* Data transfer finishes.
|
||||
*/
|
||||
if (0 != (Event & XIICPS_EVENT_COMPLETE_RECV)){
|
||||
RecvComplete = TRUE;
|
||||
}
|
||||
else if (0 != (Event & XIICPS_EVENT_COMPLETE_SEND)) {
|
||||
SendComplete = TRUE;
|
||||
} else {
|
||||
|
||||
/*
|
||||
* Data was received with an error.
|
||||
*/
|
||||
TotalErrorCount++;
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function setups the interrupt system such that interrupts can occur
|
||||
* for the IIC. This function is application specific since the actual
|
||||
* system may or may not have an interrupt controller. The IIC could be
|
||||
* directly connected to a processor without an interrupt controller. The
|
||||
* user should modify this function to fit the application.
|
||||
*
|
||||
* @param IicPsPtr contains a pointer to the instance of the Iic
|
||||
* component which is going to be connected to the interrupt
|
||||
* controller.
|
||||
*
|
||||
* @return XST_SUCCESS if successful, otherwise XST_FAILURE.
|
||||
*
|
||||
* @note None
|
||||
*
|
||||
*******************************************************************************/
|
||||
static int SetupInterruptSystem(XIicPs *IicPsPtr)
|
||||
{
|
||||
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(&InterruptController, 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_IRQ_INT,
|
||||
(Xil_ExceptionHandler)XScuGic_InterruptHandler,
|
||||
&InterruptController);
|
||||
|
||||
/*
|
||||
* 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(&InterruptController, IIC_INT_VEC_ID,
|
||||
(Xil_InterruptHandler)XIicPs_SlaveInterruptHandler,
|
||||
(void *)IicPsPtr);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
/*
|
||||
* Enable the interrupt for the Iic device.
|
||||
*/
|
||||
XScuGic_Enable(&InterruptController, IIC_INT_VEC_ID);
|
||||
|
||||
|
||||
/*
|
||||
* Enable interrupts in the Processor.
|
||||
*/
|
||||
Xil_ExceptionEnable();
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
|
@ -0,0 +1,222 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* 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 xiicps_polled_master_example.c
|
||||
*
|
||||
* A design example of using the device in polled mode as master.
|
||||
*
|
||||
* The example uses buffer size 132. Please set the send buffer of the
|
||||
* Aardvark device to be continuous 64 bytes from 0x00 to 0x3F.
|
||||
*
|
||||
* <pre> MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- --- -------- -----------------------------------------------
|
||||
* 1.00a jz 01/30/10 First release
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/***************************** Include Files **********************************/
|
||||
#include "xparameters.h"
|
||||
#include "xiicps.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 IIC_DEVICE_ID XPAR_XIICPS_0_DEVICE_ID
|
||||
|
||||
/*
|
||||
* The slave address to send to and receive from.
|
||||
*/
|
||||
#define IIC_SLAVE_ADDR 0x55
|
||||
#define IIC_SCLK_RATE 100000
|
||||
|
||||
/*
|
||||
* The following constant controls the length of the buffers to be sent
|
||||
* and received with the IIC.
|
||||
*/
|
||||
#define TEST_BUFFER_SIZE 132
|
||||
|
||||
/**************************** Type Definitions ********************************/
|
||||
|
||||
|
||||
/************************** Function Prototypes *******************************/
|
||||
|
||||
int IicPsMasterPolledExample(u16 DeviceId);
|
||||
/************************** Variable Definitions ******************************/
|
||||
|
||||
XIicPs Iic; /**< Instance of the IIC Device */
|
||||
|
||||
/*
|
||||
* The following buffers are used in this example to send and receive data
|
||||
* with the IIC.
|
||||
*/
|
||||
u8 SendBuffer[TEST_BUFFER_SIZE]; /**< Buffer for Transmitting Data */
|
||||
u8 RecvBuffer[TEST_BUFFER_SIZE]; /**< Buffer for Receiving Data */
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Main function to call the polled master example.
|
||||
*
|
||||
* @param None.
|
||||
*
|
||||
* @return XST_SUCCESS if successful, XST_FAILURE if unsuccessful.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
*******************************************************************************/
|
||||
int main(void)
|
||||
{
|
||||
int Status;
|
||||
|
||||
xil_printf("IIC Master Polled Example Test \r\n");
|
||||
|
||||
/*
|
||||
* Run the Iic polled example in master mode, specify the Device
|
||||
* ID that is specified in xparameters.h.
|
||||
*/
|
||||
Status = IicPsMasterPolledExample(IIC_DEVICE_ID);
|
||||
if (Status != XST_SUCCESS) {
|
||||
xil_printf("IIC Master Polled Example Test Failed\r\n");
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
xil_printf("Successfully ran IIC Master Polled Example Test\r\n");
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function sends data and expects to receive data from slave as modular
|
||||
* of 64.
|
||||
*
|
||||
* This function uses interrupt-driven mode of the device.
|
||||
*
|
||||
* @param DeviceId is the Device ID of the IicPs Device and is the
|
||||
* XPAR_<IICPS_instance>_DEVICE_ID value from xparameters.h
|
||||
*
|
||||
* @return XST_SUCCESS if successful, otherwise XST_FAILURE.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
*******************************************************************************/
|
||||
int IicPsMasterPolledExample(u16 DeviceId)
|
||||
{
|
||||
int Status;
|
||||
XIicPs_Config *Config;
|
||||
int Index;
|
||||
|
||||
/*
|
||||
* Initialize the IIC driver so that it's ready to use
|
||||
* Look up the configuration in the config table,
|
||||
* then initialize it.
|
||||
*/
|
||||
Config = XIicPs_LookupConfig(DeviceId);
|
||||
if (NULL == Config) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
Status = XIicPs_CfgInitialize(&Iic, Config, Config->BaseAddress);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Perform a self-test to ensure that the hardware was built correctly.
|
||||
*/
|
||||
Status = XIicPs_SelfTest(&Iic);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the IIC serial clock rate.
|
||||
*/
|
||||
XIicPs_SetSClk(&Iic, IIC_SCLK_RATE);
|
||||
|
||||
/*
|
||||
* Initialize the send buffer bytes with a pattern to send and the
|
||||
* the receive buffer bytes to zero to allow the receive data to be
|
||||
* verified.
|
||||
*/
|
||||
for (Index = 0; Index < TEST_BUFFER_SIZE; Index++) {
|
||||
SendBuffer[Index] = (Index % TEST_BUFFER_SIZE);
|
||||
RecvBuffer[Index] = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Send the buffer using the IIC and ignore the number of bytes sent
|
||||
* as the return value since we are using it in interrupt mode.
|
||||
*/
|
||||
Status = XIicPs_MasterSendPolled(&Iic, SendBuffer,
|
||||
TEST_BUFFER_SIZE, IIC_SLAVE_ADDR);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Wait until bus is idle to start another transfer.
|
||||
*/
|
||||
while (XIicPs_BusIsBusy(&Iic)) {
|
||||
/* NOP */
|
||||
}
|
||||
|
||||
Status = XIicPs_MasterRecvPolled(&Iic, RecvBuffer,
|
||||
TEST_BUFFER_SIZE, IIC_SLAVE_ADDR);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Verify received data is correct.
|
||||
*/
|
||||
for(Index = 0; Index < TEST_BUFFER_SIZE; Index ++) {
|
||||
|
||||
/* Aardvark as slave can only set 64 bytes for output */
|
||||
if (RecvBuffer[Index] != Index % 64) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
|
@ -0,0 +1,215 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* 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 xiicps_polled_slave_example.c
|
||||
*
|
||||
* A design example of using the device as slave in polled mode.
|
||||
*
|
||||
* This example uses buffer of size 250. Please set the send buffer of the
|
||||
* Aardvark device to be continuous data from 0x00 to 0xF9.
|
||||
*
|
||||
* <pre> MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- --- -------- -----------------------------------------------
|
||||
* 1.00a jz 01/30/10 First release
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/***************************** Include Files **********************************/
|
||||
#include "xparameters.h"
|
||||
#include "xiicps.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 IIC_DEVICE_ID XPAR_XIICPS_0_DEVICE_ID
|
||||
|
||||
/* The slave address to send to and receive from.
|
||||
*/
|
||||
#define IIC_SLAVE_ADDR 0x45
|
||||
#define IIC_SCLK_RATE 400000
|
||||
|
||||
/*
|
||||
* The following constant controls the length of the buffers to be sent
|
||||
* and received with the IIC
|
||||
*/
|
||||
#define TEST_BUFFER_SIZE 250
|
||||
|
||||
/**************************** Type Definitions ********************************/
|
||||
|
||||
/************************** Function Prototypes *******************************/
|
||||
|
||||
int IicPsSlavePolledExample(u16 DeviceId);
|
||||
/************************** Variable Definitions ******************************/
|
||||
|
||||
XIicPs Iic; /* Instance of the IIC Device */
|
||||
|
||||
/*
|
||||
* The following buffers are used in this example to send and receive data
|
||||
* with the IIC. These buffers are defined as global so that they are not
|
||||
* defined on the stack.
|
||||
*/
|
||||
u8 SendBuffer[TEST_BUFFER_SIZE]; /* Buffer for Transmitting Data */
|
||||
u8 RecvBuffer[TEST_BUFFER_SIZE]; /* Buffer for Receiving Data */
|
||||
|
||||
/******************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Main function to call the polled slave example.
|
||||
*
|
||||
* @param None.
|
||||
*
|
||||
* @return XST_SUCCESS if successful, XST_FAILURE if unsuccessful.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
*******************************************************************************/
|
||||
int main(void)
|
||||
{
|
||||
int Status;
|
||||
|
||||
xil_printf("IIC Slave Polled Example Test \r\n");
|
||||
|
||||
/*
|
||||
* Run the Iic polled slave example , specify the Device ID that is
|
||||
* generated in xparameters.h.
|
||||
*/
|
||||
Status = IicPsSlavePolledExample(IIC_DEVICE_ID);
|
||||
if (Status != XST_SUCCESS) {
|
||||
xil_printf("IIC Slave Polled Example Test Failed\r\n");
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
xil_printf("Successfully ran IIC Slave Polled Example Test\r\n");
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function does polled mode transfer in slave mode. It first sends to
|
||||
* master then receives.
|
||||
*
|
||||
* @param DeviceId is the Device ID of the IicPs Device and is the
|
||||
* XPAR_<IICPS_instance>_DEVICE_ID value from xparameters.h
|
||||
*
|
||||
* @return XST_SUCCESS if successful, otherwise XST_FAILURE.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
*******************************************************************************/
|
||||
int IicPsSlavePolledExample(u16 DeviceId)
|
||||
{
|
||||
int Status;
|
||||
XIicPs_Config *Config;
|
||||
int Index;
|
||||
|
||||
/*
|
||||
* Initialize the IIC driver so that it's ready to use
|
||||
* Look up the configuration in the config table,
|
||||
* then initialize it.
|
||||
*/
|
||||
Config = XIicPs_LookupConfig(DeviceId);
|
||||
if (NULL == Config) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
Status = XIicPs_CfgInitialize(&Iic, Config, Config->BaseAddress);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Perform a self-test to ensure that the hardware was built correctly.
|
||||
*/
|
||||
Status = XIicPs_SelfTest(&Iic);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
XIicPs_SetupSlave(&Iic, IIC_SLAVE_ADDR);
|
||||
|
||||
/*
|
||||
* Set the IIC serial clock rate.
|
||||
*/
|
||||
XIicPs_SetSClk(&Iic, IIC_SCLK_RATE);
|
||||
|
||||
/*
|
||||
* Initialize the send buffer bytes with a pattern to send and the
|
||||
* the receive buffer bytes to zero to allow the receive data to be
|
||||
* verified.
|
||||
*/
|
||||
for (Index = 0; Index < TEST_BUFFER_SIZE; Index++) {
|
||||
SendBuffer[Index] = (Index % TEST_BUFFER_SIZE);
|
||||
RecvBuffer[Index] = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Send the buffer using the IIC and ignore the number of bytes sent
|
||||
* as the return value since we are using it in interrupt mode.
|
||||
*/
|
||||
Status = XIicPs_SlaveSendPolled(&Iic, SendBuffer,
|
||||
TEST_BUFFER_SIZE);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
while (XIicPs_BusIsBusy(&Iic)) {
|
||||
/* NOP */
|
||||
}
|
||||
|
||||
Status = XIicPs_SlaveRecvPolled(&Iic, RecvBuffer,
|
||||
TEST_BUFFER_SIZE);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Verify received data is correct.
|
||||
*/
|
||||
for(Index = 0; Index < TEST_BUFFER_SIZE; Index ++) {
|
||||
if (RecvBuffer[Index] != Index % TEST_BUFFER_SIZE) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
|
@ -0,0 +1,468 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* 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 xiicps_repeated_start_example.c
|
||||
*
|
||||
* This file consists of a repeated start example using xiicps driver
|
||||
* in polled mode. The slave used is an EEPROM.
|
||||
*
|
||||
* The example is tested with a 2Kb/8Kb serial IIC EEPROM (ST M24C02/M24C08).
|
||||
* The WP pin of this EEPROM is hardwired to ground in the HW in which this
|
||||
* was tested.
|
||||
* This example can be used directly to read upto 16 pages
|
||||
* from start address in this EEPROM (Since single address byte).
|
||||
*
|
||||
* The AddressType should be u8 as the address pointer in the on-board
|
||||
* EEPROM is 1 bytes.
|
||||
*
|
||||
* This code assumes that no Operating System is being used.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* The I2C controller does not indicate completion of a receive transfer if HOLD
|
||||
* bit is set. Due to this errata, repeated start cannot be used if a receive
|
||||
* transfer is followed by any other transfer.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ---- -------- ---------------------------------------------------------
|
||||
* 2.1 hk 03/15/10 First release
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
#include "xparameters.h"
|
||||
#include "sleep.h"
|
||||
#include "xiicps.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 IIC_DEVICE_ID XPAR_XIICPS_0_DEVICE_ID
|
||||
|
||||
/*
|
||||
* The following constant defines the address of the IIC Slave device on the
|
||||
* IIC bus. Note that since the address is only 7 bits, this constant is the
|
||||
* address divided by 2.
|
||||
*/
|
||||
#define IIC_SLAVE_ADDR 0x54
|
||||
#define IIC_SCLK_RATE 100000
|
||||
#define IIC_MUX_ADDRESS 0x74
|
||||
|
||||
/*
|
||||
* The page size determines how much data should be written at a time.
|
||||
* The write function should be called with this as a maximum byte count.
|
||||
*/
|
||||
#define PAGE_SIZE 16
|
||||
|
||||
/*
|
||||
* The Starting address in the IIC EEPROM on which this test is performed.
|
||||
*/
|
||||
#define EEPROM_START_ADDRESS 0
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
/*
|
||||
* The AddressType should be u8 as the address pointer in the on-board
|
||||
* EEPROM is 1 bytes.
|
||||
*/
|
||||
typedef u8 AddressType;
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
int IicPsRepeatedStartExample(void);
|
||||
int EepromWriteData(u16 ByteCount);
|
||||
int MuxInit(void);
|
||||
int EepromReadDataRepStart(u8 *BufferPtr, u16 ByteCount);
|
||||
|
||||
/************************** Variable Definitions *****************************/
|
||||
|
||||
XIicPs IicInstance; /* The instance of the IIC device. */
|
||||
|
||||
/*
|
||||
* Write buffer for writing a page.
|
||||
*/
|
||||
u8 WriteBuffer[sizeof(AddressType) + PAGE_SIZE];
|
||||
|
||||
u8 ReadBuffer[PAGE_SIZE*20]; /* Read buffer for reading a page. */
|
||||
|
||||
/************************** Function Definitions *****************************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* Main function to call the Iic repeated start example.
|
||||
*
|
||||
* @param None.
|
||||
*
|
||||
* @return XST_SUCCESS if successful else XST_FAILURE.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
int main(void)
|
||||
{
|
||||
int Status;
|
||||
|
||||
xil_printf("IIC Repeated Start Example Test \r\n");
|
||||
|
||||
/*
|
||||
* Run the Iic repeated start example.
|
||||
* Refer to note in the header - repeated start cannot be used
|
||||
* if read transfer is followed by any other transfer.
|
||||
*/
|
||||
Status = IicPsRepeatedStartExample();
|
||||
if (Status != XST_SUCCESS) {
|
||||
xil_printf("IIC Repeated Start Example Test Failed\r\n");
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
xil_printf("Successfully ran IIC Repeated Start Example Test\r\n");
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* This function writes, reads, and verifies the data to the IIC EEPROM.
|
||||
* Page write is used. Buffered read with repeated start option is done.
|
||||
*
|
||||
* @param None.
|
||||
*
|
||||
* @return XST_SUCCESS if successful else XST_FAILURE.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
int IicPsRepeatedStartExample(void)
|
||||
{
|
||||
u32 Index;
|
||||
int Status;
|
||||
XIicPs_Config *ConfigPtr; /* Pointer to configuration data */
|
||||
AddressType Address = EEPROM_START_ADDRESS;
|
||||
AddressType AddressTemp;
|
||||
int PageCnt;
|
||||
int NumPages = 16;
|
||||
|
||||
/*
|
||||
* Initialize the IIC driver so that it is ready to use.
|
||||
*/
|
||||
ConfigPtr = XIicPs_LookupConfig(IIC_DEVICE_ID);
|
||||
if (ConfigPtr == NULL) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
Status = XIicPs_CfgInitialize(&IicInstance, ConfigPtr,
|
||||
ConfigPtr->BaseAddress);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the IIC serial clock rate.
|
||||
*/
|
||||
XIicPs_SetSClk(&IicInstance, IIC_SCLK_RATE);
|
||||
|
||||
/*
|
||||
* Set the channel value in IIC Mux.
|
||||
*/
|
||||
Status = MuxInit();
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
AddressTemp = Address;
|
||||
for(PageCnt = 0; PageCnt < NumPages; PageCnt++) {
|
||||
/*
|
||||
* Initialize the data to write and the read buffer.
|
||||
*/
|
||||
if (sizeof(AddressTemp) == 1) {
|
||||
WriteBuffer[0] = (u8) (AddressTemp);
|
||||
} else {
|
||||
WriteBuffer[0] = (u8) (AddressTemp >> 8);
|
||||
WriteBuffer[1] = (u8) (AddressTemp);
|
||||
}
|
||||
|
||||
for (Index = 0; Index < PAGE_SIZE; Index++) {
|
||||
WriteBuffer[sizeof(AddressTemp) + Index] = 0xFF;
|
||||
ReadBuffer[Index] = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write to the EEPROM.
|
||||
*/
|
||||
Status = EepromWriteData(sizeof(AddressTemp) + PAGE_SIZE);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
AddressTemp += PAGE_SIZE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read from the EEPROM.
|
||||
*/
|
||||
Status = EepromReadDataRepStart(ReadBuffer, PAGE_SIZE*NumPages);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Verify the data read against the data written.
|
||||
*/
|
||||
for (Index = 0; Index < PAGE_SIZE*NumPages; Index++) {
|
||||
if (ReadBuffer[Index] !=
|
||||
WriteBuffer[Index%PAGE_SIZE + sizeof(Address)]) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
ReadBuffer[Index] = 0;
|
||||
}
|
||||
|
||||
AddressTemp = Address;
|
||||
for(PageCnt = 0; PageCnt < NumPages; PageCnt++) {
|
||||
/*
|
||||
* Initialize the data to write and the read buffer.
|
||||
*/
|
||||
if (sizeof(AddressTemp) == 1) {
|
||||
WriteBuffer[0] = (u8) (AddressTemp);
|
||||
} else {
|
||||
WriteBuffer[0] = (u8) (AddressTemp >> 8);
|
||||
WriteBuffer[1] = (u8) (AddressTemp);
|
||||
}
|
||||
|
||||
for (Index = 0; Index < PAGE_SIZE; Index++) {
|
||||
WriteBuffer[sizeof(AddressTemp) + Index] = Index + 10;
|
||||
ReadBuffer[Index] = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write to the EEPROM.
|
||||
*/
|
||||
Status = EepromWriteData(sizeof(AddressTemp) + PAGE_SIZE);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
AddressTemp += PAGE_SIZE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read from the EEPROM.
|
||||
*/
|
||||
Status = EepromReadDataRepStart(ReadBuffer, PAGE_SIZE*NumPages);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Verify the data read against the data written.
|
||||
*/
|
||||
for (Index = 0; Index < PAGE_SIZE*NumPages; Index++) {
|
||||
if (ReadBuffer[Index] !=
|
||||
WriteBuffer[Index%PAGE_SIZE + sizeof(Address)]) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
ReadBuffer[Index] = 0;
|
||||
}
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* This function writes a buffer of data to the IIC serial EEPROM.
|
||||
*
|
||||
* @param ByteCount contains the number of bytes in the buffer to be
|
||||
* written.
|
||||
*
|
||||
* @return XST_SUCCESS if successful else XST_FAILURE.
|
||||
*
|
||||
* @note The Byte count should not exceed the page size of the EEPROM as
|
||||
* noted by the constant PAGE_SIZE.
|
||||
*
|
||||
******************************************************************************/
|
||||
int EepromWriteData(u16 ByteCount)
|
||||
{
|
||||
int Status;
|
||||
|
||||
/*
|
||||
* Send the Data.
|
||||
*/
|
||||
Status = XIicPs_MasterSendPolled(&IicInstance, WriteBuffer,
|
||||
ByteCount, IIC_SLAVE_ADDR);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Wait until bus is idle to start another transfer.
|
||||
*/
|
||||
if (!(IicInstance.IsRepeatedStart)) {
|
||||
while (XIicPs_BusIsBusy(&IicInstance));
|
||||
}
|
||||
|
||||
/*
|
||||
* Wait for a bit of time to allow the programming to complete
|
||||
*/
|
||||
usleep(250000);
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* This function reads data from the IIC serial EEPROM into a specified buffer.
|
||||
*
|
||||
* @param BufferPtr contains the address of the data buffer to be filled.
|
||||
* @param ByteCount contains the number of bytes in the buffer to be read.
|
||||
*
|
||||
* @return XST_SUCCESS if successful else XST_FAILURE.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
int EepromReadDataRepStart(u8 *BufferPtr, u16 ByteCount)
|
||||
{
|
||||
int Status;
|
||||
AddressType Address = EEPROM_START_ADDRESS;
|
||||
|
||||
/*
|
||||
* Enable repeated start option.
|
||||
* This call will give an indication to the driver.
|
||||
* The hold bit is actually set before beginning the following transfer
|
||||
*/
|
||||
XIicPs_SetOptions(&IicInstance, XIICPS_REP_START_OPTION);
|
||||
|
||||
/*
|
||||
* Position the Pointer in EEPROM.
|
||||
*/
|
||||
if (sizeof(Address) == 1) {
|
||||
WriteBuffer[0] = (u8) (Address);
|
||||
}
|
||||
else {
|
||||
WriteBuffer[0] = (u8) (Address >> 8);
|
||||
WriteBuffer[1] = (u8) (Address);
|
||||
}
|
||||
|
||||
Status = EepromWriteData(sizeof(Address));
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Disbale repeated start option.
|
||||
* This call will give an indication to the driver.
|
||||
* The hold bit is actually reset when the following transfer ends.
|
||||
*/
|
||||
XIicPs_ClearOptions(&IicInstance, XIICPS_REP_START_OPTION);
|
||||
|
||||
/*
|
||||
* Receive the Data.
|
||||
*/
|
||||
Status = XIicPs_MasterRecvPolled(&IicInstance, BufferPtr,
|
||||
ByteCount, IIC_SLAVE_ADDR);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Wait until bus is idle to start another transfer.
|
||||
*/
|
||||
while (XIicPs_BusIsBusy(&IicInstance));
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* This function initializes the IIC MUX to select EEPROM.
|
||||
*
|
||||
* @param None.
|
||||
*
|
||||
* @return XST_SUCCESS if pass, otherwise XST_FAILURE.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
****************************************************************************/
|
||||
int MuxInit(void)
|
||||
{
|
||||
u8 WriteBuffer;
|
||||
u8 MuxIicAddr = IIC_MUX_ADDRESS;
|
||||
u8 Buffer = 0;
|
||||
int Status = 0;
|
||||
|
||||
/*
|
||||
* Channel select value for EEPROM.
|
||||
*/
|
||||
WriteBuffer = 0x04;
|
||||
|
||||
/*
|
||||
* Send the Data.
|
||||
*/
|
||||
Status = XIicPs_MasterSendPolled(&IicInstance, &WriteBuffer,1,
|
||||
MuxIicAddr);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Wait until bus is idle to start another transfer.
|
||||
*/
|
||||
while (XIicPs_BusIsBusy(&IicInstance));
|
||||
|
||||
/*
|
||||
* Receive the Data.
|
||||
*/
|
||||
Status = XIicPs_MasterRecvPolled(&IicInstance, &Buffer,1, MuxIicAddr);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Wait until bus is idle to start another transfer.
|
||||
*/
|
||||
while (XIicPs_BusIsBusy(&IicInstance));
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
|
@ -0,0 +1,154 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* 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 xiicps_selftest_example.c
|
||||
*
|
||||
* This file contains a example for using the IIC hardware device and
|
||||
* XIicPs driver.
|
||||
*
|
||||
*
|
||||
* <pre> MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- --- -------- -----------------------------------------------
|
||||
* 1.00a sdm 05/30/11 First release
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/***************************** Include Files **********************************/
|
||||
#include "xparameters.h"
|
||||
#include "xiicps.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 IIC_DEVICE_ID XPAR_XIICPS_0_DEVICE_ID
|
||||
|
||||
|
||||
/**************************** Type Definitions ********************************/
|
||||
|
||||
/************************** Function Prototypes *******************************/
|
||||
|
||||
int IicPsSelfTestExample(u16 DeviceId);
|
||||
|
||||
/************************** Variable Definitions ******************************/
|
||||
|
||||
XIicPs Iic; /* Instance of the IIC Device */
|
||||
|
||||
/******************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Main function to call the Self Test example.
|
||||
*
|
||||
* @param None.
|
||||
*
|
||||
* @return XST_SUCCESS if successful, XST_FAILURE if unsuccessful.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
*******************************************************************************/
|
||||
#ifndef TESTAPP_GEN
|
||||
int main(void)
|
||||
{
|
||||
int Status;
|
||||
|
||||
xil_printf("IIC Self Test Example \r\n");
|
||||
|
||||
/*
|
||||
* Run the Iic Self Test example, specify the Device ID that is
|
||||
* generated in xparameters.h
|
||||
*/
|
||||
Status = IicPsSelfTestExample(IIC_DEVICE_ID);
|
||||
if (Status != XST_SUCCESS) {
|
||||
xil_printf("IIC Self Test Failed\r\n");
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
xil_printf("Successfully ran IIC Self Test Example Test\r\n");
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function does a minimal test on the Iic device and driver as a
|
||||
* design example. The purpose of this function is to illustrate
|
||||
* how to use the XIicPs component.
|
||||
*
|
||||
*
|
||||
* @param DeviceId is the Device ID of the IicPs Device and is the
|
||||
* XPAR_<IICPS_instance>_DEVICE_ID value from xparameters.h
|
||||
*
|
||||
* @return XST_SUCCESS if successful, otherwise XST_FAILURE.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
*
|
||||
*******************************************************************************/
|
||||
int IicPsSelfTestExample(u16 DeviceId)
|
||||
{
|
||||
int Status;
|
||||
XIicPs_Config *Config;
|
||||
|
||||
/*
|
||||
* Initialize the IIC driver so that it's ready to use
|
||||
* Look up the configuration in the config table, then initialize it.
|
||||
*/
|
||||
Config = XIicPs_LookupConfig(DeviceId);
|
||||
if (NULL == Config) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
Status = XIicPs_CfgInitialize(&Iic, Config, Config->BaseAddress);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Perform a self-test.
|
||||
*/
|
||||
Status = XIicPs_SelfTest(&Iic);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
|
@ -0,0 +1,354 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* 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 xiicps_slave_monitor_example.c
|
||||
*
|
||||
* A design example of using the device as master to check slave's
|
||||
* availability.
|
||||
*
|
||||
* @note
|
||||
* Please set the slave address to 0x3FB, which tests the device's ability
|
||||
* to handle 10-bit address.
|
||||
*
|
||||
* <pre> MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- --- -------- -----------------------------------------------
|
||||
* 1.00a jz 01/30/10 First release
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/***************************** Include Files **********************************/
|
||||
#include "xparameters.h"
|
||||
#include "xiicps.h"
|
||||
#include "xscugic.h"
|
||||
#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 IIC_DEVICE_ID XPAR_XIICPS_0_DEVICE_ID
|
||||
#define INTC_DEVICE_ID XPAR_SCUGIC_SINGLE_DEVICE_ID
|
||||
#define IIC_INT_VEC_ID XPAR_XIICPS_0_INTR
|
||||
|
||||
/*
|
||||
* The slave address to send to and receive from.
|
||||
*/
|
||||
#define IIC_SLAVE_ADDR 0x3FB
|
||||
#define IIC_SCLK_RATE 100000
|
||||
|
||||
/*
|
||||
* This timeout interval is used in polling mode transfers.
|
||||
* Please increase the timeout limit on faster systems to avoid
|
||||
* unintended timeout failure.
|
||||
*/
|
||||
#define POLL_TIME_OUT 2000000 /**< Time out count for polled transfer*/
|
||||
|
||||
/**************************** Type Definitions ********************************/
|
||||
|
||||
/************************** Function Prototypes *******************************/
|
||||
|
||||
int IicPsSlaveMonitorExample(u16 DeviceId);
|
||||
|
||||
static int SetupInterruptSystem(XIicPs *IicPsPtr);
|
||||
|
||||
void Handler(void *CallBackRef, u32 Event);
|
||||
|
||||
/************************** Variable Definitions ******************************/
|
||||
|
||||
XIicPs Iic; /* Instance of the IIC Device */
|
||||
XScuGic InterruptController; /* Instance of the Interrupt Controller */
|
||||
|
||||
/*
|
||||
* The following counters are used to determine when the entire buffer has
|
||||
* been sent and received.
|
||||
*/
|
||||
volatile int SlaveReady;
|
||||
volatile int TotalError;
|
||||
|
||||
/******************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Main function to call the Slave Monitor example.
|
||||
*
|
||||
* @param None.
|
||||
*
|
||||
* @return XST_SUCCESS if successful, XST_FAILURE if unsuccessful.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
*******************************************************************************/
|
||||
int main(void)
|
||||
{
|
||||
int Status;
|
||||
|
||||
xil_printf("IIC Slave Monitor Example Test \r\n");
|
||||
|
||||
/*
|
||||
* Run the Iic Slave Monitor example, specify the Device ID that is
|
||||
* generated in xparameters.h.
|
||||
*/
|
||||
Status = IicPsSlaveMonitorExample(IIC_DEVICE_ID);
|
||||
if (Status != XST_SUCCESS) {
|
||||
xil_printf("IIC Slave Monitor Example Test Failed\r\n");
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
xil_printf("Successfully ran IIC Slave Monitor Example Test\r\n");
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function checks the availability of a slave using slave monitor mode.
|
||||
*
|
||||
* @param DeviceId is the Device ID of the IicPs Device and is the
|
||||
* XPAR_<IICPS_instance>_DEVICE_ID value from xparameters.h
|
||||
*
|
||||
* @return XST_SUCCESS if successful, otherwise XST_FAILURE.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
*******************************************************************************/
|
||||
int IicPsSlaveMonitorExample(u16 DeviceId)
|
||||
{
|
||||
int Status;
|
||||
int Timeout;
|
||||
XIicPs_Config *Config;
|
||||
|
||||
/*
|
||||
* Initialize the IIC driver so that it's ready to use
|
||||
* Look up the configuration in the config table,
|
||||
* then initialize it.
|
||||
*/
|
||||
Config = XIicPs_LookupConfig(DeviceId);
|
||||
if (NULL == Config) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
Status = XIicPs_CfgInitialize(&Iic, Config, Config->BaseAddress);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Perform a self-test to ensure that the hardware was built correctly.
|
||||
*/
|
||||
Status = XIicPs_SelfTest(&Iic);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Connect the IIC to the interrupt subsystem such that interrupts can
|
||||
* occur. This function is application specific.
|
||||
*/
|
||||
Status = SetupInterruptSystem(&Iic);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup the handlers for the IIC that will be called from the
|
||||
* interrupt context when slave response to the address transfer.
|
||||
*/
|
||||
XIicPs_SetStatusHandler(&Iic, (void *) &Iic, Handler);
|
||||
|
||||
/*
|
||||
* Set 10-bit address mode.
|
||||
*/
|
||||
XIicPs_SetOptions(&Iic, XIICPS_10_BIT_ADDR_OPTION);
|
||||
|
||||
/*
|
||||
* Set the IIC serial clock rate.
|
||||
*/
|
||||
Status = XIicPs_SetSClk(&Iic, IIC_SCLK_RATE);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Wait for the bus to be idle.
|
||||
*/
|
||||
while (XIicPs_BusIsBusy(&Iic)) {
|
||||
/* NOP */
|
||||
}
|
||||
|
||||
XIicPs_EnableSlaveMonitor(&Iic, IIC_SLAVE_ADDR);
|
||||
|
||||
TotalError= 0;
|
||||
SlaveReady = FALSE;
|
||||
|
||||
Timeout = POLL_TIME_OUT;
|
||||
|
||||
/*
|
||||
* Wait for the Slave Monitor Interrupt, the interrupt processing
|
||||
* works in the background, this function may get locked up in this
|
||||
* loop if the interrupts are not working correctly or the slave
|
||||
* never responds.
|
||||
*/
|
||||
while ((!SlaveReady) && (Timeout > 0)) {
|
||||
Timeout --;
|
||||
/*
|
||||
* Ignore any errors. The hardware generates NACK interrupts
|
||||
* if the slave is not present.
|
||||
*/
|
||||
if (0 != TotalError) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (Timeout == 0) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
XIicPs_DisableSlaveMonitor(&Iic);
|
||||
|
||||
/*
|
||||
* Clear 10-bit address mode.
|
||||
*/
|
||||
XIicPs_ClearOptions(&Iic, XIICPS_10_BIT_ADDR_OPTION);
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function is the handler which performs processing to handle data events
|
||||
* from the IIC. It is called from an interrupt context such that the amount
|
||||
* of processing performed should be minimized.
|
||||
*
|
||||
* This handler provides an example of how to handle data for the IIC and
|
||||
* is application specific.
|
||||
*
|
||||
* @param CallBackRef contains a callback reference from the driver,
|
||||
* in this case it is the instance pointer for the IIC driver.
|
||||
* @param Event contains the specific kind of event that has occurred.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
*******************************************************************************/
|
||||
void Handler(void *CallBackRef, u32 Event)
|
||||
{
|
||||
if (0 != (Event & XIICPS_EVENT_SLAVE_RDY)){
|
||||
SlaveReady = TRUE;
|
||||
return;
|
||||
}
|
||||
TotalError += 1;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function setups the interrupt system such that interrupts can occur
|
||||
* for the IIC. This function is application specific since the actual
|
||||
* system may or may not have an interrupt controller. The IIC could be
|
||||
* directly connected to a processor without an interrupt controller. The
|
||||
* user should modify this function to fit the application.
|
||||
*
|
||||
* @param IicPsPtr contains a pointer to the instance of the Iic
|
||||
* which is going to be connected to the interrupt controller.
|
||||
*
|
||||
* @return XST_SUCCESS if successful, otherwise XST_FAILURE.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
*******************************************************************************/
|
||||
static int SetupInterruptSystem(XIicPs *IicPsPtr)
|
||||
{
|
||||
int Status;
|
||||
XScuGic_Config *IntcConfig;
|
||||
|
||||
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(&InterruptController, 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_IRQ_INT,
|
||||
(Xil_ExceptionHandler)XScuGic_InterruptHandler,
|
||||
&InterruptController);
|
||||
|
||||
/*
|
||||
* 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(&InterruptController, IIC_INT_VEC_ID,
|
||||
(Xil_InterruptHandler)XIicPs_MasterInterruptHandler,
|
||||
(void *)IicPsPtr);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
/*
|
||||
* Enable the interrupt for the Iic device.
|
||||
*/
|
||||
XScuGic_Enable(&InterruptController, IIC_INT_VEC_ID);
|
||||
|
||||
|
||||
/*
|
||||
* Enable interrupts in the Processor.
|
||||
*/
|
||||
Xil_ExceptionEnable();
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
40
XilinxProcessorIPLib/drivers/iicps/src/Makefile
Normal file
40
XilinxProcessorIPLib/drivers/iicps/src/Makefile
Normal 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 xiicps_libs clean
|
||||
|
||||
%.o: %.c
|
||||
${COMPILER} $(CC_FLAGS) $(ECC_FLAGS) $(INCLUDES) -o $@ $<
|
||||
|
||||
banner:
|
||||
echo "Compiling iicps"
|
||||
|
||||
xiicps_libs: ${OBJECTS}
|
||||
$(ARCHIVER) -r ${RELEASEDIR}/${LIB} ${OBJECTS}
|
||||
|
||||
.PHONY: include
|
||||
include: xiicps_includes
|
||||
|
||||
xiicps_includes:
|
||||
${CP} ${INCLUDEFILES} ${INCLUDEDIR}
|
||||
|
||||
clean:
|
||||
rm -rf ${OBJECTS}
|
326
XilinxProcessorIPLib/drivers/iicps/src/xiicps.c
Normal file
326
XilinxProcessorIPLib/drivers/iicps/src/xiicps.c
Normal file
|
@ -0,0 +1,326 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* 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 xiicps.c
|
||||
*
|
||||
* Contains implementation of required functions for the XIicPs driver.
|
||||
* See xiicps.h for detailed description of the device and driver.
|
||||
*
|
||||
* <pre> MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ------ -------- --------------------------------------------
|
||||
* 1.00a drg/jz 01/30/10 First release
|
||||
* 1.00a sdm 09/21/11 Updated the InstancePtr->Options in the
|
||||
* XIicPs_CfgInitialize by calling XIicPs_GetOptions.
|
||||
* 2.1 hk 04/25/14 Explicitly reset CR and clear FIFO in Abort function
|
||||
* and state the same in the comments. CR# 784254.
|
||||
* Fix for CR# 761060 - provision for repeated start.
|
||||
* 2.3 sk 10/07/14 Repeated start feature removed.
|
||||
* 2.4 sk 11/03/14 Modified TimeOut Register value to 0xFF
|
||||
* in XIicPs_Reset.
|
||||
* 12/06/14 Implemented Repeated start feature.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
#include "xiicps.h"
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
static void StubHandler(void *CallBackRef, u32 StatusEvent);
|
||||
|
||||
/************************** Variable Definitions *****************************/
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Initializes a specific XIicPs instance such that the driver is ready to use.
|
||||
*
|
||||
* The state of the device after initialization is:
|
||||
* - Device is disabled
|
||||
* - Slave mode
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XIicPs instance.
|
||||
* @param ConfigPtr is a reference to a structure containing information
|
||||
* about a specific IIC device. This function initializes an
|
||||
* InstancePtr object for a specific device specified by the
|
||||
* contents of Config.
|
||||
* @param EffectiveAddr is the device base address in the virtual memory
|
||||
* address space. The caller is responsible for keeping the address
|
||||
* mapping from EffectiveAddr to the device physical base address
|
||||
* unchanged once this function is invoked. Unexpected errors may
|
||||
* occur if the address mapping changes after this function is
|
||||
* called. If address translation is not used, use
|
||||
* ConfigPtr->BaseAddress for this parameter, passing the physical
|
||||
* address instead.
|
||||
*
|
||||
* @return The return value is XST_SUCCESS if successful.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
int XIicPs_CfgInitialize(XIicPs *InstancePtr, XIicPs_Config *ConfigPtr,
|
||||
u32 EffectiveAddr)
|
||||
{
|
||||
/*
|
||||
* Assert validates the input arguments.
|
||||
*/
|
||||
Xil_AssertNonvoid(InstancePtr != NULL);
|
||||
Xil_AssertNonvoid(ConfigPtr != NULL);
|
||||
|
||||
/*
|
||||
* Set some default values.
|
||||
*/
|
||||
InstancePtr->Config.DeviceId = ConfigPtr->DeviceId;
|
||||
InstancePtr->Config.BaseAddress = EffectiveAddr;
|
||||
InstancePtr->Config.InputClockHz = ConfigPtr->InputClockHz;
|
||||
InstancePtr->StatusHandler = StubHandler;
|
||||
InstancePtr->CallBackRef = NULL;
|
||||
|
||||
InstancePtr->IsReady = XIL_COMPONENT_IS_READY;
|
||||
|
||||
/*
|
||||
* Reset the IIC device to get it into its initial state. It is expected
|
||||
* that device configuration will take place after this initialization
|
||||
* is done, but before the device is started.
|
||||
*/
|
||||
XIicPs_Reset(InstancePtr);
|
||||
|
||||
/*
|
||||
* Keep a copy of what options this instance has.
|
||||
*/
|
||||
InstancePtr->Options = XIicPs_GetOptions(InstancePtr);
|
||||
|
||||
/* Initialize repeated start flag to 0 */
|
||||
InstancePtr->IsRepeatedStart = 0;
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* Check whether the I2C bus is busy
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XIicPs instance.
|
||||
*
|
||||
* @return
|
||||
* - TRUE if the bus is busy.
|
||||
* - FALSE if the bus is not busy.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
int XIicPs_BusIsBusy(XIicPs *InstancePtr)
|
||||
{
|
||||
u32 StatusReg;
|
||||
|
||||
StatusReg = XIicPs_ReadReg(InstancePtr->Config.BaseAddress,
|
||||
XIICPS_SR_OFFSET);
|
||||
if (StatusReg & XIICPS_SR_BA_MASK) {
|
||||
return TRUE;
|
||||
}else {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This is a stub for the status callback. The stub is here in case the upper
|
||||
* layers forget to set the handler.
|
||||
*
|
||||
* @param CallBackRef is a pointer to the upper layer callback reference.
|
||||
* @param StatusEvent is the event that just occurred.
|
||||
* @param ByteCount is the number of bytes transferred up until the event
|
||||
* occurred.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
static void StubHandler(void *CallBackRef, u32 StatusEvent)
|
||||
{
|
||||
(void) CallBackRef;
|
||||
(void) StatusEvent;
|
||||
Xil_AssertVoidAlways();
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Aborts a transfer in progress by resetting the FIFOs. The byte counts are
|
||||
* cleared.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XIicPs instance.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
void XIicPs_Abort(XIicPs *InstancePtr)
|
||||
{
|
||||
u32 IntrMaskReg;
|
||||
u32 IntrStatusReg;
|
||||
|
||||
Xil_AssertVoid(InstancePtr != NULL);
|
||||
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
|
||||
/*
|
||||
* Enter a critical section, so disable the interrupts while we clear
|
||||
* the FIFO and the status register.
|
||||
*/
|
||||
IntrMaskReg = XIicPs_ReadReg(InstancePtr->Config.BaseAddress,
|
||||
XIICPS_IMR_OFFSET);
|
||||
XIicPs_WriteReg(InstancePtr->Config.BaseAddress,
|
||||
XIICPS_IDR_OFFSET, XIICPS_IXR_ALL_INTR_MASK);
|
||||
|
||||
/*
|
||||
* Reset the settings in config register and clear the FIFOs.
|
||||
*/
|
||||
XIicPs_WriteReg(InstancePtr->Config.BaseAddress, XIICPS_CR_OFFSET,
|
||||
XIICPS_CR_RESET_VALUE | XIICPS_CR_CLR_FIFO_MASK);
|
||||
|
||||
/*
|
||||
* Read, then write the interrupt status to make sure there are no
|
||||
* pending interrupts.
|
||||
*/
|
||||
IntrStatusReg = XIicPs_ReadReg(InstancePtr->Config.BaseAddress,
|
||||
XIICPS_ISR_OFFSET);
|
||||
XIicPs_WriteReg(InstancePtr->Config.BaseAddress,
|
||||
XIICPS_ISR_OFFSET, IntrStatusReg);
|
||||
|
||||
/*
|
||||
* Restore the interrupt state.
|
||||
*/
|
||||
IntrMaskReg = XIICPS_IXR_ALL_INTR_MASK & (~IntrMaskReg);
|
||||
XIicPs_WriteReg(InstancePtr->Config.BaseAddress,
|
||||
XIICPS_IER_OFFSET, IntrMaskReg);
|
||||
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Resets the IIC device. Reset must only be called after the driver has been
|
||||
* initialized. The configuration of the device after reset is the same as its
|
||||
* configuration after initialization. Any data transfer that is in progress is
|
||||
* aborted.
|
||||
*
|
||||
* The upper layer software is responsible for re-configuring (if necessary)
|
||||
* and reenabling interrupts for the IIC device after the reset.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XIicPs instance.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
void XIicPs_Reset(XIicPs *InstancePtr)
|
||||
{
|
||||
|
||||
Xil_AssertVoid(InstancePtr != NULL);
|
||||
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
|
||||
/*
|
||||
* Abort any transfer that is in progress.
|
||||
*/
|
||||
XIicPs_Abort(InstancePtr);
|
||||
|
||||
/*
|
||||
* Reset any values so the software state matches the hardware device.
|
||||
*/
|
||||
XIicPs_WriteReg(InstancePtr->Config.BaseAddress, XIICPS_CR_OFFSET,
|
||||
XIICPS_CR_RESET_VALUE);
|
||||
XIicPs_WriteReg(InstancePtr->Config.BaseAddress,
|
||||
XIICPS_TIME_OUT_OFFSET, XIICPS_TO_RESET_VALUE);
|
||||
XIicPs_WriteReg(InstancePtr->Config.BaseAddress, XIICPS_IDR_OFFSET,
|
||||
XIICPS_IXR_ALL_INTR_MASK);
|
||||
|
||||
}
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* Put more data into the transmit FIFO, number of bytes is ether expected
|
||||
* number of bytes for this transfer or available space in FIFO, which ever
|
||||
* is less.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XIicPs instance.
|
||||
*
|
||||
* @return Number of bytes left for this instance.
|
||||
*
|
||||
* @note This is function is shared by master and slave.
|
||||
*
|
||||
******************************************************************************/
|
||||
int TransmitFifoFill(XIicPs *InstancePtr)
|
||||
{
|
||||
u8 AvailBytes;
|
||||
int LoopCnt;
|
||||
int NumBytesToSend;
|
||||
|
||||
/*
|
||||
* Determine number of bytes to write to FIFO.
|
||||
*/
|
||||
AvailBytes = XIICPS_FIFO_DEPTH -
|
||||
XIicPs_ReadReg(InstancePtr->Config.BaseAddress,
|
||||
XIICPS_TRANS_SIZE_OFFSET);
|
||||
|
||||
if (InstancePtr->SendByteCount > AvailBytes) {
|
||||
NumBytesToSend = AvailBytes;
|
||||
} else {
|
||||
NumBytesToSend = InstancePtr->SendByteCount;
|
||||
}
|
||||
|
||||
/*
|
||||
* Fill FIFO with amount determined above.
|
||||
*/
|
||||
for (LoopCnt = 0; LoopCnt < NumBytesToSend; LoopCnt++) {
|
||||
XIicPs_SendByte(InstancePtr);
|
||||
}
|
||||
|
||||
return InstancePtr->SendByteCount;
|
||||
}
|
405
XilinxProcessorIPLib/drivers/iicps/src/xiicps.h
Normal file
405
XilinxProcessorIPLib/drivers/iicps/src/xiicps.h
Normal file
|
@ -0,0 +1,405 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* 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 xiicps.h
|
||||
*
|
||||
* This is an implementation of IIC driver in the PS block. The device can
|
||||
* be either a master or a slave on the IIC bus. This implementation supports
|
||||
* both interrupt mode transfer and polled mode transfer. Only 7-bit address
|
||||
* is used in the driver, although the hardware also supports 10-bit address.
|
||||
*
|
||||
* IIC is a 2-wire serial interface. 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.
|
||||
*
|
||||
* The higher level software must implement a higher layer protocol to inform
|
||||
* the slave what to send to the master.
|
||||
*
|
||||
* <b>Initialization & Configuration</b>
|
||||
*
|
||||
* The XIicPs_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:
|
||||
*
|
||||
* - XIicPs_LookupConfig(DeviceId) - Use the device identifier to find
|
||||
* the static configuration structure defined in xiicps_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.
|
||||
*
|
||||
* - XIicPs_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 in the configuration
|
||||
* structure.
|
||||
*
|
||||
* <b>Multiple Masters</b>
|
||||
*
|
||||
* More than one master can exist, bus arbitration is defined in the IIC
|
||||
* standard. Lost of arbitration causes arbitration loss interrupt on the device.
|
||||
*
|
||||
* <b>Multiple Slaves</b>
|
||||
*
|
||||
* Multiple slaves are supported by selecting them with unique addresses. It is
|
||||
* up to the system designer to be sure all devices on the IIC bus have
|
||||
* unique addresses.
|
||||
*
|
||||
* <b>Addressing</b>
|
||||
*
|
||||
* The IIC hardware can use 7 or 10 bit addresses. The driver provides the
|
||||
* ability to control which address size is sent in messages as a master to a
|
||||
* slave device.
|
||||
*
|
||||
* <b>FIFO Size </b>
|
||||
* The hardware FIFO is 32 bytes deep. The user must know the limitations of
|
||||
* other IIC devices on the bus. Some are only able to receive a limited number
|
||||
* of bytes in a single transfer.
|
||||
*
|
||||
* <b>Data Rates</b>
|
||||
*
|
||||
* The data rate is set by values in the control register. The formula for
|
||||
* determining the correct register values is:
|
||||
* Fscl = Fpclk/(22 x (divisor_a+1) x (divisor_b+1))
|
||||
*
|
||||
* When the device is configured as a slave, the slck setting controls the
|
||||
* sample rate and so must be set to be at least as fast as the fastest scl
|
||||
* expected to be seen in the system.
|
||||
*
|
||||
* <b>Polled Mode Operation</b>
|
||||
*
|
||||
* This driver supports polled mode transfers.
|
||||
*
|
||||
* <b>Interrupts</b>
|
||||
*
|
||||
* The user must connect the interrupt handler of the driver,
|
||||
* XIicPs_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:
|
||||
* - Transfer complete
|
||||
* - More Data
|
||||
* - Transfer not Acknowledged
|
||||
* - Transfer Time out
|
||||
* - Monitored slave ready - master mode only
|
||||
* - Receive Overflow
|
||||
* - Transmit FIFO overflow
|
||||
* - Receive FIFO underflow
|
||||
* - Arbitration lost
|
||||
*
|
||||
* <b>Bus Busy</b>
|
||||
*
|
||||
* Bus busy is checked before the setup of a master mode device, to avoid
|
||||
* unnecessary arbitration loss interrupt.
|
||||
*
|
||||
* <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.
|
||||
*
|
||||
*<b>Repeated Start</b>
|
||||
*
|
||||
* The I2C controller does not indicate completion of a receive transfer if HOLD
|
||||
* bit is set. Due to this errata, repeated start cannot be used if a receive
|
||||
* transfer is followed by any other transfer.
|
||||
*
|
||||
* <pre> MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ------ -------- -----------------------------------------------
|
||||
* 1.00a drg/jz 01/30/08 First release
|
||||
* 1.00a sdm 09/21/11 Fixed an issue in the XIicPs_SetOptions and
|
||||
* XIicPs_ClearOptions where the InstancePtr->Options
|
||||
* was not updated correctly.
|
||||
* Updated the InstancePtr->Options in the
|
||||
* XIicPs_CfgInitialize by calling XIicPs_GetOptions.
|
||||
* Updated the XIicPs_SetupMaster to not check for
|
||||
* Bus Busy condition when the Hold Bit is set.
|
||||
* Removed some unused variables.
|
||||
* 1.01a sg 03/30/12 Fixed an issue in XIicPs_MasterSendPolled where a
|
||||
* check for transfer completion is added, which indicates
|
||||
* the completion of current transfer.
|
||||
* 1.02a sg 08/29/12 Updated the logic to arrive at the best divisors
|
||||
* to achieve I2C clock with minimum error for
|
||||
* CR #674195
|
||||
* 1.03a hk 05/04/13 Initialized BestDivA and BestDivB to 0.
|
||||
* This is fix for CR#704398 to remove warning.
|
||||
* 2.0 hk 03/07/14 Added check for error status in the while loop that
|
||||
* checks for completion.
|
||||
* (XIicPs_MasterSendPolled function). CR# 762244, 764875.
|
||||
* Limited frequency set when 100KHz or 400KHz is
|
||||
* selected. This is a hardware limitation. CR#779290.
|
||||
* 2.1 hk 04/24/14 Fix for CR# 789821 to handle >14 byte transfers.
|
||||
* Explicitly reset CR and clear FIFO in Abort function
|
||||
* and state the same in the comments. CR# 784254.
|
||||
* Fix for CR# 761060 - provision for repeated start.
|
||||
* 2.2 hk 08/23/14 Slave monitor mode changes - clear FIFO, enable
|
||||
* read mode and clear transfer size register.
|
||||
* Disable NACK to avoid interrupts on each retry.
|
||||
* 2.3 sk 10/07/14 Repeated start feature deleted.
|
||||
* 2.4 sk 11/03/14 Modified TimeOut Register value to 0xFF
|
||||
* in XIicPs_Reset.
|
||||
* 12/06/14 Implemented Repeated start feature.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef XIICPS_H /* prevent circular inclusions */
|
||||
#define XIICPS_H /* by using protection macros */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
#include "xil_types.h"
|
||||
#include "xil_assert.h"
|
||||
#include "xstatus.h"
|
||||
#include "xiicps_hw.h"
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
/** @name Configuration options
|
||||
*
|
||||
* The following options may be specified or retrieved for the device and
|
||||
* enable/disable additional features of the IIC. Each of the options
|
||||
* are bit fields, so more than one may be specified.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
#define XIICPS_7_BIT_ADDR_OPTION 0x01 /**< 7-bit address mode */
|
||||
#define XIICPS_10_BIT_ADDR_OPTION 0x02 /**< 10-bit address mode */
|
||||
#define XIICPS_SLAVE_MON_OPTION 0x04 /**< Slave monitor mode */
|
||||
#define XIICPS_REP_START_OPTION 0x08 /**< Repeated Start */
|
||||
/*@}*/
|
||||
|
||||
/** @name Callback events
|
||||
*
|
||||
* These constants specify the handler events that are passed to an application
|
||||
* event handler from the driver. These constants are bit masks such that
|
||||
* more than one event can be passed to the handler.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
#define XIICPS_EVENT_COMPLETE_SEND 0x0001 /**< Transmit Complete Event*/
|
||||
#define XIICPS_EVENT_COMPLETE_RECV 0x0002 /**< Receive Complete Event*/
|
||||
#define XIICPS_EVENT_TIME_OUT 0x0004 /**< Transfer timed out */
|
||||
#define XIICPS_EVENT_ERROR 0x0008 /**< Receive error */
|
||||
#define XIICPS_EVENT_ARB_LOST 0x0010 /**< Arbitration lost */
|
||||
#define XIICPS_EVENT_NACK 0x0020 /**< NACK Received */
|
||||
#define XIICPS_EVENT_SLAVE_RDY 0x0040 /**< Slave ready */
|
||||
#define XIICPS_EVENT_RX_OVR 0x0080 /**< RX overflow */
|
||||
#define XIICPS_EVENT_TX_OVR 0x0100 /**< TX overflow */
|
||||
#define XIICPS_EVENT_RX_UNF 0x0200 /**< RX underflow */
|
||||
/*@}*/
|
||||
|
||||
/** @name Role constants
|
||||
*
|
||||
* These constants are used to pass into the device setup routines to
|
||||
* set up the device according to transfer direction.
|
||||
*/
|
||||
#define SENDING_ROLE 1 /**< Transfer direction is sending */
|
||||
#define RECVING_ROLE 0 /**< Transfer direction is receiving */
|
||||
|
||||
/* Maximum transfer size */
|
||||
#define XIICPS_MAX_TRANSFER_SIZE (255 - 3)
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
/**
|
||||
* The handler data type allows the user to define a callback function to
|
||||
* respond to interrupt events in the system. This function is executed
|
||||
* in interrupt context, so amount of processing should be minimized.
|
||||
*
|
||||
* @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 indicates one or more status events that occurred.
|
||||
*/
|
||||
typedef void (*XIicPs_IntrHandler) (void *CallBackRef, u32 StatusEvent);
|
||||
|
||||
/**
|
||||
* 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 */
|
||||
} XIicPs_Config;
|
||||
|
||||
/**
|
||||
* The XIicPs driver instance data. The user is required to allocate a
|
||||
* variable of this type for each IIC device in the system. A pointer
|
||||
* to a variable of this type is then passed to the driver API functions.
|
||||
*/
|
||||
typedef struct {
|
||||
XIicPs_Config Config; /* Configuration structure */
|
||||
u32 IsReady; /* Device is initialized and ready */
|
||||
u32 Options; /* Options set in the device */
|
||||
|
||||
u8 *SendBufferPtr; /* Pointer to send buffer */
|
||||
u8 *RecvBufferPtr; /* Pointer to recv buffer */
|
||||
int SendByteCount; /* Number of bytes still expected to send */
|
||||
int RecvByteCount; /* Number of bytes still expected to receive */
|
||||
int CurrByteCount; /* No. of bytes expected in current transfer */
|
||||
|
||||
int UpdateTxSize; /* If tx size register has to be updated */
|
||||
int IsSend; /* Whether master is sending or receiving */
|
||||
int IsRepeatedStart; /* Indicates if user set repeated start */
|
||||
|
||||
XIicPs_IntrHandler StatusHandler; /* Event handler function */
|
||||
void *CallBackRef; /* Callback reference for event handler */
|
||||
} XIicPs;
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
/****************************************************************************/
|
||||
/*
|
||||
*
|
||||
* Place one byte into the transmit FIFO.
|
||||
*
|
||||
* @param InstancePtr is the instance of IIC
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note C-Style signature:
|
||||
* void XIicPs_SendByte(XIicPs *InstancePtr)
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XIicPs_SendByte(InstancePtr) \
|
||||
{ \
|
||||
XIicPs_Out32((InstancePtr)->Config.BaseAddress \
|
||||
+ XIICPS_DATA_OFFSET, \
|
||||
*(InstancePtr)->SendBufferPtr ++); \
|
||||
(InstancePtr)->SendByteCount --; \
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/*
|
||||
*
|
||||
* Receive one byte from FIFO.
|
||||
*
|
||||
* @param InstancePtr is the instance of IIC
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note C-Style signature:
|
||||
* u8 XIicPs_RecvByte(XIicPs *InstancePtr)
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XIicPs_RecvByte(InstancePtr) \
|
||||
{ \
|
||||
*(InstancePtr)->RecvBufferPtr ++ = \
|
||||
(u8)XIicPs_In32((InstancePtr)->Config.BaseAddress \
|
||||
+ XIICPS_DATA_OFFSET); \
|
||||
(InstancePtr)->RecvByteCount --; \
|
||||
}
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
/*
|
||||
* Function for configuration lookup, in xiicps_sinit.c
|
||||
*/
|
||||
XIicPs_Config *XIicPs_LookupConfig(u16 DeviceId);
|
||||
|
||||
/*
|
||||
* Functions for general setup, in xiicps.c
|
||||
*/
|
||||
int XIicPs_CfgInitialize(XIicPs *InstancePtr, XIicPs_Config * Config,
|
||||
u32 EffectiveAddr);
|
||||
|
||||
void XIicPs_Abort(XIicPs *InstancePtr);
|
||||
void XIicPs_Reset(XIicPs *InstancePtr);
|
||||
|
||||
int XIicPs_BusIsBusy(XIicPs *InstancePtr);
|
||||
|
||||
/*
|
||||
* Functions for interrupts, in xiicps_intr.c
|
||||
*/
|
||||
void XIicPs_SetStatusHandler(XIicPs *InstancePtr, void *CallBackRef,
|
||||
XIicPs_IntrHandler FuncPtr);
|
||||
|
||||
/*
|
||||
* Functions for device as master, in xiicps_master.c
|
||||
*/
|
||||
void XIicPs_MasterSend(XIicPs *InstancePtr, u8 *MsgPtr, int ByteCount,
|
||||
u16 SlaveAddr);
|
||||
void XIicPs_MasterRecv(XIicPs *InstancePtr, u8 *MsgPtr, int ByteCount,
|
||||
u16 SlaveAddr);
|
||||
int XIicPs_MasterSendPolled(XIicPs *InstancePtr, u8 *MsgPtr, int ByteCount,
|
||||
u16 SlaveAddr);
|
||||
int XIicPs_MasterRecvPolled(XIicPs *InstancePtr, u8 *MsgPtr, int ByteCount,
|
||||
u16 SlaveAddr);
|
||||
void XIicPs_EnableSlaveMonitor(XIicPs *InstancePtr, u16 SlaveAddr);
|
||||
void XIicPs_DisableSlaveMonitor(XIicPs *InstancePtr);
|
||||
void XIicPs_MasterInterruptHandler(XIicPs *InstancePtr);
|
||||
|
||||
/*
|
||||
* Functions for device as slave, in xiicps_slave.c
|
||||
*/
|
||||
void XIicPs_SetupSlave(XIicPs *InstancePtr, u16 SlaveAddr);
|
||||
void XIicPs_SlaveSend(XIicPs *InstancePtr, u8 *MsgPtr, int ByteCount);
|
||||
void XIicPs_SlaveRecv(XIicPs *InstancePtr, u8 *MsgPtr, int ByteCount);
|
||||
int XIicPs_SlaveSendPolled(XIicPs *InstancePtr, u8 *MsgPtr, int ByteCount);
|
||||
int XIicPs_SlaveRecvPolled(XIicPs *InstancePtr, u8 *MsgPtr, int ByteCount);
|
||||
void XIicPs_SlaveInterruptHandler(XIicPs *InstancePtr);
|
||||
|
||||
/*
|
||||
* Functions for selftest, in xiicps_selftest.c
|
||||
*/
|
||||
int XIicPs_SelfTest(XIicPs *InstancePtr);
|
||||
|
||||
/*
|
||||
* Functions for setting and getting data rate, in xiicps_options.c
|
||||
*/
|
||||
int XIicPs_SetOptions(XIicPs *InstancePtr, u32 Options);
|
||||
int XIicPs_ClearOptions(XIicPs *InstancePtr, u32 Options);
|
||||
u32 XIicPs_GetOptions(XIicPs *InstancePtr);
|
||||
|
||||
int XIicPs_SetSClk(XIicPs *InstancePtr, u32 FsclHz);
|
||||
u32 XIicPs_GetSClk(XIicPs *InstancePtr);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* end of protection macro */
|
86
XilinxProcessorIPLib/drivers/iicps/src/xiicps_g.c
Normal file
86
XilinxProcessorIPLib/drivers/iicps/src/xiicps_g.c
Normal 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 xiicps_g.c
|
||||
*
|
||||
* This file contains a configuration table that specifies the configuration of
|
||||
* IIC devices in the system.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ------ -------- --------------------------------------------
|
||||
* 1.00a drg/jz 01/30/10 First release
|
||||
* 2.00 hk 22/01/14 Added check for picking second instance
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
#include "xparameters.h"
|
||||
#include "xiicps.h"
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
|
||||
/************************** Variable Prototypes ******************************/
|
||||
|
||||
/**
|
||||
* This table contains configuration information for each IIC device
|
||||
* in the system.
|
||||
*/
|
||||
XIicPs_Config XIicPs_ConfigTable[XPAR_XIICPS_NUM_INSTANCES] = {
|
||||
{
|
||||
XPAR_XIICPS_0_DEVICE_ID, /* Device ID for instance */
|
||||
XPAR_XIICPS_0_BASEADDR, /* Device base address */
|
||||
XPAR_XIICPS_0_I2C_CLK_FREQ_HZ /* Device input clock frequency */
|
||||
},
|
||||
#ifdef XPAR_XIICPS_1_DEVICE_ID
|
||||
{
|
||||
XPAR_XIICPS_1_DEVICE_ID, /* Device ID for instance */
|
||||
XPAR_XIICPS_1_BASEADDR, /* Device base address */
|
||||
XPAR_XIICPS_1_CLOCK_HZ /* Device input clock frequency */
|
||||
}
|
||||
#endif
|
||||
};
|
107
XilinxProcessorIPLib/drivers/iicps/src/xiicps_hw.c
Normal file
107
XilinxProcessorIPLib/drivers/iicps/src/xiicps_hw.c
Normal file
|
@ -0,0 +1,107 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* 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 xiicps_hw.c
|
||||
*
|
||||
* Contains implementation of required functions for providing the reset sequence
|
||||
* to the i2c interface
|
||||
*
|
||||
* <pre> MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ------ -------- --------------------------------------------
|
||||
* 1.04a kpc 11/07/13 First release
|
||||
* 2.4 sk 11/03/14 Modified TimeOut Register value to 0xFF
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
#include "xiicps_hw.h"
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
/************************** Variable Definitions *****************************/
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* This function perform the reset sequence to the given I2c interface by
|
||||
* configuring the appropriate control bits in the I2c specifc registers
|
||||
* the i2cps reset squence involves the following steps
|
||||
* Disable all the interuupts
|
||||
* Clear the status
|
||||
* Clear FIFO's and disable hold bit
|
||||
* Clear the line status
|
||||
* Update relevant config registers with reset values
|
||||
*
|
||||
* @param BaseAddress of the interface
|
||||
*
|
||||
* @return N/A
|
||||
*
|
||||
* @note
|
||||
* This function will not modify the slcr registers that are relavant for
|
||||
* I2c controller
|
||||
******************************************************************************/
|
||||
void XIicPs_ResetHw(u32 BaseAddress)
|
||||
{
|
||||
u32 RegVal;
|
||||
|
||||
/* Disable all the interrupts */
|
||||
XIicPs_WriteReg(BaseAddress, XIICPS_IDR_OFFSET, XIICPS_IXR_ALL_INTR_MASK);
|
||||
/* Clear the interrupt status */
|
||||
RegVal = XIicPs_ReadReg(BaseAddress,XIICPS_ISR_OFFSET);
|
||||
XIicPs_WriteReg(BaseAddress, XIICPS_ISR_OFFSET, RegVal);
|
||||
/* Clear the hold bit,master enable bit and ack bit */
|
||||
RegVal = XIicPs_ReadReg(BaseAddress,XIICPS_CR_OFFSET);
|
||||
RegVal &= ~(XIICPS_CR_HOLD_MASK|XIICPS_CR_MS_MASK|XIICPS_CR_ACKEN_MASK);
|
||||
/* Clear the fifos */
|
||||
RegVal |= XIICPS_CR_CLR_FIFO_MASK;
|
||||
XIicPs_WriteReg(BaseAddress, XIICPS_CR_OFFSET, RegVal);
|
||||
/* Clear the timeout register */
|
||||
XIicPs_WriteReg(BaseAddress, XIICPS_TIME_OUT_OFFSET, XIICPS_TO_RESET_VALUE);
|
||||
/* Clear the transfer size register */
|
||||
XIicPs_WriteReg(BaseAddress, XIICPS_TRANS_SIZE_OFFSET, 0x0);
|
||||
/* Clear the status register */
|
||||
RegVal = XIicPs_ReadReg(BaseAddress,XIICPS_SR_OFFSET);
|
||||
XIicPs_WriteReg(BaseAddress, XIICPS_SR_OFFSET, RegVal);
|
||||
/* Update the configuraqtion register with reset value */
|
||||
XIicPs_WriteReg(BaseAddress, XIICPS_CR_OFFSET, 0x0);
|
||||
}
|
379
XilinxProcessorIPLib/drivers/iicps/src/xiicps_hw.h
Normal file
379
XilinxProcessorIPLib/drivers/iicps/src/xiicps_hw.h
Normal file
|
@ -0,0 +1,379 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* 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 xiicps_hw.h
|
||||
*
|
||||
* This header file contains the hardware definition for an IIC device.
|
||||
* It includes register definitions and interface functions to read/write
|
||||
* the registers.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ------ -------- -----------------------------------------------
|
||||
* 1.00a drg/jz 01/30/10 First release
|
||||
* 1.04a kpc 11/07/13 Added function prototype.
|
||||
* 2.4 sk 11/03/14 Modified the TimeOut Register value to 0xFF
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef XIICPS_HW_H /* prevent circular inclusions */
|
||||
#define XIICPS_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 for the IIC.
|
||||
* @{
|
||||
*/
|
||||
#define XIICPS_CR_OFFSET 0x00 /**< 32-bit Control */
|
||||
#define XIICPS_SR_OFFSET 0x04 /**< Status */
|
||||
#define XIICPS_ADDR_OFFSET 0x08 /**< IIC Address */
|
||||
#define XIICPS_DATA_OFFSET 0x0C /**< IIC FIFO Data */
|
||||
#define XIICPS_ISR_OFFSET 0x10 /**< Interrupt Status */
|
||||
#define XIICPS_TRANS_SIZE_OFFSET 0x14 /**< Transfer Size */
|
||||
#define XIICPS_SLV_PAUSE_OFFSET 0x18 /**< Slave monitor pause */
|
||||
#define XIICPS_TIME_OUT_OFFSET 0x1C /**< Time Out */
|
||||
#define XIICPS_IMR_OFFSET 0x20 /**< Interrupt Enabled Mask */
|
||||
#define XIICPS_IER_OFFSET 0x24 /**< Interrupt Enable */
|
||||
#define XIICPS_IDR_OFFSET 0x28 /**< Interrupt Disable */
|
||||
/* @} */
|
||||
|
||||
/** @name Control Register
|
||||
*
|
||||
* This register contains various control bits that
|
||||
* affects the operation of the IIC controller. Read/Write.
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define XIICPS_CR_DIV_A_MASK 0x0000C000 /**< Clock Divisor A */
|
||||
#define XIICPS_CR_DIV_A_SHIFT 14 /**< Clock Divisor A shift */
|
||||
#define XIICPS_DIV_A_MAX 4 /**< Maximum value of Divisor A */
|
||||
#define XIICPS_CR_DIV_B_MASK 0x00003F00 /**< Clock Divisor B */
|
||||
#define XIICPS_CR_DIV_B_SHIFT 8 /**< Clock Divisor B shift */
|
||||
#define XIICPS_CR_CLR_FIFO_MASK 0x00000040 /**< Clear FIFO, auto clears*/
|
||||
#define XIICPS_CR_SLVMON_MASK 0x00000020 /**< Slave monitor mode */
|
||||
#define XIICPS_CR_HOLD_MASK 0x00000010 /**< Hold bus 1=Hold scl,
|
||||
0=terminate transfer */
|
||||
#define XIICPS_CR_ACKEN_MASK 0x00000008 /**< Enable TX of ACK when
|
||||
Master receiver*/
|
||||
#define XIICPS_CR_NEA_MASK 0x00000004 /**< Addressing Mode 1=7 bit,
|
||||
0=10 bit */
|
||||
#define XIICPS_CR_MS_MASK 0x00000002 /**< Master mode bit 1=Master,
|
||||
0=Slave */
|
||||
#define XIICPS_CR_RD_WR_MASK 0x00000001 /**< Read or Write Master
|
||||
transfer 0=Transmitter,
|
||||
1=Receiver*/
|
||||
#define XIICPS_CR_RESET_VALUE 0 /**< Reset value of the Control
|
||||
register */
|
||||
/* @} */
|
||||
|
||||
/** @name IIC Status Register
|
||||
*
|
||||
* This register is used to indicate status of the IIC controller. Read only
|
||||
* @{
|
||||
*/
|
||||
#define XIICPS_SR_BA_MASK 0x00000100 /**< Bus Active Mask */
|
||||
#define XIICPS_SR_RXOVF_MASK 0x00000080 /**< Receiver Overflow Mask */
|
||||
#define XIICPS_SR_TXDV_MASK 0x00000040 /**< Transmit Data Valid Mask */
|
||||
#define XIICPS_SR_RXDV_MASK 0x00000020 /**< Receiver Data Valid Mask */
|
||||
#define XIICPS_SR_RXRW_MASK 0x00000008 /**< Receive read/write Mask */
|
||||
/* @} */
|
||||
|
||||
/** @name IIC Address Register
|
||||
*
|
||||
* Normal addressing mode uses add[6:0]. Extended addressing mode uses add[9:0].
|
||||
* A write access to this register always initiates a transfer if the IIC is in
|
||||
* master mode. Read/Write
|
||||
* @{
|
||||
*/
|
||||
#define XIICPS_ADDR_MASK 0x000003FF /**< IIC Address Mask */
|
||||
/* @} */
|
||||
|
||||
/** @name IIC Data Register
|
||||
*
|
||||
* When written to, the data register sets data to transmit. When read from, the
|
||||
* data register reads the last received byte of data. Read/Write
|
||||
* @{
|
||||
*/
|
||||
#define XIICPS_DATA_MASK 0x000000FF /**< IIC Data Mask */
|
||||
/* @} */
|
||||
|
||||
/** @name IIC Interrupt Registers
|
||||
*
|
||||
* <b>IIC Interrupt Status Register</b>
|
||||
*
|
||||
* This register holds the interrupt status flags for the IIC controller. Some
|
||||
* of the flags are level triggered
|
||||
* - i.e. are set as long as the interrupt condition exists. Other flags are
|
||||
* edge triggered, which means they are set one the interrupt condition occurs
|
||||
* then remain set until they are cleared by software.
|
||||
* The interrupts are cleared by writing a one to the interrupt bit position
|
||||
* in the Interrupt Status Register. Read/Write.
|
||||
*
|
||||
* <b>IIC Interrupt Enable Register</b>
|
||||
*
|
||||
* This register is used to enable interrupt sources for the IIC controller.
|
||||
* Writing a '1' to a bit in this register clears the corresponding bit in the
|
||||
* IIC Interrupt Mask register. Write only.
|
||||
*
|
||||
* <b>IIC Interrupt Disable Register </b>
|
||||
*
|
||||
* This register is used to disable interrupt sources for the IIC controller.
|
||||
* Writing a '1' to a bit in this register sets the corresponding bit in the
|
||||
* IIC Interrupt Mask register. Write only.
|
||||
*
|
||||
* <b>IIC Interrupt Mask Register</b>
|
||||
*
|
||||
* This register shows the enabled/disabled status of each IIC controller
|
||||
* interrupt source. A bit set to 1 will ignore the corresponding interrupt in
|
||||
* the status register. A bit set to 0 means the interrupt is enabled.
|
||||
* All mask bits are set and all interrupts are disabled after reset. 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 Interrupt Status Register
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define XIICPS_IXR_ARB_LOST_MASK 0x00000200 /**< Arbitration Lost Interrupt
|
||||
mask */
|
||||
#define XIICPS_IXR_RX_UNF_MASK 0x00000080 /**< FIFO Recieve Underflow
|
||||
Interrupt mask */
|
||||
#define XIICPS_IXR_TX_OVR_MASK 0x00000040 /**< Transmit Overflow
|
||||
Interrupt mask */
|
||||
#define XIICPS_IXR_RX_OVR_MASK 0x00000020 /**< Receive Overflow Interrupt
|
||||
mask */
|
||||
#define XIICPS_IXR_SLV_RDY_MASK 0x00000010 /**< Monitored Slave Ready
|
||||
Interrupt mask */
|
||||
#define XIICPS_IXR_TO_MASK 0x00000008 /**< Transfer Time Out
|
||||
Interrupt mask */
|
||||
#define XIICPS_IXR_NACK_MASK 0x00000004 /**< NACK Interrupt mask */
|
||||
#define XIICPS_IXR_DATA_MASK 0x00000002 /**< Data Interrupt mask */
|
||||
#define XIICPS_IXR_COMP_MASK 0x00000001 /**< Transfer Complete
|
||||
Interrupt mask */
|
||||
#define XIICPS_IXR_DEFAULT_MASK 0x000002FF /**< Default ISR Mask */
|
||||
#define XIICPS_IXR_ALL_INTR_MASK 0x000002FF /**< All ISR Mask */
|
||||
/* @} */
|
||||
|
||||
|
||||
/** @name IIC Transfer Size Register
|
||||
*
|
||||
* The register's meaning varies according to the operating mode as follows:
|
||||
* - Master transmitter mode: number of data bytes still not transmitted minus
|
||||
* one
|
||||
* - Master receiver mode: number of data bytes that are still expected to be
|
||||
* received
|
||||
* - Slave transmitter mode: number of bytes remaining in the FIFO after the
|
||||
* master terminates the transfer
|
||||
* - Slave receiver mode: number of valid data bytes in the FIFO
|
||||
*
|
||||
* This register is cleared if CLR_FIFO bit in the control register is set.
|
||||
* Read/Write
|
||||
* @{
|
||||
*/
|
||||
#define XIICPS_TRANS_SIZE_MASK 0x0000003F /**< IIC Transfer Size Mask */
|
||||
#define XIICPS_FIFO_DEPTH 16 /**< Number of bytes in the FIFO */
|
||||
#define XIICPS_DATA_INTR_DEPTH 14 /**< Number of bytes at DATA intr */
|
||||
/* @} */
|
||||
|
||||
|
||||
/** @name IIC Slave Monitor Pause Register
|
||||
*
|
||||
* This register is associated with the slave monitor mode of the I2C interface.
|
||||
* It is meaningful only when the module is in master mode and bit SLVMON in the
|
||||
* control register is set.
|
||||
*
|
||||
* This register defines the pause interval between consecutive attempts to
|
||||
* address the slave once a write to an I2C address register is done by the
|
||||
* host. It represents the number of sclk cycles minus one between two attempts.
|
||||
*
|
||||
* The reset value of the register is 0, which results in the master repeatedly
|
||||
* trying to access the slave immediately after unsuccessful attempt.
|
||||
* Read/Write
|
||||
* @{
|
||||
*/
|
||||
#define XIICPS_SLV_PAUSE_MASK 0x0000000F /**< Slave monitor pause mask */
|
||||
/* @} */
|
||||
|
||||
|
||||
/** @name IIC Time Out Register
|
||||
*
|
||||
* The value of time out register represents the time out interval in number of
|
||||
* sclk cycles minus one.
|
||||
*
|
||||
* When the accessed slave holds the sclk line low for longer than the time out
|
||||
* period, thus prohibiting the I2C interface in master mode to complete the
|
||||
* current transfer, an interrupt is generated and TO interrupt flag is set.
|
||||
*
|
||||
* The reset value of the register is 0x1f.
|
||||
* Read/Write
|
||||
* @{
|
||||
*/
|
||||
#define XIICPS_TIME_OUT_MASK 0x000000FF /**< IIC Time Out mask */
|
||||
#define XIICPS_TO_RESET_VALUE 0x000000FF /**< IIC Time Out reset value */
|
||||
/* @} */
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
#define XIicPs_In32 Xil_In32
|
||||
#define XIicPs_Out32 Xil_Out32
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
* Read an IIC register.
|
||||
*
|
||||
* @param BaseAddress contains the base address of the device.
|
||||
* @param RegOffset contains the offset from the 1st register of the
|
||||
* device to select the specific register.
|
||||
*
|
||||
* @return The value read from the register.
|
||||
*
|
||||
* @note C-Style signature:
|
||||
* u32 XIicPs_ReadReg(u32 BaseAddress. int RegOffset)
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIicPs_ReadReg(BaseAddress, RegOffset) \
|
||||
XIicPs_In32((BaseAddress) + (RegOffset))
|
||||
|
||||
/***************************************************************************/
|
||||
/**
|
||||
* Write an IIC register.
|
||||
*
|
||||
* @param BaseAddress contains the base address of the device.
|
||||
* @param RegOffset contains the offset from the 1st register of the
|
||||
* device to select the specific register.
|
||||
* @param RegisterValue is the value to be written to the register.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note C-Style signature:
|
||||
* void XIicPs_WriteReg(u32 BaseAddress, int RegOffset, u32 RegisterValue)
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIicPs_WriteReg(BaseAddress, RegOffset, RegisterValue) \
|
||||
XIicPs_Out32((BaseAddress) + (RegOffset), (RegisterValue))
|
||||
|
||||
/***************************************************************************/
|
||||
/**
|
||||
* Read the interrupt enable register.
|
||||
*
|
||||
* @param BaseAddress contains the base address of the device.
|
||||
*
|
||||
* @return Current bit mask that represents currently enabled interrupts.
|
||||
*
|
||||
* @note C-Style signature:
|
||||
* u32 XIicPs_ReadIER(u32 BaseAddress)
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIicPs_ReadIER(BaseAddress) \
|
||||
XIicPs_ReadReg((BaseAddress), XIICPS_IER_OFFSET)
|
||||
|
||||
/***************************************************************************/
|
||||
/**
|
||||
* Write to the interrupt enable register.
|
||||
*
|
||||
* @param BaseAddress contains the base address of the device.
|
||||
*
|
||||
* @param IntrMask is the interrupts to be enabled.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note C-Style signature:
|
||||
* void XIicPs_EnabledInterrupts(u32 BaseAddress, u32 IntrMask)
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIicPs_EnableInterrupts(BaseAddress, IntrMask) \
|
||||
XIicPs_WriteReg((BaseAddress), XIICPS_IER_OFFSET, (IntrMask))
|
||||
|
||||
/***************************************************************************/
|
||||
/**
|
||||
* Disable all interrupts.
|
||||
*
|
||||
* @param BaseAddress contains the base address of the device.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note C-Style signature:
|
||||
* void XIicPs_DisableAllInterrupts(u32 BaseAddress)
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIicPs_DisableAllInterrupts(BaseAddress) \
|
||||
XIicPs_WriteReg((BaseAddress), XIICPS_IDR_OFFSET, \
|
||||
XIICPS_IXR_ALL_INTR_MASK)
|
||||
|
||||
/***************************************************************************/
|
||||
/**
|
||||
* Disable selected interrupts.
|
||||
*
|
||||
* @param BaseAddress contains the base address of the device.
|
||||
*
|
||||
* @param IntrMask is the interrupts to be disabled.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note C-Style signature:
|
||||
* void XIicPs_DisableInterrupts(u32 BaseAddress, u32 IntrMask)
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIicPs_DisableInterrupts(BaseAddress, IntrMask) \
|
||||
XIicPs_WriteReg((BaseAddress), XIICPS_IDR_OFFSET, \
|
||||
(IntrMask))
|
||||
|
||||
/************************** Variable Definitions *****************************/
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
/*
|
||||
* Perform reset operation to the I2c interface
|
||||
*/
|
||||
void XIicPs_ResetHw(u32 BaseAddr);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* end of protection macro */
|
97
XilinxProcessorIPLib/drivers/iicps/src/xiicps_intr.c
Normal file
97
XilinxProcessorIPLib/drivers/iicps/src/xiicps_intr.c
Normal file
|
@ -0,0 +1,97 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* 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 xiicps_intr.c
|
||||
*
|
||||
* Contains functions of the XIicPs driver for interrupt-driven transfers.
|
||||
* See xiicps.h for a detailed description of the device and driver.
|
||||
*
|
||||
* <pre> MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ------ -------- -----------------------------------------------
|
||||
* 1.00a drg/jz 01/30/10 First release
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
#include "xiicps.h"
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
/************************* Variable Definitions *****************************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function sets the status callback function, the status handler, which the
|
||||
* driver calls when it encounters conditions that should be reported to the
|
||||
* higher layer software. The handler executes in an interrupt context, so
|
||||
* the amount of processing should be minimized
|
||||
*
|
||||
* Refer to the xiicps.h file for a list of the Callback events. The events are
|
||||
* defined to start with XIICPS_EVENT_*.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XIicPs instance.
|
||||
* @param CallBackRef is the upper layer callback reference passed back
|
||||
* when the callback function is invoked.
|
||||
* @param FuncPtr is the pointer to the callback function.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* The handler is called within interrupt context, so it should finish its
|
||||
* work quickly.
|
||||
*
|
||||
******************************************************************************/
|
||||
void XIicPs_SetStatusHandler(XIicPs *InstancePtr, void *CallBackRef,
|
||||
XIicPs_IntrHandler FuncPtr)
|
||||
{
|
||||
Xil_AssertVoid(InstancePtr != NULL);
|
||||
Xil_AssertVoid(FuncPtr != NULL);
|
||||
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
|
||||
InstancePtr->StatusHandler = FuncPtr;
|
||||
InstancePtr->CallBackRef = CallBackRef;
|
||||
}
|
885
XilinxProcessorIPLib/drivers/iicps/src/xiicps_master.c
Normal file
885
XilinxProcessorIPLib/drivers/iicps/src/xiicps_master.c
Normal file
|
@ -0,0 +1,885 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* 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 xiicps_master.c
|
||||
*
|
||||
* Handles master mode transfers.
|
||||
*
|
||||
* <pre> MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- --- -------- ---------------------------------------------
|
||||
* 1.00a jz 01/30/10 First release
|
||||
* 1.00a sdm 09/21/11 Updated the XIicPs_SetupMaster to not check for
|
||||
* Bus Busy condition when the Hold Bit is set.
|
||||
* 1.01a sg 03/30/12 Fixed an issue in XIicPs_MasterSendPolled where a
|
||||
* check for transfer completion is added, which indicates
|
||||
* the completion of current transfer.
|
||||
* 2.0 hk 03/07/14 Added check for error status in the while loop that
|
||||
* checks for completion. CR# 762244, 764875.
|
||||
* 2.1 hk 04/24/14 Fix for CR# 789821 to handle >14 byte transfers.
|
||||
* Fix for CR# 761060 - provision for repeated start.
|
||||
* 2.2 hk 08/23/14 Slave monitor mode changes - clear FIFO, enable
|
||||
* read mode and clear transfer size register.
|
||||
* Disable NACK to avoid interrupts on each retry.
|
||||
* 2.3 sk 10/06/14 Fill transmit fifo before address register when sending.
|
||||
* Replaced XIICPS_DATA_INTR_DEPTH with XIICPS_FIFO_DEPTH.
|
||||
* Repeated start feature removed.
|
||||
* 12/06/14 Implemented Repeated start feature.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
#include "xiicps.h"
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
int TransmitFifoFill(XIicPs *InstancePtr);
|
||||
|
||||
static int XIicPs_SetupMaster(XIicPs *InstancePtr, int Role);
|
||||
static void MasterSendData(XIicPs *InstancePtr);
|
||||
|
||||
/************************* Variable Definitions *****************************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* This function initiates an interrupt-driven send in master mode.
|
||||
*
|
||||
* It tries to send the first FIFO-full of data, then lets the interrupt
|
||||
* handler to handle the rest of the data if there is any.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XIicPs instance.
|
||||
* @param MsgPtr is the pointer to the send buffer.
|
||||
* @param ByteCount is the number of bytes to be sent.
|
||||
* @param SlaveAddr is the address of the slave we are sending to.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note This send routine is for interrupt-driven transfer only.
|
||||
*
|
||||
****************************************************************************/
|
||||
void XIicPs_MasterSend(XIicPs *InstancePtr, u8 *MsgPtr, int ByteCount,
|
||||
u16 SlaveAddr)
|
||||
{
|
||||
u32 BaseAddr;
|
||||
|
||||
/*
|
||||
* Assert validates the input arguments.
|
||||
*/
|
||||
Xil_AssertVoid(InstancePtr != NULL);
|
||||
Xil_AssertVoid(MsgPtr != NULL);
|
||||
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
Xil_AssertVoid(XIICPS_ADDR_MASK >= SlaveAddr);
|
||||
|
||||
|
||||
BaseAddr = InstancePtr->Config.BaseAddress;
|
||||
InstancePtr->SendBufferPtr = MsgPtr;
|
||||
InstancePtr->SendByteCount = ByteCount;
|
||||
InstancePtr->RecvBufferPtr = NULL;
|
||||
InstancePtr->IsSend = 1;
|
||||
|
||||
/*
|
||||
* Set repeated start if sending more than FIFO of data.
|
||||
*/
|
||||
if ((InstancePtr->IsRepeatedStart) ||
|
||||
(ByteCount > XIICPS_FIFO_DEPTH)) {
|
||||
XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET,
|
||||
XIicPs_ReadReg(BaseAddr, XIICPS_CR_OFFSET) |
|
||||
XIICPS_CR_HOLD_MASK);
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup as a master sending role.
|
||||
*/
|
||||
XIicPs_SetupMaster(InstancePtr, SENDING_ROLE);
|
||||
|
||||
TransmitFifoFill(InstancePtr);
|
||||
|
||||
/*
|
||||
* Do the address transfer to notify the slave.
|
||||
*/
|
||||
XIicPs_WriteReg(BaseAddr, XIICPS_ADDR_OFFSET, SlaveAddr);
|
||||
|
||||
XIicPs_EnableInterrupts(BaseAddr,
|
||||
XIICPS_IXR_NACK_MASK | XIICPS_IXR_COMP_MASK |
|
||||
XIICPS_IXR_ARB_LOST_MASK);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* This function initiates an interrupt-driven receive in master mode.
|
||||
*
|
||||
* It sets the transfer size register so the slave can send data to us.
|
||||
* The rest of the work is managed by interrupt handler.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XIicPs instance.
|
||||
* @param MsgPtr is the pointer to the receive buffer.
|
||||
* @param ByteCount is the number of bytes to be received.
|
||||
* @param SlaveAddr is the address of the slave we are receiving from.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note This receive routine is for interrupt-driven transfer only.
|
||||
*
|
||||
****************************************************************************/
|
||||
void XIicPs_MasterRecv(XIicPs *InstancePtr, u8 *MsgPtr, int ByteCount,
|
||||
u16 SlaveAddr)
|
||||
{
|
||||
u32 BaseAddr;
|
||||
|
||||
/*
|
||||
* Assert validates the input arguments.
|
||||
*/
|
||||
Xil_AssertVoid(InstancePtr != NULL);
|
||||
Xil_AssertVoid(MsgPtr != NULL);
|
||||
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
Xil_AssertVoid(XIICPS_ADDR_MASK >= SlaveAddr);
|
||||
|
||||
BaseAddr = InstancePtr->Config.BaseAddress;
|
||||
InstancePtr->RecvBufferPtr = MsgPtr;
|
||||
InstancePtr->RecvByteCount = ByteCount;
|
||||
InstancePtr->CurrByteCount = ByteCount;
|
||||
InstancePtr->SendBufferPtr = NULL;
|
||||
InstancePtr->IsSend = 0;
|
||||
InstancePtr->UpdateTxSize = 0;
|
||||
|
||||
if ((ByteCount > XIICPS_FIFO_DEPTH) ||
|
||||
(InstancePtr->IsRepeatedStart))
|
||||
{
|
||||
XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET,
|
||||
XIicPs_ReadReg(BaseAddr, XIICPS_CR_OFFSET) |
|
||||
XIICPS_CR_HOLD_MASK);
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize for a master receiving role.
|
||||
*/
|
||||
XIicPs_SetupMaster(InstancePtr, RECVING_ROLE);
|
||||
|
||||
/*
|
||||
* Do the address transfer to signal the slave.
|
||||
*/
|
||||
XIicPs_WriteReg(BaseAddr, XIICPS_ADDR_OFFSET, SlaveAddr);
|
||||
|
||||
/*
|
||||
* Setup the transfer size register so the slave knows how much
|
||||
* to send to us.
|
||||
*/
|
||||
if (ByteCount > XIICPS_MAX_TRANSFER_SIZE) {
|
||||
XIicPs_WriteReg(BaseAddr, XIICPS_TRANS_SIZE_OFFSET,
|
||||
XIICPS_MAX_TRANSFER_SIZE);
|
||||
InstancePtr->CurrByteCount = XIICPS_MAX_TRANSFER_SIZE;
|
||||
InstancePtr->UpdateTxSize = 1;
|
||||
}else {
|
||||
XIicPs_WriteReg(BaseAddr, XIICPS_TRANS_SIZE_OFFSET,
|
||||
ByteCount);
|
||||
}
|
||||
|
||||
XIicPs_EnableInterrupts(BaseAddr,
|
||||
XIICPS_IXR_NACK_MASK | XIICPS_IXR_DATA_MASK |
|
||||
XIICPS_IXR_RX_OVR_MASK | XIICPS_IXR_COMP_MASK |
|
||||
XIICPS_IXR_ARB_LOST_MASK);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* This function initiates a polled mode send in master mode.
|
||||
*
|
||||
* It sends data to the FIFO and waits for the slave to pick them up.
|
||||
* If slave fails to remove data from FIFO, the send fails with
|
||||
* time out.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XIicPs instance.
|
||||
* @param MsgPtr is the pointer to the send buffer.
|
||||
* @param ByteCount is the number of bytes to be sent.
|
||||
* @param SlaveAddr is the address of the slave we are sending to.
|
||||
*
|
||||
* @return
|
||||
* - XST_SUCCESS if everything went well.
|
||||
* - XST_FAILURE if timed out.
|
||||
*
|
||||
* @note This send routine is for polled mode transfer only.
|
||||
*
|
||||
****************************************************************************/
|
||||
int XIicPs_MasterSendPolled(XIicPs *InstancePtr, u8 *MsgPtr,
|
||||
int ByteCount, u16 SlaveAddr)
|
||||
{
|
||||
u32 IntrStatusReg;
|
||||
u32 StatusReg;
|
||||
u32 BaseAddr;
|
||||
u32 Intrs;
|
||||
|
||||
/*
|
||||
* Assert validates the input arguments.
|
||||
*/
|
||||
Xil_AssertNonvoid(InstancePtr != NULL);
|
||||
Xil_AssertNonvoid(MsgPtr != NULL);
|
||||
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
Xil_AssertNonvoid(XIICPS_ADDR_MASK >= SlaveAddr);
|
||||
|
||||
BaseAddr = InstancePtr->Config.BaseAddress;
|
||||
InstancePtr->SendBufferPtr = MsgPtr;
|
||||
InstancePtr->SendByteCount = ByteCount;
|
||||
|
||||
if ((InstancePtr->IsRepeatedStart) ||
|
||||
(ByteCount > XIICPS_FIFO_DEPTH)) {
|
||||
XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET,
|
||||
XIicPs_ReadReg(BaseAddr, XIICPS_CR_OFFSET) |
|
||||
XIICPS_CR_HOLD_MASK);
|
||||
}
|
||||
|
||||
XIicPs_SetupMaster(InstancePtr, SENDING_ROLE);
|
||||
|
||||
/*
|
||||
* Intrs keeps all the error-related interrupts.
|
||||
*/
|
||||
Intrs = XIICPS_IXR_ARB_LOST_MASK | XIICPS_IXR_TX_OVR_MASK |
|
||||
XIICPS_IXR_NACK_MASK;
|
||||
|
||||
/*
|
||||
* Clear the interrupt status register before use it to monitor.
|
||||
*/
|
||||
IntrStatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_ISR_OFFSET);
|
||||
XIicPs_WriteReg(BaseAddr, XIICPS_ISR_OFFSET, IntrStatusReg);
|
||||
|
||||
/*
|
||||
* Transmit first FIFO full of data.
|
||||
*/
|
||||
TransmitFifoFill(InstancePtr);
|
||||
|
||||
XIicPs_WriteReg(BaseAddr, XIICPS_ADDR_OFFSET, SlaveAddr);
|
||||
|
||||
IntrStatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_ISR_OFFSET);
|
||||
|
||||
/*
|
||||
* Continue sending as long as there is more data and
|
||||
* there are no errors.
|
||||
*/
|
||||
while ((InstancePtr->SendByteCount > 0) &&
|
||||
((IntrStatusReg & Intrs) == 0)) {
|
||||
StatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_SR_OFFSET);
|
||||
|
||||
/*
|
||||
* Wait until transmit FIFO is empty.
|
||||
*/
|
||||
if ((StatusReg & XIICPS_SR_TXDV_MASK) != 0) {
|
||||
IntrStatusReg = XIicPs_ReadReg(BaseAddr,
|
||||
XIICPS_ISR_OFFSET);
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Send more data out through transmit FIFO.
|
||||
*/
|
||||
TransmitFifoFill(InstancePtr);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check for completion of transfer.
|
||||
*/
|
||||
while ((IntrStatusReg & XIICPS_IXR_COMP_MASK) != XIICPS_IXR_COMP_MASK){
|
||||
|
||||
IntrStatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_ISR_OFFSET);
|
||||
/*
|
||||
* If there is an error, tell the caller.
|
||||
*/
|
||||
if ((IntrStatusReg & Intrs) != 0) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(InstancePtr->IsRepeatedStart)) {
|
||||
XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET,
|
||||
XIicPs_ReadReg(BaseAddr,XIICPS_CR_OFFSET) &
|
||||
(~XIICPS_CR_HOLD_MASK));
|
||||
}
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* This function initiates a polled mode receive in master mode.
|
||||
*
|
||||
* It repeatedly sets the transfer size register so the slave can
|
||||
* send data to us. It polls the data register for data to come in.
|
||||
* If slave fails to send us data, it fails with time out.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XIicPs instance.
|
||||
* @param MsgPtr is the pointer to the receive buffer.
|
||||
* @param ByteCount is the number of bytes to be received.
|
||||
* @param SlaveAddr is the address of the slave we are receiving from.
|
||||
*
|
||||
* @return
|
||||
* - XST_SUCCESS if everything went well.
|
||||
* - XST_FAILURE if timed out.
|
||||
*
|
||||
* @note This receive routine is for polled mode transfer only.
|
||||
*
|
||||
****************************************************************************/
|
||||
int XIicPs_MasterRecvPolled(XIicPs *InstancePtr, u8 *MsgPtr,
|
||||
int ByteCount, u16 SlaveAddr)
|
||||
{
|
||||
u32 IntrStatusReg;
|
||||
u32 Intrs;
|
||||
u32 StatusReg;
|
||||
u32 BaseAddr;
|
||||
int IsHold = 0;
|
||||
int UpdateTxSize = 0;
|
||||
|
||||
/*
|
||||
* Assert validates the input arguments.
|
||||
*/
|
||||
Xil_AssertNonvoid(InstancePtr != NULL);
|
||||
Xil_AssertNonvoid(MsgPtr != NULL);
|
||||
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
Xil_AssertNonvoid(XIICPS_ADDR_MASK >= SlaveAddr);
|
||||
|
||||
BaseAddr = InstancePtr->Config.BaseAddress;
|
||||
InstancePtr->RecvBufferPtr = MsgPtr;
|
||||
InstancePtr->RecvByteCount = ByteCount;
|
||||
|
||||
if((ByteCount > XIICPS_FIFO_DEPTH) ||
|
||||
(InstancePtr->IsRepeatedStart))
|
||||
{
|
||||
XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET,
|
||||
XIicPs_ReadReg(BaseAddr, XIICPS_CR_OFFSET) |
|
||||
XIICPS_CR_HOLD_MASK);
|
||||
IsHold = 1;
|
||||
}
|
||||
|
||||
XIicPs_SetupMaster(InstancePtr, RECVING_ROLE);
|
||||
|
||||
/*
|
||||
* Clear the interrupt status register before use it to monitor.
|
||||
*/
|
||||
IntrStatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_ISR_OFFSET);
|
||||
XIicPs_WriteReg(BaseAddr, XIICPS_ISR_OFFSET, IntrStatusReg);
|
||||
|
||||
XIicPs_WriteReg(BaseAddr, XIICPS_ADDR_OFFSET, SlaveAddr);
|
||||
|
||||
/*
|
||||
* Set up the transfer size register so the slave knows how much
|
||||
* to send to us.
|
||||
*/
|
||||
if (ByteCount > XIICPS_MAX_TRANSFER_SIZE) {
|
||||
XIicPs_WriteReg(BaseAddr, XIICPS_TRANS_SIZE_OFFSET,
|
||||
XIICPS_MAX_TRANSFER_SIZE);
|
||||
ByteCount = XIICPS_MAX_TRANSFER_SIZE;
|
||||
UpdateTxSize = 1;
|
||||
}else {
|
||||
XIicPs_WriteReg(BaseAddr, XIICPS_TRANS_SIZE_OFFSET,
|
||||
ByteCount);
|
||||
}
|
||||
|
||||
/*
|
||||
* Intrs keeps all the error-related interrupts.
|
||||
*/
|
||||
Intrs = XIICPS_IXR_ARB_LOST_MASK | XIICPS_IXR_RX_OVR_MASK |
|
||||
XIICPS_IXR_RX_UNF_MASK | XIICPS_IXR_NACK_MASK;
|
||||
|
||||
/*
|
||||
* Poll the interrupt status register to find the errors.
|
||||
*/
|
||||
IntrStatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_ISR_OFFSET);
|
||||
while ((InstancePtr->RecvByteCount > 0) &&
|
||||
((IntrStatusReg & Intrs) == 0)) {
|
||||
StatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_SR_OFFSET);
|
||||
|
||||
while (StatusReg & XIICPS_SR_RXDV_MASK) {
|
||||
if ((InstancePtr->RecvByteCount <
|
||||
XIICPS_DATA_INTR_DEPTH) && IsHold &&
|
||||
(!(InstancePtr->IsRepeatedStart))) {
|
||||
IsHold = 0;
|
||||
XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET,
|
||||
XIicPs_ReadReg(BaseAddr,
|
||||
XIICPS_CR_OFFSET) &
|
||||
(~XIICPS_CR_HOLD_MASK));
|
||||
}
|
||||
XIicPs_RecvByte(InstancePtr);
|
||||
ByteCount --;
|
||||
|
||||
if (UpdateTxSize &&
|
||||
(ByteCount == XIICPS_FIFO_DEPTH + 1))
|
||||
break;
|
||||
|
||||
StatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_SR_OFFSET);
|
||||
}
|
||||
|
||||
if (UpdateTxSize && (ByteCount == XIICPS_FIFO_DEPTH + 1)) {
|
||||
/*
|
||||
* wait while fifo is full
|
||||
*/
|
||||
while(XIicPs_ReadReg(BaseAddr,
|
||||
XIICPS_TRANS_SIZE_OFFSET) !=
|
||||
(ByteCount - XIICPS_FIFO_DEPTH));
|
||||
|
||||
if ((InstancePtr->RecvByteCount - XIICPS_FIFO_DEPTH) >
|
||||
XIICPS_MAX_TRANSFER_SIZE) {
|
||||
|
||||
XIicPs_WriteReg(BaseAddr,
|
||||
XIICPS_TRANS_SIZE_OFFSET,
|
||||
XIICPS_MAX_TRANSFER_SIZE);
|
||||
ByteCount = XIICPS_MAX_TRANSFER_SIZE +
|
||||
XIICPS_FIFO_DEPTH;
|
||||
}else {
|
||||
XIicPs_WriteReg(BaseAddr,
|
||||
XIICPS_TRANS_SIZE_OFFSET,
|
||||
InstancePtr->RecvByteCount -
|
||||
XIICPS_FIFO_DEPTH);
|
||||
UpdateTxSize = 0;
|
||||
ByteCount = InstancePtr->RecvByteCount;
|
||||
}
|
||||
}
|
||||
|
||||
IntrStatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_ISR_OFFSET);
|
||||
}
|
||||
|
||||
if (!(InstancePtr->IsRepeatedStart)) {
|
||||
XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET,
|
||||
XIicPs_ReadReg(BaseAddr,XIICPS_CR_OFFSET) &
|
||||
(~XIICPS_CR_HOLD_MASK));
|
||||
}
|
||||
|
||||
if (IntrStatusReg & Intrs) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* This function enables the slave monitor mode.
|
||||
*
|
||||
* It enables slave monitor in the control register and enables
|
||||
* slave ready interrupt. It then does an address transfer to slave.
|
||||
* Interrupt handler will signal the caller if slave responds to
|
||||
* the address transfer.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XIicPs instance.
|
||||
* @param SlaveAddr is the address of the slave we want to contact.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
****************************************************************************/
|
||||
void XIicPs_EnableSlaveMonitor(XIicPs *InstancePtr, u16 SlaveAddr)
|
||||
{
|
||||
u32 BaseAddr;
|
||||
u32 ConfigReg;
|
||||
|
||||
Xil_AssertVoid(InstancePtr != NULL);
|
||||
|
||||
BaseAddr = InstancePtr->Config.BaseAddress;
|
||||
|
||||
/* Clear transfer size register */
|
||||
XIicPs_WriteReg(BaseAddr, XIICPS_TRANS_SIZE_OFFSET, 0x0);
|
||||
|
||||
/*
|
||||
* Enable slave monitor mode in control register.
|
||||
*/
|
||||
ConfigReg = XIicPs_ReadReg(BaseAddr, XIICPS_CR_OFFSET);
|
||||
ConfigReg |= XIICPS_CR_MS_MASK | XIICPS_CR_NEA_MASK |
|
||||
XIICPS_CR_CLR_FIFO_MASK | XIICPS_CR_SLVMON_MASK;
|
||||
ConfigReg &= ~XIICPS_CR_RD_WR_MASK;
|
||||
|
||||
XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET, ConfigReg);
|
||||
|
||||
/*
|
||||
* Set up interrupt flag for slave monitor interrupt.
|
||||
* Dont enable NACK.
|
||||
*/
|
||||
XIicPs_EnableInterrupts(BaseAddr, XIICPS_IXR_SLV_RDY_MASK);
|
||||
|
||||
/*
|
||||
* Initialize the slave monitor register.
|
||||
*/
|
||||
XIicPs_WriteReg(BaseAddr, XIICPS_SLV_PAUSE_OFFSET, 0xF);
|
||||
|
||||
/*
|
||||
* Set the slave address to start the slave address transmission.
|
||||
*/
|
||||
XIicPs_WriteReg(BaseAddr, XIICPS_ADDR_OFFSET, SlaveAddr);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* This function disables slave monitor mode.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XIicPs instance.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
****************************************************************************/
|
||||
void XIicPs_DisableSlaveMonitor(XIicPs *InstancePtr)
|
||||
{
|
||||
u32 BaseAddr;
|
||||
|
||||
Xil_AssertVoid(InstancePtr != NULL);
|
||||
|
||||
BaseAddr = InstancePtr->Config.BaseAddress;
|
||||
|
||||
/*
|
||||
* Clear slave monitor control bit.
|
||||
*/
|
||||
XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET,
|
||||
XIicPs_ReadReg(BaseAddr, XIICPS_CR_OFFSET)
|
||||
& (~XIICPS_CR_SLVMON_MASK));
|
||||
|
||||
/*
|
||||
* Clear interrupt flag for slave monitor interrupt.
|
||||
*/
|
||||
XIicPs_DisableInterrupts(BaseAddr, XIICPS_IXR_SLV_RDY_MASK);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* The interrupt handler for the master mode. It does the protocol handling for
|
||||
* the interrupt-driven transfers.
|
||||
*
|
||||
* Completion events and errors are signaled to upper layer for proper handling.
|
||||
*
|
||||
* <pre>
|
||||
* The interrupts that are handled are:
|
||||
* - DATA
|
||||
* This case is handled only for master receive data.
|
||||
* The master has to request for more data (if there is more data to
|
||||
* receive) and read the data from the FIFO .
|
||||
*
|
||||
* - COMP
|
||||
* If the Master is transmitting data and there is more data to be
|
||||
* sent then the data is written to the FIFO. If there is no more data to
|
||||
* be transmitted then a completion event is signalled to the upper layer
|
||||
* by calling the callback handler.
|
||||
*
|
||||
* If the Master is receiving data then the data is read from the FIFO and
|
||||
* the Master has to request for more data (if there is more data to
|
||||
* receive). If all the data has been received then a completion event
|
||||
* is signalled to the upper layer by calling the callback handler.
|
||||
* It is an error if the amount of received data is more than expected.
|
||||
*
|
||||
* - NAK and SLAVE_RDY
|
||||
* This is signalled to the upper layer by calling the callback handler.
|
||||
*
|
||||
* - All Other interrupts
|
||||
* These interrupts are marked as error. This is signalled to the upper
|
||||
* layer by calling the callback handler.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XIicPs instance.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
****************************************************************************/
|
||||
void XIicPs_MasterInterruptHandler(XIicPs *InstancePtr)
|
||||
{
|
||||
u32 IntrStatusReg;
|
||||
u32 StatusEvent = 0;
|
||||
u32 BaseAddr;
|
||||
int ByteCnt;
|
||||
int IsHold;
|
||||
|
||||
/*
|
||||
* Assert validates the input arguments.
|
||||
*/
|
||||
Xil_AssertVoid(InstancePtr != NULL);
|
||||
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
|
||||
BaseAddr = InstancePtr->Config.BaseAddress;
|
||||
|
||||
/*
|
||||
* Read the Interrupt status register.
|
||||
*/
|
||||
IntrStatusReg = XIicPs_ReadReg(BaseAddr,
|
||||
XIICPS_ISR_OFFSET);
|
||||
|
||||
/*
|
||||
* Write the status back to clear the interrupts so no events are
|
||||
* missed while processing this interrupt.
|
||||
*/
|
||||
XIicPs_WriteReg(BaseAddr, XIICPS_ISR_OFFSET, IntrStatusReg);
|
||||
|
||||
/*
|
||||
* Use the Mask register AND with the Interrupt Status register so
|
||||
* disabled interrupts are not processed.
|
||||
*/
|
||||
IntrStatusReg &= ~(XIicPs_ReadReg(BaseAddr, XIICPS_IMR_OFFSET));
|
||||
|
||||
ByteCnt = InstancePtr->CurrByteCount;
|
||||
|
||||
IsHold = 0;
|
||||
if (XIicPs_ReadReg(BaseAddr, XIICPS_CR_OFFSET) & XIICPS_CR_HOLD_MASK) {
|
||||
IsHold = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Send
|
||||
*/
|
||||
if ((InstancePtr->IsSend) &&
|
||||
(0 != (IntrStatusReg & XIICPS_IXR_COMP_MASK))) {
|
||||
if (InstancePtr->SendByteCount > 0) {
|
||||
MasterSendData(InstancePtr);
|
||||
} else {
|
||||
StatusEvent |= XIICPS_EVENT_COMPLETE_SEND;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Receive
|
||||
*/
|
||||
if ((!(InstancePtr->IsSend)) &&
|
||||
((0 != (IntrStatusReg & XIICPS_IXR_DATA_MASK)) ||
|
||||
(0 != (IntrStatusReg & XIICPS_IXR_COMP_MASK)))){
|
||||
|
||||
while (XIicPs_ReadReg(BaseAddr, XIICPS_SR_OFFSET) &
|
||||
XIICPS_SR_RXDV_MASK) {
|
||||
if ((InstancePtr->RecvByteCount <
|
||||
XIICPS_DATA_INTR_DEPTH) && IsHold &&
|
||||
(!(InstancePtr->IsRepeatedStart))) {
|
||||
IsHold = 0;
|
||||
XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET,
|
||||
XIicPs_ReadReg(BaseAddr,
|
||||
XIICPS_CR_OFFSET) &
|
||||
(~XIICPS_CR_HOLD_MASK));
|
||||
}
|
||||
XIicPs_RecvByte(InstancePtr);
|
||||
ByteCnt--;
|
||||
|
||||
if (InstancePtr->UpdateTxSize &&
|
||||
(ByteCnt == XIICPS_FIFO_DEPTH + 1))
|
||||
break;
|
||||
}
|
||||
|
||||
if (InstancePtr->UpdateTxSize &&
|
||||
(ByteCnt == XIICPS_FIFO_DEPTH + 1)) {
|
||||
/*
|
||||
* wait while fifo is full
|
||||
*/
|
||||
while(XIicPs_ReadReg(BaseAddr,
|
||||
XIICPS_TRANS_SIZE_OFFSET) !=
|
||||
(ByteCnt - XIICPS_FIFO_DEPTH));
|
||||
|
||||
if ((InstancePtr->RecvByteCount - XIICPS_FIFO_DEPTH) >
|
||||
XIICPS_MAX_TRANSFER_SIZE) {
|
||||
|
||||
XIicPs_WriteReg(BaseAddr,
|
||||
XIICPS_TRANS_SIZE_OFFSET,
|
||||
XIICPS_MAX_TRANSFER_SIZE);
|
||||
ByteCnt = XIICPS_MAX_TRANSFER_SIZE +
|
||||
XIICPS_FIFO_DEPTH;
|
||||
}else {
|
||||
XIicPs_WriteReg(BaseAddr,
|
||||
XIICPS_TRANS_SIZE_OFFSET,
|
||||
InstancePtr->RecvByteCount -
|
||||
XIICPS_FIFO_DEPTH);
|
||||
InstancePtr->UpdateTxSize = 0;
|
||||
ByteCnt = InstancePtr->RecvByteCount;
|
||||
}
|
||||
}
|
||||
InstancePtr->CurrByteCount = ByteCnt;
|
||||
}
|
||||
|
||||
if ((!(InstancePtr->IsSend)) &&
|
||||
(0 != (IntrStatusReg & XIICPS_IXR_COMP_MASK))) {
|
||||
/*
|
||||
* If all done, tell the application.
|
||||
*/
|
||||
if (InstancePtr->RecvByteCount == 0){
|
||||
if (!(InstancePtr->IsRepeatedStart)) {
|
||||
XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET,
|
||||
XIicPs_ReadReg(BaseAddr,
|
||||
XIICPS_CR_OFFSET) &
|
||||
(~XIICPS_CR_HOLD_MASK));
|
||||
}
|
||||
StatusEvent |= XIICPS_EVENT_COMPLETE_RECV;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Slave ready interrupt, it is only meaningful for master mode.
|
||||
*/
|
||||
if (0 != (IntrStatusReg & XIICPS_IXR_SLV_RDY_MASK)) {
|
||||
StatusEvent |= XIICPS_EVENT_SLAVE_RDY;
|
||||
}
|
||||
|
||||
if (0 != (IntrStatusReg & XIICPS_IXR_NACK_MASK)) {
|
||||
if (!(InstancePtr->IsRepeatedStart)) {
|
||||
XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET,
|
||||
XIicPs_ReadReg(BaseAddr,
|
||||
XIICPS_CR_OFFSET) &
|
||||
(~XIICPS_CR_HOLD_MASK));
|
||||
}
|
||||
StatusEvent |= XIICPS_EVENT_NACK;
|
||||
}
|
||||
|
||||
/*
|
||||
* All other interrupts are treated as error.
|
||||
*/
|
||||
if (0 != (IntrStatusReg & (XIICPS_IXR_NACK_MASK |
|
||||
XIICPS_IXR_ARB_LOST_MASK | XIICPS_IXR_RX_UNF_MASK |
|
||||
XIICPS_IXR_TX_OVR_MASK | XIICPS_IXR_RX_OVR_MASK))) {
|
||||
if (!(InstancePtr->IsRepeatedStart)) {
|
||||
XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET,
|
||||
XIicPs_ReadReg(BaseAddr,
|
||||
XIICPS_CR_OFFSET) &
|
||||
(~XIICPS_CR_HOLD_MASK));
|
||||
}
|
||||
StatusEvent |= XIICPS_EVENT_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Signal application if there are any events.
|
||||
*/
|
||||
if (0 != StatusEvent) {
|
||||
InstancePtr->StatusHandler(InstancePtr->CallBackRef,
|
||||
StatusEvent);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/*
|
||||
* This function prepares a device to transfers as a master.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XIicPs instance.
|
||||
*
|
||||
* @param Role specifies whether the device is sending or receiving.
|
||||
*
|
||||
* @return
|
||||
* - XST_SUCCESS if everything went well.
|
||||
* - XST_FAILURE if bus is busy.
|
||||
*
|
||||
* @note Interrupts are always disabled, device which needs to use
|
||||
* interrupts needs to setup interrupts after this call.
|
||||
*
|
||||
****************************************************************************/
|
||||
static int XIicPs_SetupMaster(XIicPs *InstancePtr, int Role)
|
||||
{
|
||||
u32 ControlReg;
|
||||
u32 BaseAddr;
|
||||
u32 EnabledIntr = 0x0;
|
||||
|
||||
Xil_AssertNonvoid(InstancePtr != NULL);
|
||||
|
||||
BaseAddr = InstancePtr->Config.BaseAddress;
|
||||
ControlReg = XIicPs_ReadReg(BaseAddr, XIICPS_CR_OFFSET);
|
||||
|
||||
|
||||
/*
|
||||
* Only check if bus is busy when repeated start option is not set.
|
||||
*/
|
||||
if ((ControlReg & XIICPS_CR_HOLD_MASK) == 0) {
|
||||
if (XIicPs_BusIsBusy(InstancePtr)) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Set up master, AckEn, nea and also clear fifo.
|
||||
*/
|
||||
ControlReg |= XIICPS_CR_ACKEN_MASK | XIICPS_CR_CLR_FIFO_MASK |
|
||||
XIICPS_CR_NEA_MASK | XIICPS_CR_MS_MASK;
|
||||
|
||||
if (Role == RECVING_ROLE) {
|
||||
ControlReg |= XIICPS_CR_RD_WR_MASK;
|
||||
EnabledIntr = XIICPS_IXR_DATA_MASK |XIICPS_IXR_RX_OVR_MASK;
|
||||
}else {
|
||||
ControlReg &= ~XIICPS_CR_RD_WR_MASK;
|
||||
}
|
||||
EnabledIntr |= XIICPS_IXR_COMP_MASK | XIICPS_IXR_ARB_LOST_MASK;
|
||||
|
||||
XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET, ControlReg);
|
||||
|
||||
XIicPs_DisableAllInterrupts(BaseAddr);
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/*
|
||||
* This function handles continuation of sending data. It is invoked
|
||||
* from interrupt handler.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XIicPs instance.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
****************************************************************************/
|
||||
static void MasterSendData(XIicPs *InstancePtr)
|
||||
{
|
||||
TransmitFifoFill(InstancePtr);
|
||||
|
||||
/*
|
||||
* Clear hold bit if done, so stop can be sent out.
|
||||
*/
|
||||
if (InstancePtr->SendByteCount == 0) {
|
||||
|
||||
/*
|
||||
* If user has enabled repeated start as an option,
|
||||
* do not disable it.
|
||||
*/
|
||||
if (!(InstancePtr->IsRepeatedStart)) {
|
||||
|
||||
XIicPs_WriteReg(InstancePtr->Config.BaseAddress,
|
||||
XIICPS_CR_OFFSET,
|
||||
XIicPs_ReadReg(InstancePtr->Config.BaseAddress,
|
||||
XIICPS_CR_OFFSET) & ~ XIICPS_CR_HOLD_MASK);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
487
XilinxProcessorIPLib/drivers/iicps/src/xiicps_options.c
Normal file
487
XilinxProcessorIPLib/drivers/iicps/src/xiicps_options.c
Normal file
|
@ -0,0 +1,487 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* 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 xiicps_options.c
|
||||
*
|
||||
* Contains functions for the configuration of the XIccPs driver.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ------ -------- -----------------------------------------------
|
||||
* 1.00a drg/jz 01/30/10 First release
|
||||
* 1.02a sg 08/29/12 Updated the logic to arrive at the best divisors
|
||||
* to achieve I2C clock with minimum error.
|
||||
* This is a fix for CR #674195
|
||||
* 1.03a hk 05/04/13 Initialized BestDivA and BestDivB to 0.
|
||||
* This is fix for CR#704398 to remove warning.
|
||||
* 2.0 hk 03/07/14 Limited frequency set when 100KHz or 400KHz is
|
||||
* selected. This is a hardware limitation. CR#779290.
|
||||
* 2.1 hk 04/24/14 Fix for CR# 761060 - provision for repeated start.
|
||||
* 2.3 sk 10/07/14 Repeated start feature removed.
|
||||
* 2.4 sk 12/06/14 Implemented Repeated start feature.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
#include "xiicps.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[] = {
|
||||
{XIICPS_7_BIT_ADDR_OPTION, XIICPS_CR_NEA_MASK},
|
||||
{XIICPS_10_BIT_ADDR_OPTION, XIICPS_CR_NEA_MASK},
|
||||
{XIICPS_SLAVE_MON_OPTION, XIICPS_CR_SLVMON_MASK},
|
||||
{XIICPS_REP_START_OPTION, XIICPS_CR_HOLD_MASK},
|
||||
};
|
||||
|
||||
#define XIICPS_NUM_OPTIONS (sizeof(OptionsTable) / sizeof(OptionsMap))
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function sets the options for the IIC device driver. The options control
|
||||
* how the device behaves relative to the IIC bus. The device must be idle
|
||||
* rather than busy transferring data before setting these device options.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XIicPs instance.
|
||||
* @param Options contains the specified options to be set. This is a bit
|
||||
* mask where a 1 means to turn the option on. One or more bit
|
||||
* values may be contained in the mask. See the bit definitions
|
||||
* named XIICPS_*_OPTION in xiicps.h.
|
||||
*
|
||||
* @return
|
||||
* - XST_SUCCESS if options are successfully set.
|
||||
* - XST_DEVICE_IS_STARTED if the device is currently transferring
|
||||
* data. The transfer must complete or be aborted before setting
|
||||
* options.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
int XIicPs_SetOptions(XIicPs *InstancePtr, u32 Options)
|
||||
{
|
||||
u32 ControlReg;
|
||||
unsigned int Index;
|
||||
|
||||
Xil_AssertNonvoid(InstancePtr != NULL);
|
||||
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
|
||||
ControlReg = XIicPs_ReadReg(InstancePtr->Config.BaseAddress,
|
||||
XIICPS_CR_OFFSET);
|
||||
|
||||
/*
|
||||
* If repeated start option is requested, set the flag.
|
||||
* The hold bit in CR will be written by driver when the next transfer
|
||||
* is initiated.
|
||||
*/
|
||||
if (Options & XIICPS_REP_START_OPTION) {
|
||||
InstancePtr->IsRepeatedStart = 1;
|
||||
Options = Options & (~XIICPS_REP_START_OPTION);
|
||||
}
|
||||
|
||||
/*
|
||||
* Loop through the options table, turning the option on.
|
||||
*/
|
||||
for (Index = 0; Index < XIICPS_NUM_OPTIONS; Index++) {
|
||||
if (Options & OptionsTable[Index].Option) {
|
||||
/*
|
||||
* 10-bit option is specially treated, because it is
|
||||
* using the 7-bit option, so turning it on means
|
||||
* turning 7-bit option off.
|
||||
*/
|
||||
if (OptionsTable[Index].Option &
|
||||
XIICPS_10_BIT_ADDR_OPTION) {
|
||||
/* Turn 7-bit off */
|
||||
ControlReg &= ~OptionsTable[Index].Mask;
|
||||
} else {
|
||||
/* Turn 7-bit on */
|
||||
ControlReg |= OptionsTable[Index].Mask;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Now write to the control register. Leave it to the upper layers
|
||||
* to restart the device.
|
||||
*/
|
||||
XIicPs_WriteReg(InstancePtr->Config.BaseAddress, XIICPS_CR_OFFSET,
|
||||
ControlReg);
|
||||
|
||||
/*
|
||||
* Keep a copy of what options this instance has.
|
||||
*/
|
||||
InstancePtr->Options = XIicPs_GetOptions(InstancePtr);
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function clears the options for the IIC device driver. The options
|
||||
* control how the device behaves relative to the IIC bus. The device must be
|
||||
* idle rather than busy transferring data before setting these device options.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XIicPs instance.
|
||||
* @param Options contains the specified options to be cleared. This is a
|
||||
* bit mask where a 1 means to turn the option off. One or more bit
|
||||
* values may be contained in the mask. See the bit definitions
|
||||
* named XIICPS_*_OPTION in xiicps.h.
|
||||
*
|
||||
* @return
|
||||
* - XST_SUCCESS if options are successfully set.
|
||||
* - XST_DEVICE_IS_STARTED if the device is currently transferring
|
||||
* data. The transfer must complete or be aborted before setting
|
||||
* options.
|
||||
*
|
||||
* @note None
|
||||
*
|
||||
******************************************************************************/
|
||||
int XIicPs_ClearOptions(XIicPs *InstancePtr, u32 Options)
|
||||
{
|
||||
u32 ControlReg;
|
||||
unsigned int Index;
|
||||
|
||||
Xil_AssertNonvoid(InstancePtr != NULL);
|
||||
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
|
||||
ControlReg = XIicPs_ReadReg(InstancePtr->Config.BaseAddress,
|
||||
XIICPS_CR_OFFSET);
|
||||
|
||||
/*
|
||||
* If repeated start option is cleared, set the flag.
|
||||
* The hold bit in CR will be cleared by driver when the
|
||||
* following transfer ends.
|
||||
*/
|
||||
if (Options & XIICPS_REP_START_OPTION) {
|
||||
InstancePtr->IsRepeatedStart = 0;
|
||||
Options = Options & (~XIICPS_REP_START_OPTION);
|
||||
}
|
||||
|
||||
/*
|
||||
* Loop through the options table and clear the specified options.
|
||||
*/
|
||||
for (Index = 0; Index < XIICPS_NUM_OPTIONS; Index++) {
|
||||
if (Options & OptionsTable[Index].Option) {
|
||||
|
||||
/*
|
||||
* 10-bit option is specially treated, because it is
|
||||
* using the 7-bit option, so clearing it means turning
|
||||
* 7-bit option on.
|
||||
*/
|
||||
if (OptionsTable[Index].Option &
|
||||
XIICPS_10_BIT_ADDR_OPTION) {
|
||||
|
||||
/* Turn 7-bit on */
|
||||
ControlReg |= OptionsTable[Index].Mask;
|
||||
} else {
|
||||
|
||||
/* Turn 7-bit off */
|
||||
ControlReg &= ~OptionsTable[Index].Mask;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Now write the control register. Leave it to the upper layers
|
||||
* to restart the device.
|
||||
*/
|
||||
XIicPs_WriteReg(InstancePtr->Config.BaseAddress, XIICPS_CR_OFFSET,
|
||||
ControlReg);
|
||||
|
||||
/*
|
||||
* Keep a copy of what options this instance has.
|
||||
*/
|
||||
InstancePtr->Options = XIicPs_GetOptions(InstancePtr);
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function gets the options for the IIC device. The options control how
|
||||
* the device behaves relative to the IIC bus.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XIicPs instance.
|
||||
*
|
||||
* @return 32 bit mask of the options, where a 1 means the option is on,
|
||||
* and a 0 means to the option is off. One or more bit values may
|
||||
* be contained in the mask. See the bit definitions named
|
||||
* XIICPS_*_OPTION in the file xiicps.h.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
u32 XIicPs_GetOptions(XIicPs *InstancePtr)
|
||||
{
|
||||
u32 OptionsFlag = 0;
|
||||
u32 ControlReg;
|
||||
unsigned int Index;
|
||||
|
||||
Xil_AssertNonvoid(InstancePtr != NULL);
|
||||
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
|
||||
/*
|
||||
* Read control register to find which options are currently set.
|
||||
*/
|
||||
ControlReg = XIicPs_ReadReg(InstancePtr->Config.BaseAddress,
|
||||
XIICPS_CR_OFFSET);
|
||||
|
||||
/*
|
||||
* Loop through the options table to determine which options are set.
|
||||
*/
|
||||
for (Index = 0; Index < XIICPS_NUM_OPTIONS; Index++) {
|
||||
if (ControlReg & OptionsTable[Index].Mask) {
|
||||
OptionsFlag |= OptionsTable[Index].Option;
|
||||
}
|
||||
if ((ControlReg & XIICPS_CR_NEA_MASK) == 0) {
|
||||
OptionsFlag |= XIICPS_10_BIT_ADDR_OPTION;
|
||||
}
|
||||
}
|
||||
|
||||
if (InstancePtr->IsRepeatedStart) {
|
||||
OptionsFlag |= XIICPS_REP_START_OPTION;
|
||||
}
|
||||
return OptionsFlag;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function sets the serial clock rate for the IIC device. The device
|
||||
* must be idle rather than busy transferring data before setting these device
|
||||
* options.
|
||||
*
|
||||
* The data rate is set by values in the control register. The formula for
|
||||
* determining the correct register values is:
|
||||
* Fscl = Fpclk/(22 x (divisor_a+1) x (divisor_b+1))
|
||||
* See the hardware data sheet for a full explanation of setting the serial
|
||||
* clock rate.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XIicPs instance.
|
||||
* @param FsclHz is the clock frequency in Hz. The two most common clock
|
||||
* rates are 100KHz and 400KHz.
|
||||
*
|
||||
* @return
|
||||
* - XST_SUCCESS if options are successfully set.
|
||||
* - XST_DEVICE_IS_STARTED if the device is currently transferring
|
||||
* data. The transfer must complete or be aborted before setting
|
||||
* options.
|
||||
* - XST_FAILURE if the Fscl frequency can not be set.
|
||||
*
|
||||
* @note The clock can not be faster than the input clock divide by 22.
|
||||
*
|
||||
******************************************************************************/
|
||||
int XIicPs_SetSClk(XIicPs *InstancePtr, u32 FsclHz)
|
||||
{
|
||||
u32 Div_a;
|
||||
u32 Div_b;
|
||||
u32 ActualFscl;
|
||||
u32 Temp;
|
||||
u32 TempLimit;
|
||||
u32 LastError;
|
||||
u32 BestError;
|
||||
u32 CurrentError;
|
||||
u32 ControlReg;
|
||||
u32 CalcDivA;
|
||||
u32 CalcDivB;
|
||||
u32 BestDivA = 0;
|
||||
u32 BestDivB = 0;
|
||||
|
||||
Xil_AssertNonvoid(InstancePtr != NULL);
|
||||
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
Xil_AssertNonvoid(FsclHz > 0);
|
||||
|
||||
if (0 != XIicPs_In32((InstancePtr->Config.BaseAddress) +
|
||||
XIICPS_TRANS_SIZE_OFFSET)) {
|
||||
return XST_DEVICE_IS_STARTED;
|
||||
}
|
||||
|
||||
/*
|
||||
* Assume Div_a is 0 and calculate (divisor_a+1) x (divisor_b+1).
|
||||
*/
|
||||
Temp = (InstancePtr->Config.InputClockHz) / (22 * FsclHz);
|
||||
|
||||
/*
|
||||
* If the answer is negative or 0, the Fscl input is out of range.
|
||||
*/
|
||||
if (0 == Temp) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* If frequency 400KHz is selected, 384.6KHz should be set.
|
||||
* If frequency 100KHz is selected, 90KHz should be set.
|
||||
* This is due to a hardware limitation.
|
||||
*/
|
||||
if(FsclHz > 384600) {
|
||||
FsclHz = 384600;
|
||||
}
|
||||
|
||||
if((FsclHz <= 100000) && (FsclHz > 90000)) {
|
||||
FsclHz = 90000;
|
||||
}
|
||||
|
||||
/*
|
||||
* TempLimit helps in iterating over the consecutive value of Temp to
|
||||
* find the closest clock rate achievable with divisors.
|
||||
* Iterate over the next value only if fractional part is involved.
|
||||
*/
|
||||
TempLimit = ((InstancePtr->Config.InputClockHz) % (22 * FsclHz)) ?
|
||||
Temp + 1 : Temp;
|
||||
BestError = FsclHz;
|
||||
|
||||
for ( ; Temp <= TempLimit ; Temp++)
|
||||
{
|
||||
LastError = FsclHz;
|
||||
CalcDivA = 0;
|
||||
CalcDivB = 0;
|
||||
CurrentError = 0;
|
||||
|
||||
for (Div_b = 0; Div_b < 64; Div_b++) {
|
||||
|
||||
Div_a = Temp / (Div_b + 1);
|
||||
|
||||
if (Div_a != 0)
|
||||
Div_a = Div_a - 1;
|
||||
|
||||
if (Div_a > 3)
|
||||
continue;
|
||||
|
||||
ActualFscl = (InstancePtr->Config.InputClockHz) /
|
||||
(22 * (Div_a + 1) * (Div_b + 1));
|
||||
|
||||
if (ActualFscl > FsclHz)
|
||||
CurrentError = (ActualFscl - FsclHz);
|
||||
else
|
||||
CurrentError = (FsclHz - ActualFscl);
|
||||
|
||||
if (LastError > CurrentError) {
|
||||
CalcDivA = Div_a;
|
||||
CalcDivB = Div_b;
|
||||
LastError = CurrentError;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Used to capture the best divisors.
|
||||
*/
|
||||
if (LastError < BestError) {
|
||||
BestError = LastError;
|
||||
BestDivA = CalcDivA;
|
||||
BestDivB = CalcDivB;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Read the control register and mask the Divisors.
|
||||
*/
|
||||
ControlReg = XIicPs_ReadReg(InstancePtr->Config.BaseAddress,
|
||||
XIICPS_CR_OFFSET);
|
||||
ControlReg &= ~(XIICPS_CR_DIV_A_MASK | XIICPS_CR_DIV_B_MASK);
|
||||
ControlReg |= (BestDivA << XIICPS_CR_DIV_A_SHIFT) |
|
||||
(BestDivB << XIICPS_CR_DIV_B_SHIFT);
|
||||
|
||||
XIicPs_WriteReg(InstancePtr->Config.BaseAddress, XIICPS_CR_OFFSET,
|
||||
ControlReg);
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function gets the serial clock rate for the IIC device. The device
|
||||
* must be idle rather than busy transferring data before setting these device
|
||||
* options.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XIicPs instance.
|
||||
*
|
||||
* @return The value of the IIC clock to the nearest Hz based on the
|
||||
* control register settings. The actual value may not be exact to
|
||||
* to integer math rounding errors.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
u32 XIicPs_GetSClk(XIicPs *InstancePtr)
|
||||
{
|
||||
u32 ControlReg;
|
||||
u32 ActualFscl;
|
||||
u32 Div_a;
|
||||
u32 Div_b;
|
||||
|
||||
Xil_AssertNonvoid(InstancePtr != NULL);
|
||||
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
|
||||
ControlReg = XIicPs_ReadReg(InstancePtr->Config.BaseAddress,
|
||||
XIICPS_CR_OFFSET);
|
||||
|
||||
Div_a = (ControlReg & XIICPS_CR_DIV_A_MASK) >> XIICPS_CR_DIV_A_SHIFT;
|
||||
Div_b = (ControlReg & XIICPS_CR_DIV_B_MASK) >> XIICPS_CR_DIV_B_SHIFT;
|
||||
|
||||
ActualFscl = (InstancePtr->Config.InputClockHz) /
|
||||
(22 * (Div_a + 1) * (Div_b + 1));
|
||||
|
||||
return ActualFscl;
|
||||
}
|
128
XilinxProcessorIPLib/drivers/iicps/src/xiicps_selftest.c
Normal file
128
XilinxProcessorIPLib/drivers/iicps/src/xiicps_selftest.c
Normal file
|
@ -0,0 +1,128 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* 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 xiicps_selftest.c
|
||||
*
|
||||
* This component contains the implementation of selftest functions for the
|
||||
* XIicPs driver component.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ------ -------- ---------------------------------------------
|
||||
* 1.00a drg/jz 01/30/10 First release
|
||||
* 1.00a sdm 09/22/11 Removed unused code
|
||||
* 2.4 sk 11/03/14 Removed TimeOut Register value check
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
#include "xiicps.h"
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
#define REG_TEST_VALUE 0x00000005
|
||||
|
||||
/**************************** 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 XIicPs instance.
|
||||
*
|
||||
* @return
|
||||
* - XST_SUCCESS if successful.
|
||||
* - XST_REGISTER_ERROR indicates a register did not read or write
|
||||
* correctly
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
int XIicPs_SelfTest(XIicPs *InstancePtr)
|
||||
{
|
||||
|
||||
Xil_AssertNonvoid(InstancePtr != NULL);
|
||||
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
|
||||
/*
|
||||
* All the IIC registers should be in their default state right now.
|
||||
*/
|
||||
if ((XIICPS_CR_RESET_VALUE !=
|
||||
XIicPs_ReadReg(InstancePtr->Config.BaseAddress,
|
||||
XIICPS_CR_OFFSET)) ||
|
||||
(XIICPS_IXR_ALL_INTR_MASK !=
|
||||
XIicPs_ReadReg(InstancePtr->Config.BaseAddress,
|
||||
XIICPS_IMR_OFFSET))) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
XIicPs_Reset(InstancePtr);
|
||||
|
||||
/*
|
||||
* Write, Read then write a register
|
||||
*/
|
||||
XIicPs_WriteReg(InstancePtr->Config.BaseAddress,
|
||||
XIICPS_SLV_PAUSE_OFFSET, REG_TEST_VALUE);
|
||||
|
||||
if (REG_TEST_VALUE != XIicPs_ReadReg(InstancePtr->Config.BaseAddress,
|
||||
XIICPS_SLV_PAUSE_OFFSET)) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
XIicPs_WriteReg(InstancePtr->Config.BaseAddress,
|
||||
XIICPS_SLV_PAUSE_OFFSET, 0);
|
||||
|
||||
XIicPs_Reset(InstancePtr);
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
98
XilinxProcessorIPLib/drivers/iicps/src/xiicps_sinit.c
Normal file
98
XilinxProcessorIPLib/drivers/iicps/src/xiicps_sinit.c
Normal file
|
@ -0,0 +1,98 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* 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 xiicps_sinit.c
|
||||
*
|
||||
* The implementation of the XIicPs component's static initialization
|
||||
* functionality.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ------ -------- --------------------------------------------
|
||||
* 1.00a drg/jz 01/30/10 First release
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
#include "xstatus.h"
|
||||
#include "xparameters.h"
|
||||
#include "xiicps.h"
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
/************************** Variable Definitions *****************************/
|
||||
extern XIicPs_Config XIicPs_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 xiicps.h for the definition of
|
||||
* XIicPs_Config.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
XIicPs_Config *XIicPs_LookupConfig(u16 DeviceId)
|
||||
{
|
||||
XIicPs_Config *CfgPtr = NULL;
|
||||
int Index;
|
||||
|
||||
for (Index = 0; Index < XPAR_XIICPS_NUM_INSTANCES; Index++) {
|
||||
if (XIicPs_ConfigTable[Index].DeviceId == DeviceId) {
|
||||
CfgPtr = &XIicPs_ConfigTable[Index];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return CfgPtr;
|
||||
}
|
575
XilinxProcessorIPLib/drivers/iicps/src/xiicps_slave.c
Normal file
575
XilinxProcessorIPLib/drivers/iicps/src/xiicps_slave.c
Normal file
|
@ -0,0 +1,575 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* 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 xiicps_slave.c
|
||||
*
|
||||
* Handles slave transfers
|
||||
*
|
||||
* <pre> MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- -- -------- ---------------------------------------------
|
||||
* 1.00a jz 01/30/10 First release
|
||||
* 1.04a kpc 08/30/13 Avoid buffer overwrite in SlaveRecvData function
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
#include "xiicps.h"
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
extern int TransmitFifoFill(XIicPs *InstancePtr);
|
||||
|
||||
static int SlaveRecvData(XIicPs *InstancePtr);
|
||||
|
||||
/************************* Variable Definitions *****************************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* This function sets up the device to be a slave.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XIicPs instance.
|
||||
* @param SlaveAddr is the address of the slave we are receiving from.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note
|
||||
* Interrupt is always enabled no matter the tranfer is interrupt-
|
||||
* driven or polled mode. Whether device will be interrupted or not
|
||||
* depends on whether the device is connected to an interrupt
|
||||
* controller and interrupt for the device is enabled.
|
||||
*
|
||||
****************************************************************************/
|
||||
void XIicPs_SetupSlave(XIicPs *InstancePtr, u16 SlaveAddr)
|
||||
{
|
||||
volatile u32 ControlReg;
|
||||
u32 BaseAddr;
|
||||
|
||||
Xil_AssertVoid(InstancePtr != NULL);
|
||||
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
Xil_AssertVoid(XIICPS_ADDR_MASK >= SlaveAddr);
|
||||
|
||||
BaseAddr = InstancePtr->Config.BaseAddress;
|
||||
|
||||
ControlReg = XIicPs_In32(BaseAddr + XIICPS_CR_OFFSET);
|
||||
|
||||
/*
|
||||
* Set up master, AckEn, nea and also clear fifo.
|
||||
*/
|
||||
ControlReg |= XIICPS_CR_ACKEN_MASK | XIICPS_CR_CLR_FIFO_MASK;
|
||||
ControlReg |= XIICPS_CR_NEA_MASK;
|
||||
ControlReg &= ~XIICPS_CR_MS_MASK;
|
||||
|
||||
XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET,
|
||||
ControlReg);
|
||||
|
||||
XIicPs_DisableAllInterrupts(BaseAddr);
|
||||
|
||||
XIicPs_WriteReg(InstancePtr->Config.BaseAddress,
|
||||
XIICPS_ADDR_OFFSET, SlaveAddr);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* This function setup a slave interrupt-driven send. It set the repeated
|
||||
* start for the device is the tranfer size is larger than FIFO depth.
|
||||
* Data processing for the send is initiated by the interrupt handler.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XIicPs instance.
|
||||
* @param MsgPtr is the pointer to the send buffer.
|
||||
* @param ByteCount is the number of bytes to be sent.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note This send routine is for interrupt-driven transfer only.
|
||||
*
|
||||
****************************************************************************/
|
||||
void XIicPs_SlaveSend(XIicPs *InstancePtr, u8 *MsgPtr, int ByteCount)
|
||||
{
|
||||
u32 BaseAddr;
|
||||
|
||||
/*
|
||||
* Assert validates the input arguments
|
||||
*/
|
||||
Xil_AssertVoid(InstancePtr != NULL);
|
||||
Xil_AssertVoid(MsgPtr != NULL);
|
||||
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
|
||||
|
||||
BaseAddr = InstancePtr->Config.BaseAddress;
|
||||
InstancePtr->SendBufferPtr = MsgPtr;
|
||||
InstancePtr->SendByteCount = ByteCount;
|
||||
InstancePtr->RecvBufferPtr = NULL;
|
||||
|
||||
XIicPs_EnableInterrupts(BaseAddr,
|
||||
XIICPS_IXR_DATA_MASK | XIICPS_IXR_COMP_MASK |
|
||||
XIICPS_IXR_TO_MASK | XIICPS_IXR_NACK_MASK |
|
||||
XIICPS_IXR_TX_OVR_MASK);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* This function setup a slave interrupt-driven receive.
|
||||
* Data processing for the receive is handled by the interrupt handler.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XIicPs instance.
|
||||
* @param MsgPtr is the pointer to the receive buffer.
|
||||
* @param ByteCount is the number of bytes to be received.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note This routine is for interrupt-driven transfer only.
|
||||
*
|
||||
****************************************************************************/
|
||||
void XIicPs_SlaveRecv(XIicPs *InstancePtr, u8 *MsgPtr, int ByteCount)
|
||||
{
|
||||
/*
|
||||
* Assert validates the input arguments.
|
||||
*/
|
||||
Xil_AssertVoid(InstancePtr != NULL);
|
||||
Xil_AssertVoid(MsgPtr != NULL);
|
||||
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
|
||||
|
||||
InstancePtr->RecvBufferPtr = MsgPtr;
|
||||
InstancePtr->RecvByteCount = ByteCount;
|
||||
InstancePtr->SendBufferPtr = NULL;
|
||||
|
||||
XIicPs_EnableInterrupts(InstancePtr->Config.BaseAddress,
|
||||
XIICPS_IXR_DATA_MASK | XIICPS_IXR_COMP_MASK |
|
||||
XIICPS_IXR_NACK_MASK | XIICPS_IXR_TO_MASK |
|
||||
XIICPS_IXR_RX_OVR_MASK | XIICPS_IXR_RX_UNF_MASK);
|
||||
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* This function sends a buffer in polled mode as a slave.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XIicPs instance.
|
||||
* @param MsgPtr is the pointer to the send buffer.
|
||||
* @param ByteCount is the number of bytes to be sent.
|
||||
*
|
||||
* @return
|
||||
* - XST_SUCCESS if everything went well.
|
||||
* - XST_FAILURE if master sends us data or master terminates the
|
||||
* transfer before all data has sent out.
|
||||
*
|
||||
* @note This send routine is for polled mode transfer only.
|
||||
*
|
||||
****************************************************************************/
|
||||
int XIicPs_SlaveSendPolled(XIicPs *InstancePtr, u8 *MsgPtr, int ByteCount)
|
||||
{
|
||||
volatile u32 IntrStatusReg;
|
||||
volatile u32 StatusReg;
|
||||
u32 BaseAddr;
|
||||
int Tmp;
|
||||
int BytesToSend;
|
||||
int Error = 0;
|
||||
|
||||
/*
|
||||
* Assert validates the input arguments.
|
||||
*/
|
||||
Xil_AssertNonvoid(InstancePtr != NULL);
|
||||
Xil_AssertNonvoid(MsgPtr != NULL);
|
||||
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
|
||||
BaseAddr = InstancePtr->Config.BaseAddress;
|
||||
InstancePtr->SendBufferPtr = MsgPtr;
|
||||
InstancePtr->SendByteCount = ByteCount;
|
||||
|
||||
/*
|
||||
* Use RXRW bit in status register to wait master to start a read.
|
||||
*/
|
||||
StatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_SR_OFFSET);
|
||||
while (((StatusReg & XIICPS_SR_RXRW_MASK) == 0) && (!Error)) {
|
||||
|
||||
/*
|
||||
* If master tries to send us data, it is an error.
|
||||
*/
|
||||
if (StatusReg & XIICPS_SR_RXDV_MASK) {
|
||||
Error = 1;
|
||||
}
|
||||
|
||||
StatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_SR_OFFSET);
|
||||
}
|
||||
|
||||
if (Error) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Clear the interrupt status register.
|
||||
*/
|
||||
IntrStatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_ISR_OFFSET);
|
||||
XIicPs_WriteReg(BaseAddr, XIICPS_ISR_OFFSET, IntrStatusReg);
|
||||
|
||||
/*
|
||||
* Send data as long as there is more data to send and
|
||||
* there are no errors.
|
||||
*/
|
||||
while ((InstancePtr->SendByteCount > 0) && (!Error)){
|
||||
|
||||
/*
|
||||
* Find out how many can be sent.
|
||||
*/
|
||||
BytesToSend = InstancePtr->SendByteCount;
|
||||
if (BytesToSend > XIICPS_FIFO_DEPTH) {
|
||||
BytesToSend = XIICPS_FIFO_DEPTH;
|
||||
}
|
||||
|
||||
for(Tmp = 0; Tmp < BytesToSend; Tmp ++) {
|
||||
XIicPs_SendByte(InstancePtr);
|
||||
}
|
||||
|
||||
StatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_SR_OFFSET);
|
||||
|
||||
/*
|
||||
* Wait for master to read the data out of fifo.
|
||||
*/
|
||||
while (((StatusReg & XIICPS_SR_TXDV_MASK) != 0) && (!Error)) {
|
||||
|
||||
/*
|
||||
* If master terminates the transfer before all data is
|
||||
* sent, it is an error.
|
||||
*/
|
||||
IntrStatusReg = XIicPs_ReadReg(BaseAddr,
|
||||
XIICPS_ISR_OFFSET);
|
||||
if (IntrStatusReg & XIICPS_IXR_NACK_MASK) {
|
||||
Error = 1;
|
||||
}
|
||||
|
||||
/* Clear ISR.
|
||||
*/
|
||||
XIicPs_WriteReg(BaseAddr, XIICPS_ISR_OFFSET,
|
||||
IntrStatusReg);
|
||||
|
||||
StatusReg = XIicPs_ReadReg(BaseAddr,
|
||||
XIICPS_SR_OFFSET);
|
||||
}
|
||||
}
|
||||
|
||||
if (Error) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* This function receives a buffer in polled mode as a slave.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XIicPs instance.
|
||||
* @param MsgPtr is the pointer to the receive buffer.
|
||||
* @param ByteCount is the number of bytes to be received.
|
||||
*
|
||||
* @return
|
||||
* - XST_SUCCESS if everything went well.
|
||||
* - XST_FAILURE if timed out.
|
||||
*
|
||||
* @note This receive routine is for polled mode transfer only.
|
||||
*
|
||||
****************************************************************************/
|
||||
int XIicPs_SlaveRecvPolled(XIicPs *InstancePtr, u8 *MsgPtr, int ByteCount)
|
||||
{
|
||||
volatile u32 IntrStatusReg;
|
||||
volatile u32 StatusReg;
|
||||
u32 BaseAddr;
|
||||
|
||||
/*
|
||||
* Assert validates the input arguments.
|
||||
*/
|
||||
Xil_AssertNonvoid(InstancePtr != NULL);
|
||||
Xil_AssertNonvoid(MsgPtr != NULL);
|
||||
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
|
||||
BaseAddr = InstancePtr->Config.BaseAddress;
|
||||
InstancePtr->RecvBufferPtr = MsgPtr;
|
||||
InstancePtr->RecvByteCount = ByteCount;
|
||||
|
||||
StatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_SR_OFFSET);
|
||||
|
||||
/*
|
||||
* Clear the interrupt status register.
|
||||
*/
|
||||
IntrStatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_ISR_OFFSET);
|
||||
XIicPs_WriteReg(BaseAddr, XIICPS_ISR_OFFSET, IntrStatusReg);
|
||||
|
||||
/*
|
||||
* Clear the status register.
|
||||
*/
|
||||
StatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_SR_OFFSET);
|
||||
XIicPs_WriteReg(BaseAddr, XIICPS_SR_OFFSET, StatusReg);
|
||||
|
||||
StatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_SR_OFFSET);
|
||||
while (InstancePtr->RecvByteCount > 0) {
|
||||
|
||||
/* Wait for master to put data */
|
||||
while ((StatusReg & XIICPS_SR_RXDV_MASK) == 0) {
|
||||
StatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_SR_OFFSET);
|
||||
|
||||
/*
|
||||
* If master terminates the transfer before we get all
|
||||
* the data or the master tries to read from us,
|
||||
* it is an error.
|
||||
*/
|
||||
IntrStatusReg = XIicPs_ReadReg(BaseAddr,
|
||||
XIICPS_ISR_OFFSET);
|
||||
if ((IntrStatusReg & (XIICPS_IXR_DATA_MASK |
|
||||
XIICPS_IXR_COMP_MASK)) &&
|
||||
((StatusReg & XIICPS_SR_RXDV_MASK) == 0) &&
|
||||
(InstancePtr->RecvByteCount > 0)) {
|
||||
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Clear the interrupt status register.
|
||||
*/
|
||||
XIicPs_WriteReg(BaseAddr, XIICPS_ISR_OFFSET,
|
||||
IntrStatusReg);
|
||||
}
|
||||
|
||||
/*
|
||||
* Read all data from FIFO.
|
||||
*/
|
||||
while ((StatusReg & XIICPS_SR_RXDV_MASK) &&
|
||||
(InstancePtr->RecvByteCount > 0)){
|
||||
|
||||
XIicPs_RecvByte(InstancePtr);
|
||||
|
||||
StatusReg = XIicPs_ReadReg(BaseAddr,
|
||||
XIICPS_SR_OFFSET);
|
||||
}
|
||||
}
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* The interrupt handler for slave mode. It does the protocol handling for
|
||||
* the interrupt-driven transfers.
|
||||
*
|
||||
* Completion events and errors are signaled to upper layer for proper
|
||||
* handling.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* The interrupts that are handled are:
|
||||
* - DATA
|
||||
* If the instance is sending, it means that the master wants to read more
|
||||
* data from us. Send more data, and check whether we are done with this
|
||||
* send.
|
||||
*
|
||||
* If the instance is receiving, it means that the master has writen
|
||||
* more data to us. Receive more data, and check whether we are done with
|
||||
* with this receive.
|
||||
*
|
||||
* - COMP
|
||||
* This marks that stop sequence has been sent from the master, transfer
|
||||
* is about to terminate. However, for receiving, the master may have
|
||||
* written us some data, so receive that first.
|
||||
*
|
||||
* It is an error if the amount of transfered data is less than expected.
|
||||
*
|
||||
* - NAK
|
||||
* This marks that master does not want our data. It is for send only.
|
||||
*
|
||||
* - Other interrupts
|
||||
* These interrupts are marked as error.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XIicPs instance.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
****************************************************************************/
|
||||
void XIicPs_SlaveInterruptHandler(XIicPs *InstancePtr)
|
||||
{
|
||||
volatile u32 IntrStatusReg;
|
||||
u32 IsSend = 0;
|
||||
u32 StatusEvent = 0;
|
||||
int LeftOver;
|
||||
u32 BaseAddr;
|
||||
|
||||
/*
|
||||
* Assert validates the input arguments.
|
||||
*/
|
||||
Xil_AssertVoid(InstancePtr != NULL);
|
||||
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
|
||||
BaseAddr = InstancePtr->Config.BaseAddress;
|
||||
|
||||
/*
|
||||
* Read the Interrupt status register.
|
||||
*/
|
||||
IntrStatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_ISR_OFFSET);
|
||||
|
||||
/*
|
||||
* Write the status back to clear the interrupts so no events are missed
|
||||
* while processing this interrupt.
|
||||
*/
|
||||
XIicPs_WriteReg(BaseAddr, XIICPS_ISR_OFFSET, IntrStatusReg);
|
||||
|
||||
/*
|
||||
* Use the Mask register AND with the Interrupt Status register so
|
||||
* disabled interrupts are not processed.
|
||||
*/
|
||||
IntrStatusReg &= ~(XIicPs_ReadReg(BaseAddr, XIICPS_IMR_OFFSET));
|
||||
|
||||
/*
|
||||
* Determine whether the device is sending.
|
||||
*/
|
||||
if (InstancePtr->RecvBufferPtr == NULL) {
|
||||
IsSend = 1;
|
||||
}
|
||||
|
||||
/* Data interrupt
|
||||
*
|
||||
* This means master wants to do more data transfers.
|
||||
* Also check for completion of transfer, signal upper layer if done.
|
||||
*/
|
||||
if (0 != (IntrStatusReg & XIICPS_IXR_DATA_MASK)) {
|
||||
if (IsSend) {
|
||||
LeftOver = TransmitFifoFill(InstancePtr);
|
||||
/*
|
||||
* We may finish send here
|
||||
*/
|
||||
if (LeftOver == 0) {
|
||||
StatusEvent |=
|
||||
XIICPS_EVENT_COMPLETE_SEND;
|
||||
}
|
||||
} else {
|
||||
LeftOver = SlaveRecvData(InstancePtr);
|
||||
|
||||
/* We may finish the receive here */
|
||||
if (LeftOver == 0) {
|
||||
StatusEvent |= XIICPS_EVENT_COMPLETE_RECV;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Complete interrupt.
|
||||
*
|
||||
* In slave mode, it means the master has done with this transfer, so
|
||||
* we signal the application using completion event.
|
||||
*/
|
||||
if (0 != (IntrStatusReg & XIICPS_IXR_COMP_MASK)) {
|
||||
if (IsSend) {
|
||||
if (InstancePtr->SendByteCount > 0) {
|
||||
StatusEvent |= XIICPS_EVENT_ERROR;
|
||||
}else {
|
||||
StatusEvent |= XIICPS_EVENT_COMPLETE_SEND;
|
||||
}
|
||||
} else {
|
||||
LeftOver = SlaveRecvData(InstancePtr);
|
||||
if (LeftOver > 0) {
|
||||
StatusEvent |= XIICPS_EVENT_ERROR;
|
||||
} else {
|
||||
StatusEvent |= XIICPS_EVENT_COMPLETE_RECV;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Nack interrupt, pass this information to application.
|
||||
*/
|
||||
if (0 != (IntrStatusReg & XIICPS_IXR_NACK_MASK)) {
|
||||
StatusEvent |= XIICPS_EVENT_NACK;
|
||||
}
|
||||
|
||||
/*
|
||||
* All other interrupts are treated as error.
|
||||
*/
|
||||
if (0 != (IntrStatusReg & (XIICPS_IXR_TO_MASK |
|
||||
XIICPS_IXR_RX_UNF_MASK |
|
||||
XIICPS_IXR_TX_OVR_MASK |
|
||||
XIICPS_IXR_RX_OVR_MASK))){
|
||||
|
||||
StatusEvent |= XIICPS_EVENT_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Signal application if there are any events.
|
||||
*/
|
||||
if (0 != StatusEvent) {
|
||||
InstancePtr->StatusHandler(InstancePtr->CallBackRef,
|
||||
StatusEvent);
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/*
|
||||
*
|
||||
* This function handles continuation of receiving data. It is invoked
|
||||
* from interrupt handler.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XIicPs instance.
|
||||
*
|
||||
* @return Number of bytes still expected by the instance.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
****************************************************************************/
|
||||
static int SlaveRecvData(XIicPs *InstancePtr)
|
||||
{
|
||||
volatile u32 StatusReg;
|
||||
u32 BaseAddr;
|
||||
|
||||
BaseAddr = InstancePtr->Config.BaseAddress;
|
||||
|
||||
StatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_SR_OFFSET);
|
||||
|
||||
while ((StatusReg & XIICPS_SR_RXDV_MASK) &&
|
||||
(InstancePtr->RecvByteCount > 0)) {
|
||||
XIicPs_RecvByte(InstancePtr);
|
||||
StatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_SR_OFFSET);
|
||||
}
|
||||
|
||||
return InstancePtr->RecvByteCount;
|
||||
}
|
|
@ -34,7 +34,7 @@ OPTION psf_version = 2.1;
|
|||
BEGIN driver iicps
|
||||
|
||||
OPTION supported_peripherals = (ps7_i2c);
|
||||
OPTION driver_state = ACTIVE;
|
||||
OPTION driver_state = DEPRECATED;
|
||||
OPTION copyfiles = all;
|
||||
OPTION VERSION = 2.4;
|
||||
OPTION NAME = iicps;
|
||||
|
|
Loading…
Add table
Reference in a new issue