diff --git a/XilinxProcessorIPLib/drivers/canps/data/canps.mdd b/XilinxProcessorIPLib/drivers/canps/data/canps.mdd new file mode 100755 index 00000000..348e99ab --- /dev/null +++ b/XilinxProcessorIPLib/drivers/canps/data/canps.mdd @@ -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 canps + + OPTION supported_peripherals = (ps7_can); + OPTION driver_state = ACTIVE; + OPTION copyfiles = all; + OPTION VERSION = 3.0; + OPTION NAME = canps; + +END driver diff --git a/XilinxProcessorIPLib/drivers/canps/data/canps.tcl b/XilinxProcessorIPLib/drivers/canps/data/canps.tcl new file mode 100755 index 00000000..e9e5065f --- /dev/null +++ b/XilinxProcessorIPLib/drivers/canps/data/canps.tcl @@ -0,0 +1,51 @@ +############################################################################### +# +# Copyright (C) 2011 - 2014 Xilinx, Inc. All rights reserved. +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# Use of the Software is limited solely to applications: +# (a) running on a Xilinx device, or +# (b) that interact with a Xilinx device through a bus or interconnect. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +# OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# +# Except as contained in this notice, the name of the Xilinx shall not be used +# in advertising or otherwise to promote the sale, use or other dealings in +# this Software without prior written authorization from Xilinx. +# +############################################################################### +############################################################################## +# +# Modification History +# +# Ver Who Date Changes +# ----- ---- -------- ----------------------------------------------- +# 1.00a sdm 11/22/11 Created +# +############################################################################## + +#uses "xillib.tcl" + +proc generate {drv_handle} { + xdefine_zynq_include_file $drv_handle "xparameters.h" "XCanPs" "NUM_INSTANCES" "DEVICE_ID" "C_S_AXI_BASEADDR" "C_S_AXI_HIGHADDR" "C_CAN_CLK_FREQ_HZ" + + xdefine_zynq_config_file $drv_handle "xcanps_g.c" "XCanPs" "DEVICE_ID" "C_S_AXI_BASEADDR" + + xdefine_zynq_canonical_xpars $drv_handle "xparameters.h" "XCanPs" "DEVICE_ID" "C_S_AXI_BASEADDR" "C_S_AXI_HIGHADDR" "C_CAN_CLK_FREQ_HZ" + +} diff --git a/XilinxProcessorIPLib/drivers/canps/data/canps_header.h b/XilinxProcessorIPLib/drivers/canps/data/canps_header.h new file mode 100755 index 00000000..c768ff36 --- /dev/null +++ b/XilinxProcessorIPLib/drivers/canps/data/canps_header.h @@ -0,0 +1,45 @@ +/****************************************************************************** +* +* 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 CANPS_HEADER_H /* prevent circular inclusions */ +#define CANPS_HEADER_H /* by using protection macros */ + +#include "xil_types.h" +#include "xil_assert.h" +#include "xstatus.h" + +int CanPsPolledExample(u16 DeviceId); + +#ifdef XPAR_PS7_SCUGIC_0_DEVICE_ID +int CanPsIntrExample(XScuGic *IntcInstPtr, XCanPs *CanInstPtr, + u16 CanDeviceId, u16 CanIntrId); +#endif +#endif diff --git a/XilinxProcessorIPLib/drivers/canps/data/canps_tapp.tcl b/XilinxProcessorIPLib/drivers/canps/data/canps_tapp.tcl new file mode 100755 index 00000000..bf3261c0 --- /dev/null +++ b/XilinxProcessorIPLib/drivers/canps/data/canps_tapp.tcl @@ -0,0 +1,191 @@ +############################################################################### +# +# Copyright (C) 2004 - 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 10/12/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 {xcanps.h canps_header.h} + } + return $inc_file_lines +} + +proc gen_src_files {swproj mhsinst} { + if {$swproj == 0} { + return "" + } + set isintr [::hsm::utils::is_ip_interrupting_current_proc $mhsinst] + if {$swproj == 1} { + if {$isintr == 1} { + set inc_file_lines {examples/xcanps_polled_example.c examples/xcanps_intr_example.c data/canps_header.h} + } else { + set inc_file_lines {examples/xcanps_polled_example.c data/canps_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} { + + set ipname [get_property NAME $mhsinst] + set decl " static XCanPs ${ipname};" + set inc_file_lines $decl + return $inc_file_lines + + } + +} + +proc gen_testfunc_call {swproj mhsinst} { + + if {$swproj == 0} { + return "" + } + + set ipname [get_property NAME $mhsinst] + set deviceid [::hsm::utils::get_ip_param_name $mhsinst "DEVICE_ID"] + set stdout [get_property CONFIG.STDOUT [get_os]] + if { $stdout == "" || $stdout == "none" } { + set hasStdout 0 + } else { + set hasStdout 1 + } + set isintr [::hsm::utils::is_ip_interrupting_current_proc $mhsinst] + set intcvar intc + + set testfunc_call "" + + if {${hasStdout} == 0} { + + append testfunc_call " + + { + int Status; + + Status = CanPsPolledExample(${deviceid}); + + }" + if {$isintr == 1} { + set intr_id "XPAR_${ipname}_INTR" + set intr_id [string toupper $intr_id] + + append testfunc_call " + + { + int Status; + Status = CanPsIntrExample(&${intcvar}, &${ipname}, \\ + ${deviceid}, \\ + ${intr_id}); + }" + + } + + + + } else { + + append testfunc_call " + + { + int Status; + + print(\"\\r\\n Running CanPsPolledExample() for ${ipname}...\\r\\n\"); + + Status = CanPsPolledExample(${deviceid}); + + if (Status == 0) { + print(\"CanPsPolledExample PASSED\\r\\n\"); + } + else { + print(\"CanPsPolledExample FAILED\\r\\n\"); + } + }" + + if {$isintr ==1 } { + set intr_id "XPAR_${ipname}_INTR" + set intr_id [string toupper $intr_id] + + append testfunc_call " + { + int Status; + + print(\"\\r\\n Running Interrupt Test for ${ipname}...\\r\\n\"); + + Status = CanPsIntrExample(&${intcvar}, &${ipname}, \\ + ${deviceid}, \\ + ${intr_id}); + + if (Status == 0) { + print(\"CanPsIntrExample PASSED\\r\\n\"); + } + else { + print(\"CanPsIntrExample FAILED\\r\\n\"); + } + + }" + } + + + } + + return $testfunc_call +} diff --git a/XilinxProcessorIPLib/drivers/canps/examples/index.html b/XilinxProcessorIPLib/drivers/canps/examples/index.html new file mode 100755 index 00000000..7feadbdf --- /dev/null +++ b/XilinxProcessorIPLib/drivers/canps/examples/index.html @@ -0,0 +1,19 @@ + + +
+ + +Copyright � 1995-2014 Xilinx, Inc. All rights reserved.
+ + diff --git a/XilinxProcessorIPLib/drivers/canps/examples/xcanps_intr_example.c b/XilinxProcessorIPLib/drivers/canps/examples/xcanps_intr_example.c new file mode 100755 index 00000000..5708e386 --- /dev/null +++ b/XilinxProcessorIPLib/drivers/canps/examples/xcanps_intr_example.c @@ -0,0 +1,704 @@ +/****************************************************************************** +* +* 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 xcanps_intr_example.c +* +* Contains an example of how to use the XCanPs driver directly. +* This example shows the usage of the driver/device in interrupt mode. +* +* @note +* The Baud Rate Prescaler Register (BRPR) and Bit Timing Register (BTR) +* are setup such that CAN baud rate equals 40Kbps, assuming that the +* the CAN clock is 24MHz. The user needs to modify these values based on +* the desired baud rate and the CAN clock frequency. For more information +* see the CAN 2.0A, CAN 2.0B, ISO 11898-1 specifications. +* +*+* MODIFICATION HISTORY: +* +* Ver Who Date Changes +* ----- ----- -------- ----------------------------------------------- +* 1.00a xd/sv 01/12/10 First release +* 2.1 adk 23/08/14 Fixed CR:798792 Peripheral test for CANPS IP in +* SDK claims a 40kbps baud rate but it's not. +*+* +******************************************************************************/ + +/***************************** Include Files *********************************/ + +#include "xparameters.h" +#include "xcanps.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 CAN_DEVICE_ID XPAR_XCANPS_0_DEVICE_ID +#define INTC_DEVICE_ID XPAR_SCUGIC_SINGLE_DEVICE_ID +#define CAN_INTR_VEC_ID XPAR_XCANPS_0_INTR + +/* Maximum CAN frame length in word */ +#define XCANPS_MAX_FRAME_SIZE_IN_WORDS (XCANPS_MAX_FRAME_SIZE / sizeof(u32)) + +#define FRAME_DATA_LENGTH 8 /* Frame Data field length */ + +/* + * Message Id Constant. + */ +#define TEST_MESSAGE_ID 2000 + +/* + * The Baud Rate Prescaler Register (BRPR) and Bit Timing Register (BTR) + * are setup such that CAN baud rate equals 40Kbps, assuming that the + * the CAN clock is 24MHz. The user needs to modify these values based on + * the desired baud rate and the CAN clock frequency. For more information + * see the CAN 2.0A, CAN 2.0B, ISO 11898-1 specifications. + */ + +/* + * Timing parameters to be set in the Bit Timing Register (BTR). + * These values are for a 40 Kbps baudrate assuming the CAN input clock + * frequency is 24 MHz. + */ +#define TEST_BTR_SYNCJUMPWIDTH 3 +#define TEST_BTR_SECOND_TIMESEGMENT 2 +#define TEST_BTR_FIRST_TIMESEGMENT 15 + +/* + * The Baud rate Prescalar value in the Baud Rate Prescaler Register + * needs to be set based on the input clock frequency to the CAN core and + * the desired CAN baud rate. + * This value is for a 40 Kbps baudrate assuming the CAN input clock frequency + * is 24 MHz. + */ +#define TEST_BRPR_BAUD_PRESCALAR 29 + +/**************************** Type Definitions *******************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ + +/************************** Function Prototypes ******************************/ + +int CanPsIntrExample(XScuGic *IntcInstPtr, + XCanPs *CanInstPtr, + u16 CanDeviceId, + u16 CanIntrId); +static void Config(XCanPs *InstancePtr); +static void SendFrame(XCanPs *InstancePtr); + +static void SendHandler(void *CallBackRef); +static void RecvHandler(void *CallBackRef); +static void ErrorHandler(void *CallBackRef, u32 ErrorMask); +static void EventHandler(void *CallBackRef, u32 Mask); + +static int SetupInterruptSystem(XScuGic *IntcInstancePtr, + XCanPs *CanInstancePtr, + u16 CanIntrId); + +/************************** Variable Definitions *****************************/ + +#ifndef TESTAPP_GEN +static XCanPs CanInstance; /* Instance of the Can driver */ +static XScuGic IntcInstance; /* Instance of the Interrupt Controller driver */ +#endif + +/* + * Buffers to hold frames to send and receive. These are declared as global so + * that they are not on the stack. + * These buffers need to be 32-bit aligned + */ +static u32 TxFrame[XCANPS_MAX_FRAME_SIZE_IN_WORDS]; +static u32 RxFrame[XCANPS_MAX_FRAME_SIZE_IN_WORDS]; + +/* + * Shared variables used to test the callbacks. + */ +volatile static int LoopbackError; /* Asynchronous error occurred */ +volatile static int RecvDone; /* Received a frame */ +volatile static int SendDone; /* Frame was sent successfully */ + +/****************************************************************************/ +/** +* +* This function is the main function of the Can interrupt example. +* +* @param None. +* +* @return +* - XST_SUCCESS if the example has completed successfully. +* - XST_FAILURE if the example has failed. +* +* @note None. +* +*****************************************************************************/ +#ifndef TESTAPP_GEN +int main() +{ + int Status; + + xil_printf("CAN Interrupt Example Test \r\n"); + + /* + * Run the Can interrupt example. + */ + Status = CanPsIntrExample(&IntcInstance, &CanInstance, + CAN_DEVICE_ID, CAN_INTR_VEC_ID); + if (Status != XST_SUCCESS) { + xil_printf("CAN Interrupt Example Test Failed\r\n"); + return XST_FAILURE; + } + + xil_printf("Successfully ran CAN Interrupt Example Test\r\n"); + return XST_SUCCESS; +} +#endif + +/*****************************************************************************/ +/** +* +* The main entry point for showing the XCanPs driver in interrupt mode. +* The example configures the device for internal loop back mode, then +* sends a CAN frame and receives the same CAN frame. +* +* @param IntcInstPtr is a pointer to the instance of the INTC driver. +* @param CanInstPtr is a pointer to the instance of the CAN driver which +* is going to be connected to the interrupt controller. +* @param CanDeviceId is the device Id of the CAN device and is typically +* XPAR_
+* MODIFICATION HISTORY: +* +* Ver Who Date Changes +* ----- ----- -------- ----------------------------------------------- +* 1.00a xd/sv 01/12/10 First release +* 2.1 adk 23/08/14 Fixed CR:798792 Peripheral test for CANPS IP in +* SDK claims a 40kbps baud rate but it's not. +*+* +******************************************************************************/ + +/***************************** Include Files *********************************/ + +#include "xcanps.h" +#include "xparameters.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 CAN_DEVICE_ID XPAR_XCANPS_0_DEVICE_ID + +/* + * Maximum CAN frame length in words. + */ +#define XCANPS_MAX_FRAME_SIZE_IN_WORDS (XCANPS_MAX_FRAME_SIZE / sizeof(u32)) + +#define FRAME_DATA_LENGTH 8 /* Frame Data field length */ + +/* + * Message Id Constant. + */ +#define TEST_MESSAGE_ID 2000 + +/* + * The Baud Rate Prescaler Register (BRPR) and Bit Timing Register (BTR) + * are setup such that CAN baud rate equals 40Kbps, assuming that the + * the CAN clock is 24MHz. The user needs to modify these values based on + * the desired baud rate and the CAN clock frequency. For more information + * see the CAN 2.0A, CAN 2.0B, ISO 11898-1 specifications. + */ + +/* + * Timing parameters to be set in the Bit Timing Register (BTR). + * These values are for a 40 Kbps baudrate assuming the CAN input clock + frequency + * is 24 MHz. + */ +#define TEST_BTR_SYNCJUMPWIDTH 3 +#define TEST_BTR_SECOND_TIMESEGMENT 2 +#define TEST_BTR_FIRST_TIMESEGMENT 15 + +/* + * The Baud rate Prescalar value in the Baud Rate Prescaler Register (BRPR) + * needs to be set based on the input clock frequency to the CAN core and + * the desired CAN baud rate. + * This value is for a 40 Kbps baudrate assuming the CAN input clock frequency + * is 24 MHz. + */ +#define TEST_BRPR_BAUD_PRESCALAR 29 + +/**************************** Type Definitions *******************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ + +/************************** Function Prototypes ******************************/ + +int CanPsPolledExample(u16 DeviceId); +static int SendFrame(XCanPs *InstancePtr); +static int RecvFrame(XCanPs *InstancePtr); + +/************************** Variable Definitions *****************************/ + +/* + * Buffers to hold frames to send and receive. These are declared as global so + * that they are not on the stack. + * These buffers need to be 32-bit aligned + */ +static u32 TxFrame[XCANPS_MAX_FRAME_SIZE_IN_WORDS]; +static u32 RxFrame[XCANPS_MAX_FRAME_SIZE_IN_WORDS]; + +/* Driver instance */ +static XCanPs Can; + +/****************************************************************************/ +/** +* +* This function is the main function of the Can polled example. +* +* @param None +* +* @return +* - XST_SUCCESS if the example has completed successfully. +* - XST_FAILURE if the example has failed. +* +* @note None +* +*****************************************************************************/ +#ifndef TESTAPP_GEN +int main() +{ + int Status; + + xil_printf("CAN Polled Mode Example Test \r\n"); + + /* + * Run the Can Polled example, specify the Device ID that is generated + * in xparameters.h . + */ + Status = CanPsPolledExample(CAN_DEVICE_ID); + if (Status != XST_SUCCESS) { + xil_printf("CAN Polled Mode Example Test Failed\r\n"); + return XST_FAILURE; + } + + xil_printf("Successfully ran CAN Polled Mode Example Test\r\n"); + return XST_SUCCESS; +} +#endif + +/*****************************************************************************/ +/** +* +* The entry point for showing the XCanPs driver in polled mode. The example +* configures the device for internal loop back mode, then sends a Can +* frame, receives the same Can frame, and verifies the frame contents. +* +* @param DeviceId is the XPAR_
+* +* MODIFICATION HISTORY: +* +* Ver Who Date Changes +* ----- ----- -------- ----------------------------------------------- +* 1.00a xd/sv 01/12/10 First release +* +* +*+* +******************************************************************************/ + +/***************************** Include Files *********************************/ + +#include "xparameters.h" +#include "xcanps.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 CAN_DEVICE_ID XPAR_XCANPS_0_DEVICE_ID +#define INTC_DEVICE_ID XPAR_SCUGIC_SINGLE_DEVICE_ID +#define CAN_INTR_VEC_ID XPAR_XCANPS_0_INTR + +/* + * Maximum CAN frame length in words. + */ +#define XCANPS_MAX_FRAME_SIZE_IN_WORDS (XCANPS_MAX_FRAME_SIZE / sizeof(u32)) + +#define FRAME_DATA_LENGTH 8 /* Frame Data field length */ + +#define TEST_THRESHOLD 25 /* This is Rx FIFO WaterMark Threshold */ + +/* + * Message Id Constant. + */ +#define TEST_MESSAGE_ID 2000 + +/* + * The Baud Rate Prescaler Register (BRPR) and Bit Timing Register (BTR) + * are setup such that CAN baud rate equals 40Kbps, assuming that the + * the CAN clock is 24MHz. The user needs to modify these values based on + * the desired baud rate and the CAN clock frequency. For more information + * see the CAN 2.0A, CAN 2.0B, ISO 11898-1 specifications. + */ + +/* + * Timing parameters to be set in the Bit Timing Register (BTR). + * These values are for a 40 Kbps baudrate assuming the CAN input clock + * frequency is 24 MHz. + */ +#define TEST_BTR_SYNCJUMPWIDTH 3 +#define TEST_BTR_SECOND_TIMESEGMENT 2 +#define TEST_BTR_FIRST_TIMESEGMENT 15 + +/* + * The Baud rate Prescalar value in the Baud Rate Prescaler Register + * needs to be set based on the input clock frequency to the CAN core and + * the desired CAN baud rate. + * This value is for a 40 Kbps baudrate assuming the CAN input clock frequency + * is 24 MHz. + */ +#define TEST_BRPR_BAUD_PRESCALAR 29 + +/**************************** Type Definitions *******************************/ + + +/***************** Macros (Inline Functions) Definitions *********************/ + + +/************************** Function Prototypes ******************************/ + +int CanPsWatermarkIntrExample(XScuGic *IntcInstPtr, + XCanPs *CanInstPtr, + u16 CanDeviceId, + u16 CanIntrId); + +static void Config(XCanPs *InstancePtr); +static void SendFrame(XCanPs *InstancePtr); +static int ReceiveData(XCanPs *InstancePtr); + +static void SendHandler(void *CallBackRef); +static void RecvHandler(void *CallBackRef); +static void ErrorHandler(void *CallBackRef, u32 ErrorMask); +static void EventHandler(void *CallBackRef, u32 Mask); + +static int SetupInterruptSystem(XScuGic *IntcInstancePtr, + XCanPs *CanInstancePtr, + u16 CanIntrId); + + +/************************** Variable Definitions *****************************/ + +static XCanPs CanInstance; /* Instance of the Can driver */ +static XScuGic IntcInstance; /* Instance of the Interrupt Controller driver */ + + +/* + * Buffers to hold frames to send and receive. These are declared as global so + * that they are not on the stack. + * These buffers need to be 32-bit aligned + */ +static u32 TxFrame[XCANPS_MAX_FRAME_SIZE_IN_WORDS]; +static u32 RxFrame[XCANPS_MAX_FRAME_SIZE_IN_WORDS]; + +/* + * Shared variables used to test the callbacks. + */ +volatile static int LoopbackError; /* Asynchronous error occurred */ +volatile static int RecvDone; /* Received a frame */ +volatile static int SendDone; /* Frame was sent successfully */ + +static u8 TestDataOffset; /* Test Data value added to the CAN data */ + +/****************************************************************************/ +/** +* +* This function is the main function of the Can Rx Watermark interrupt example. +* +* @param None. +* +* @return +* - XST_SUCCESS if the example has completed successfully. +* - XST_FAILURE if the example has failed. +* +* @note None +* +*****************************************************************************/ +int main() +{ + int Status; + + xil_printf("CAN Watermark Example Test \r\n"); + + /* + * Run the Can Rx Watermark interrupt example. + */ + Status = CanPsWatermarkIntrExample(&IntcInstance, &CanInstance, + CAN_DEVICE_ID, CAN_INTR_VEC_ID); + if (Status != XST_SUCCESS) { + xil_printf("CAN Watermark Example Test Failed\r\n"); + return XST_FAILURE; + } + + xil_printf("Successfully ran CAN Watermark Example Test\r\n"); + return XST_SUCCESS; +} + +/*****************************************************************************/ +/** +* +* The main entry point for showing the usage of XCanPs driver in interrupt +* mode. The example configures the device for internal loop back mode, then +* sends multiple CAN frames and receives the same number of CAN frame's +* using the Rx Watermark Interrupt. +* +* @param IntcInstPtr is a pointer to the instance of the ScuGic driver. +* @param CanInstPtr is a pointer to the instance of the CAN driver which +* is going to be connected to the interrupt controller. +* @param CanDeviceId is the device Id of the CAN device and is typically +* XPAR_
+* MODIFICATION HISTORY: +* +* Ver Who Date Changes +* ----- ----- -------- ----------------------------------------------- +* 1.00a xd/sv 01/12/10 First release +* 1.01a bss 12/27/11 Added the APIs XCanPs_SetTxIntrWatermark and +* XCanPs_GetTxIntrWatermark. +*+* +******************************************************************************/ + +/***************************** Include Files *********************************/ + +#include "xcanps.h" + +/************************** Constant Definitions *****************************/ + +/**************************** Type Definitions *******************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ + +/************************** Variable Definitions *****************************/ + +/************************** Function Prototypes ******************************/ + +static void StubHandler(void); + +/*****************************************************************************/ +/* +* +* This function initializes a XCanPs instance/driver. +* +* The initialization entails: +* - Initialize all members of the XCanPs structure. +* - Reset the CAN device. The CAN device will enter Configuration Mode +* immediately after the reset is finished. +* +* @param InstancePtr is a pointer to the XCanPs instance. +* @param ConfigPtr points to the XCanPs device configuration structure. +* @param EffectiveAddr is the device base address in the virtual memory +* address space. If the address translation is not used then the +* physical address is passed. +* Unexpected errors may occur if the address mapping is changed +* after this function is invoked. +* +* @return XST_SUCCESS always. +* +* @note None. +* +******************************************************************************/ +int XCanPs_CfgInitialize(XCanPs *InstancePtr, XCanPs_Config *ConfigPtr, + u32 EffectiveAddr) +{ + + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(ConfigPtr != NULL); + + /* + * Set some default values for instance data, don't indicate the device + * is ready to use until everything has been initialized successfully. + */ + InstancePtr->IsReady = 0; + InstancePtr->CanConfig.BaseAddr = EffectiveAddr; + InstancePtr->CanConfig.DeviceId = ConfigPtr->DeviceId; + + /* + * Set all handlers to stub values, let user configure this data later. + */ + InstancePtr->SendHandler = (XCanPs_SendRecvHandler) StubHandler; + InstancePtr->RecvHandler = (XCanPs_SendRecvHandler) StubHandler; + InstancePtr->ErrorHandler = (XCanPs_ErrorHandler) StubHandler; + InstancePtr->EventHandler = (XCanPs_EventHandler) StubHandler; + + /* + * Indicate the component is now ready to use. + */ + InstancePtr->IsReady = XIL_COMPONENT_IS_READY; + + /* + * Reset the device to get it into its initial state. + */ + XCanPs_Reset(InstancePtr); + + return XST_SUCCESS; +} + +/*****************************************************************************/ +/** +* +* This function resets the CAN device. Calling this function resets the device +* immediately, and any pending transmission or reception is terminated at once. +* Both Object Layer and Transfer Layer are reset. This function does not reset +* the Physical Layer. All registers are reset to the default values, and no +* previous status will be restored. TX FIFO, RX FIFO and TX High Priority +* Buffer are also reset. +* +* When a reset is required due to an internal error, the driver notifies the +* upper layer software of this need through the error status code or interrupts. +* The upper layer software is responsible for calling this Reset function and +* then re-configuring the device. +* +* The CAN device will be in Configuration Mode immediately after this function +* returns. +* +* @param InstancePtr is a pointer to the XCanPs instance. +* +* @return None. +* +* @note None. +* +******************************************************************************/ +void XCanPs_Reset(XCanPs *InstancePtr) +{ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr, XCANPS_SRR_OFFSET, \ + XCANPS_SRR_SRST_MASK); +} + +/****************************************************************************/ +/** +* +* This routine returns the current operation mode of the CAN device. +* +* @param InstancePtr is a pointer to the XCanPs instance. +* +* @return +* - XCANPS_MODE_CONFIG if the device is in Configuration Mode. +* - XCANPS_MODE_SLEEP if the device is in Sleep Mode. +* - XCANPS_MODE_NORMAL if the device is in Normal Mode. +* - XCANPS_MODE_LOOPBACK if the device is in Loop Back Mode. +* - XCANPS_MODE_SNOOP if the device is in Snoop Mode. +* +* @note None. +* +*****************************************************************************/ +u8 XCanPs_GetMode(XCanPs *InstancePtr) +{ + u32 StatusReg; + + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + StatusReg = XCanPs_GetStatus(InstancePtr); + + if (StatusReg & XCANPS_SR_CONFIG_MASK) { + return XCANPS_MODE_CONFIG; + + } else if (StatusReg & XCANPS_SR_SLEEP_MASK) { + return XCANPS_MODE_SLEEP; + + } else if (StatusReg & XCANPS_SR_NORMAL_MASK) { + if (StatusReg & XCANPS_SR_SNOOP_MASK) { + return XCANPS_MODE_SNOOP; + } else { + return XCANPS_MODE_NORMAL; + } + } else { + /* + * If this line is reached, the device is in Loop Back Mode. + */ + return XCANPS_MODE_LOOPBACK; + } +} + +/*****************************************************************************/ +/** +* +* This function allows the CAN device to enter one of the following operation +* modes: +* - Configuration Mode: Pass in parameter XCANPS_MODE_CONFIG +* - Sleep Mode: Pass in parameter XCANPS_MODE_SLEEP +* - Normal Mode: Pass in parameter XCANPS_MODE_NORMAL +* - Loop Back Mode: Pass in parameter XCANPS_MODE_LOOPBACK. +* - Snoop Mode: Pass in parameter XCANPS_MODE_SNOOP. +* +* Read the xcanps.h file and device specification for detailed description of +* each operation mode. +* +* @param InstancePtr is a pointer to the XCanPs instance. +* @param OperationMode specify which operation mode to enter. Valid value +* is any of XCANPS_MODE_* defined in xcanps.h. Multiple modes +* can not be entered at the same time. +* +* @return None. +* +* @note +* +* This function does NOT ensure CAN device enters the specified operation mode +* before it returns the control to the caller. The caller is responsible for +* checking current operation mode using XCanPs_GetMode(). +* +******************************************************************************/ +void XCanPs_EnterMode(XCanPs *InstancePtr, u8 OperationMode) +{ + u8 CurrentMode; + + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + Xil_AssertVoid((OperationMode == XCANPS_MODE_CONFIG) || + (OperationMode == XCANPS_MODE_SLEEP) || + (OperationMode == XCANPS_MODE_NORMAL) || + (OperationMode == XCANPS_MODE_LOOPBACK) || + (OperationMode == XCANPS_MODE_SNOOP)); + + CurrentMode = XCanPs_GetMode(InstancePtr); + + /* + * If current mode is Normal Mode and the mode to enter is Sleep Mode, + * or if current mode is Sleep Mode and the mode to enter is Normal + * Mode, no transition through Configuration Mode is needed. + */ + if ((CurrentMode == XCANPS_MODE_NORMAL) && + (OperationMode == XCANPS_MODE_SLEEP)) { + /* + * Normal Mode ---> Sleep Mode + */ + XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr, + XCANPS_MSR_OFFSET, XCANPS_MSR_SLEEP_MASK); + return; + + } else if ((CurrentMode == XCANPS_MODE_SLEEP) && + (OperationMode == XCANPS_MODE_NORMAL)) { + /* + * Sleep Mode ---> Normal Mode + */ + XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr, + XCANPS_MSR_OFFSET, 0); + return; + } + + + /* + * If the mode transition is not any of the two cases above, CAN must + * enter Configuration Mode before switching into the target operation + * mode. + */ + XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr, + XCANPS_SRR_OFFSET, 0); + + /* + * Check if the device has entered Configuration Mode, if not, return to + * the caller. + */ + if (XCanPs_GetMode(InstancePtr) != XCANPS_MODE_CONFIG) { + return; + } + + switch (OperationMode) { + case XCANPS_MODE_CONFIG: + /* + * As CAN is in Configuration Mode already. + * Nothing is needed to be done here. + */ + break; + + case XCANPS_MODE_SLEEP: + XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr, + XCANPS_MSR_OFFSET, XCANPS_MSR_SLEEP_MASK); + XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr, + XCANPS_SRR_OFFSET, XCANPS_SRR_CEN_MASK); + break; + + case XCANPS_MODE_NORMAL: + XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr, + XCANPS_MSR_OFFSET, 0); + XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr, + XCANPS_SRR_OFFSET, XCANPS_SRR_CEN_MASK); + break; + + case XCANPS_MODE_LOOPBACK: + XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr, + XCANPS_MSR_OFFSET, XCANPS_MSR_LBACK_MASK); + XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr, + XCANPS_SRR_OFFSET, XCANPS_SRR_CEN_MASK); + break; + + case XCANPS_MODE_SNOOP: + XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr, + XCANPS_MSR_OFFSET, XCANPS_MSR_SNOOP_MASK); + XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr, + XCANPS_SRR_OFFSET, XCANPS_SRR_CEN_MASK); + break; + + } +} + +/*****************************************************************************/ +/** +* +* This function returns Status value from Status Register (SR). Use the +* XCANPS_SR_* constants defined in xcanps_hw.h to interpret the returned +* value. +* +* @param InstancePtr is a pointer to the XCanPs instance. +* +* @return The 32-bit value read from Status Register. +* +* @note None. +* +******************************************************************************/ +u32 XCanPs_GetStatus(XCanPs *InstancePtr) +{ + + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + return XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr, + XCANPS_SR_OFFSET); +} + +/*****************************************************************************/ +/** +* +* This function reads Receive and Transmit error counters. +* +* @param InstancePtr is a pointer to the XCanPs instance. +* @param RxErrorCount is a pointer to data in which the Receive Error +* counter value is returned. +* @param TxErrorCount is a pointer to data in which the Transmit Error +* counter value is returned. +* +* @return None. +* +* @note None. +* +******************************************************************************/ +void XCanPs_GetBusErrorCounter(XCanPs *InstancePtr, u8 *RxErrorCount, + u8 *TxErrorCount) +{ + u32 ErrorCount; + + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + Xil_AssertVoid(RxErrorCount != NULL); + Xil_AssertVoid(TxErrorCount != NULL); + /* + * Read Error Counter Register and parse it. + */ + ErrorCount = XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr, + XCANPS_ECR_OFFSET); + *RxErrorCount = (ErrorCount & XCANPS_ECR_REC_MASK) >> + XCANPS_ECR_REC_SHIFT; + *TxErrorCount = ErrorCount & XCANPS_ECR_TEC_MASK; +} + +/*****************************************************************************/ +/** +* +* This function reads Error Status value from Error Status Register (ESR). Use +* the XCANPS_ESR_* constants defined in xcanps_hw.h to interpret the +* returned value. +* +* @param InstancePtr is a pointer to the XCanPs instance. +* +* @return The 32-bit value read from Error Status Register. +* +* @note None. +* +******************************************************************************/ +u32 XCanPs_GetBusErrorStatus(XCanPs *InstancePtr) +{ + + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + return XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr, + XCANPS_ESR_OFFSET); +} + +/*****************************************************************************/ +/** +* +* This function clears Error Status bit(s) previously set in Error +* Status Register (ESR). Use the XCANPS_ESR_* constants defined in xcanps_hw.h +* to create the value to pass in. If a bit was cleared in Error Status Register +* before this function is called, it will not be modified. +* +* @param InstancePtr is a pointer to the XCanPs instance. +* +* @param Mask is he 32-bit mask used to clear bits in Error Status +* Register. Multiple XCANPS_ESR_* values can be 'OR'ed to clear +* multiple bits. +* +* @note None. +* +******************************************************************************/ +void XCanPs_ClearBusErrorStatus(XCanPs *InstancePtr, u32 Mask) +{ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr, + XCANPS_ESR_OFFSET, Mask); +} + +/*****************************************************************************/ +/** +* +* This function sends a CAN Frame. If the TX FIFO is not full then the given +* frame is written into the the TX FIFO otherwise, it returns an error code +* immediately. +* This function does not wait for the given frame being sent to CAN bus. +* +* @param InstancePtr is a pointer to the XCanPs instance. +* @param FramePtr is a pointer to a 32-bit aligned buffer containing the +* CAN frame to be sent. +* +* @return +* - XST_SUCCESS if TX FIFO was not full and the given frame was +* written into the FIFO. +* - XST_FIFO_NO_ROOM if there is no room in the TX FIFO for the +* given frame. +* +* @note None. +* +******************************************************************************/ +int XCanPs_Send(XCanPs *InstancePtr, u32 *FramePtr) +{ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(FramePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + if (XCanPs_IsTxFifoFull(InstancePtr) == TRUE) { + return XST_FIFO_NO_ROOM; + } + + /* + * Write IDR, DLC, Data Word 1 and Data Word 2 to the CAN device. + */ + XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr, + XCANPS_TXFIFO_ID_OFFSET, FramePtr[0]); + XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr, + XCANPS_TXFIFO_DLC_OFFSET, FramePtr[1]); + XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr, + XCANPS_TXFIFO_DW1_OFFSET, FramePtr[2]); + XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr, + XCANPS_TXFIFO_DW2_OFFSET, FramePtr[3]); + + return XST_SUCCESS; +} + +/*****************************************************************************/ +/** +* +* This function receives a CAN Frame. This function first checks if RX FIFO is +* empty, if not, it then reads a frame from the RX FIFO into the given buffer. +* This function returns error code immediately if there is no frame in the RX +* FIFO. +* +* @param InstancePtr is a pointer to the XCanPs instance. +* @param FramePtr is a pointer to a 32-bit aligned buffer where the CAN +* frame to be written. +* +* @return +* - XST_SUCCESS if RX FIFO was not empty and a frame was read from +* RX FIFO successfully and written into the given buffer. +* - XST_NO_DATA if there is no frame to be received from the FIFO. +* +* @note None. +* +******************************************************************************/ +int XCanPs_Recv(XCanPs *InstancePtr, u32 *FramePtr) +{ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(FramePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + if (XCanPs_IsRxEmpty(InstancePtr) == TRUE) { + return XST_NO_DATA; + } + + /* + * Read IDR, DLC, Data Word 1 and Data Word 2 from the CAN device. + */ + FramePtr[0] = XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr, + XCANPS_RXFIFO_ID_OFFSET); + FramePtr[1] = XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr, + XCANPS_RXFIFO_DLC_OFFSET); + FramePtr[2] = XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr, + XCANPS_RXFIFO_DW1_OFFSET); + FramePtr[3] = XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr, + XCANPS_RXFIFO_DW2_OFFSET); + + /* + * Clear RXNEMP bit in ISR. This allows future XCanPs_IsRxEmpty() call + * returns correct RX FIFO occupancy/empty condition. + */ + XCanPs_IntrClear(InstancePtr, XCANPS_IXR_RXNEMP_MASK); + + return XST_SUCCESS; +} + +/*****************************************************************************/ +/** +* +* This routine sends a CAN High Priority frame. This function first checks if +* TX High Priority Buffer is empty. If yes, it then writes the given frame into +* the Buffer. If not, this function returns immediately. This function does not +* wait for the given frame being sent to CAN bus. +* +* @param InstancePtr is a pointer to the XCanPs instance. +* @param FramePtr is a pointer to a 32-bit aligned buffer containing the +* CAN High Priority frame to be sent. +* +* @return +* - XST_SUCCESS if TX High Priority Buffer was not full and the +* given frame was written into the buffer; +* - XST_FIFO_NO_ROOM if there is no room in the TX High Priority +* Buffer for this frame. +* +* @note +* +* If the frame needs to be sent immediately and not delayed by processor's +* interrupt handling, the caller should disable interrupt at processor +* level before invoking this function. +* +******************************************************************************/ +int XCanPs_SendHighPriority(XCanPs *InstancePtr, u32 *FramePtr) +{ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(FramePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + if (XCanPs_IsHighPriorityBufFull(InstancePtr) == TRUE) { + return XST_FIFO_NO_ROOM; + } + + /* + * Write IDR, DLC, Data Word 1 and Data Word 2 to the CAN device. + */ + XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr, + XCANPS_TXHPB_ID_OFFSET, FramePtr[0]); + XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr, + XCANPS_TXHPB_DLC_OFFSET, FramePtr[1]); + XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr, + XCANPS_TXHPB_DW1_OFFSET, FramePtr[2]); + XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr, + XCANPS_TXHPB_DW2_OFFSET, FramePtr[3]); + + return XST_SUCCESS; +} + +/*****************************************************************************/ +/** +* +* This routine enables individual acceptance filters. Up to 4 filters could +* be enabled. +* +* @param InstancePtr is a pointer to the XCanPs instance. +* @param FilterIndexes specifies which filter(s) to enable. Use +* any XCANPS_AFR_UAF*_MASK to enable one filter, and "Or" +* multiple XCANPS_AFR_UAF*_MASK values if multiple filters need +* to be enabled. Any filter not specified in this parameter will +* keep its previous enable/disable setting. +* +* @return None. +* +* @note None. +* +* +******************************************************************************/ +void XCanPs_AcceptFilterEnable(XCanPs *InstancePtr, u32 FilterIndexes) +{ + u32 EnabledFilters; + + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Calculate the new value and write to AFR. + */ + EnabledFilters = XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr, + XCANPS_AFR_OFFSET); + EnabledFilters |= FilterIndexes; + EnabledFilters &= XCANPS_AFR_UAF_ALL_MASK; + XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr, XCANPS_AFR_OFFSET, + EnabledFilters); +} + +/*****************************************************************************/ +/** +* +* This routine disables individual acceptance filters. Up to 4 filters could +* be disabled. If all acceptance filters are disabled then all the received +* frames are stored in the RX FIFO. +* +* @param InstancePtr is a pointer to the XCanPs instance. +* @param FilterIndexes specifies which filter(s) to disable. Use +* any XCANPS_AFR_UAF*_MASK to disable one filter, and "Or" +* multiple XCANPS_AFR_UAF*_MASK values if multiple filters need +* to be disabled. Any filter not specified in this parameter will +* keep its previous enable/disable setting. If all acceptance +* filters are disabled then all received frames are stored in the +* RX FIFO. +* +* @return None. +* +* @note None. +* +******************************************************************************/ +void XCanPs_AcceptFilterDisable(XCanPs *InstancePtr, u32 FilterIndexes) +{ + u32 EnabledFilters; + + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Calculate the new value and write to AFR. + */ + EnabledFilters = XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr, + XCANPS_AFR_OFFSET); + EnabledFilters &= XCANPS_AFR_UAF_ALL_MASK & (~FilterIndexes); + XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr, XCANPS_AFR_OFFSET, + EnabledFilters); +} + +/*****************************************************************************/ +/** +* +* This function returns enabled acceptance filters. Use XCANPS_AFR_UAF*_MASK +* defined in xcanps_hw.h to interpret the returned value. If no acceptance +* filters are enabled then all received frames are stored in the RX FIFO. +* +* @param InstancePtr is a pointer to the XCanPs instance. +* +* @return The value stored in Acceptance Filter Register. +* +* @note None. +* +* +******************************************************************************/ +u32 XCanPs_AcceptFilterGetEnabled(XCanPs *InstancePtr) +{ + + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + return XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr, + XCANPS_AFR_OFFSET); + +} + +/*****************************************************************************/ +/** +* +* This function sets values to the Acceptance Filter Mask Register (AFMR) and +* Acceptance Filter ID Register (AFIR) for the specified Acceptance Filter. +* Use XCANPS_IDR_* defined in xcanps_hw.h to create the values to set the +* filter. Read the xcanps.h file and device specification for details. +* +* This function should be called only after: +* - The given filter is disabled by calling XCanPs_AcceptFilterDisable(); +* - And the CAN device is ready to accept writes to AFMR and AFIR, i.e., +* XCanPs_IsAcceptFilterBusy() returns FALSE. +* +* @param InstancePtr is a pointer to the XCanPs instance. +* @param FilterIndex defines which Acceptance Filter Mask and ID Register +* to set. Use any single XCANPS_AFR_UAF*_MASK value. +* @param MaskValue is the value to write to the chosen Acceptance Filter +* Mask Register. +* @param IdValue is the value to write to the chosen Acceptance Filter +* ID Register. +* +* @return +* - XST_SUCCESS if the values were set successfully. +* - XST_FAILURE if the given filter was not disabled, or the CAN +* device was not ready to accept writes to AFMR and AFIR. +* +* @note None. +* +******************************************************************************/ +int XCanPs_AcceptFilterSet(XCanPs *InstancePtr, u32 FilterIndex, + u32 MaskValue, u32 IdValue) +{ + u32 EnabledFilters; + + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + Xil_AssertNonvoid((FilterIndex == XCANPS_AFR_UAF4_MASK) || + (FilterIndex == XCANPS_AFR_UAF3_MASK) || + (FilterIndex == XCANPS_AFR_UAF2_MASK) || + (FilterIndex == XCANPS_AFR_UAF1_MASK)); + + /* + * Return an error if the given filter is currently enabled. + */ + EnabledFilters = XCanPs_AcceptFilterGetEnabled(InstancePtr); + if ((EnabledFilters & FilterIndex) == FilterIndex) { + return XST_FAILURE; + } + + /* + * If the CAN device is not ready to accept writes to AFMR and AFIR, + * return error code. + */ + if (XCanPs_IsAcceptFilterBusy(InstancePtr) == TRUE) { + return XST_FAILURE; + } + + /* + * Write to the AFMR and AFIR of the specified filter. + */ + switch (FilterIndex) { + case XCANPS_AFR_UAF1_MASK: /* Acceptance Filter No. 1 */ + + XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr, + XCANPS_AFMR1_OFFSET, MaskValue); + XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr, + XCANPS_AFIR1_OFFSET, IdValue); + break; + + case XCANPS_AFR_UAF2_MASK: /* Acceptance Filter No. 2 */ + XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr, + XCANPS_AFMR2_OFFSET, MaskValue); + XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr, + XCANPS_AFIR2_OFFSET, IdValue); + break; + + case XCANPS_AFR_UAF3_MASK: /* Acceptance Filter No. 3 */ + XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr, + XCANPS_AFMR3_OFFSET, MaskValue); + XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr, + XCANPS_AFIR3_OFFSET, IdValue); + break; + + case XCANPS_AFR_UAF4_MASK: /* Acceptance Filter No. 4 */ + XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr, + XCANPS_AFMR4_OFFSET, MaskValue); + XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr, + XCANPS_AFIR4_OFFSET, IdValue); + break; + } + + return XST_SUCCESS; +} + +/*****************************************************************************/ +/** +* +* This function reads the values of the Acceptance Filter Mask and ID Register +* for the specified Acceptance Filter. Use XCANPS_IDR_* defined in xcanps_hw.h +* to interpret the values. Read the xcanps.h file and device specification for +* details. +* +* @param InstancePtr is a pointer to the XCanPs instance. +* @param FilterIndex defines which Acceptance Filter Mask Register to get +* Mask and ID from. Use any single XCANPS_FILTER_* value. +* @param MaskValue is a pointer to the data in which the Mask value read +* from the chosen Acceptance Filter Mask Register is returned. +* @param IdValue is a pointer to the data in which the ID value read +* from the chosen Acceptance Filter ID Register is returned. +* +* @return None. +* +* @note None. +* +******************************************************************************/ +void XCanPs_AcceptFilterGet(XCanPs *InstancePtr, u32 FilterIndex, + u32 *MaskValue, u32 *IdValue) +{ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + Xil_AssertVoid((FilterIndex == XCANPS_AFR_UAF4_MASK) || + (FilterIndex == XCANPS_AFR_UAF3_MASK) || + (FilterIndex == XCANPS_AFR_UAF2_MASK) || + (FilterIndex == XCANPS_AFR_UAF1_MASK)); + Xil_AssertVoid(MaskValue != NULL); + Xil_AssertVoid(IdValue != NULL); + + /* + * Read from the AFMR and AFIR of the specified filter. + */ + switch (FilterIndex) { + case XCANPS_AFR_UAF1_MASK: /* Acceptance Filter No. 1 */ + *MaskValue = XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr, + XCANPS_AFMR1_OFFSET); + *IdValue = XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr, + XCANPS_AFIR1_OFFSET); + break; + + case XCANPS_AFR_UAF2_MASK: /* Acceptance Filter No. 2 */ + *MaskValue = XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr, + XCANPS_AFMR2_OFFSET); + *IdValue = XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr, + XCANPS_AFIR2_OFFSET); + break; + + case XCANPS_AFR_UAF3_MASK: /* Acceptance Filter No. 3 */ + *MaskValue = XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr, + XCANPS_AFMR3_OFFSET); + *IdValue = XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr, + XCANPS_AFIR3_OFFSET); + break; + + case XCANPS_AFR_UAF4_MASK: /* Acceptance Filter No. 4 */ + *MaskValue = XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr, + XCANPS_AFMR4_OFFSET); + *IdValue = XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr, + XCANPS_AFIR4_OFFSET); + break; + } +} + +/*****************************************************************************/ +/** +* +* This routine sets Baud Rate Prescaler value. The system clock for the CAN +* controller is divided by (Prescaler + 1) to generate the quantum clock +* needed for sampling and synchronization. Read the device specification +* for details. +* +* Baud Rate Prescaler can be set only if the CAN device is in Configuration +* Mode. Call XCanPs_EnterMode() to enter Configuration Mode before using this +* function. +* +* @param InstancePtr is a pointer to the XCanPs instance. +* @param Prescaler is the value to set. Valid values are from 0 to 255. +* +* @return +* - XST_SUCCESS if the Baud Rate Prescaler value is set +* successfully. +* - XST_FAILURE if CAN device is not in Configuration Mode. +* +* @note None. +* +******************************************************************************/ +int XCanPs_SetBaudRatePrescaler(XCanPs *InstancePtr, u8 Prescaler) +{ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + if (XCanPs_GetMode(InstancePtr) != XCANPS_MODE_CONFIG) { + return XST_FAILURE; + } + + XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr, XCANPS_BRPR_OFFSET, + (u32)Prescaler); + + return XST_SUCCESS; +} + +/*****************************************************************************/ +/** +* +* This routine gets Baud Rate Prescaler value. The system clock for the CAN +* controller is divided by (Prescaler + 1) to generate the quantum clock +* needed for sampling and synchronization. Read the device specification for +* details. +* +* @param InstancePtr is a pointer to the XCanPs instance. +* +* @return Current used Baud Rate Prescaler value. The value's range is +* from 0 to 255. +* +* @note None. +* +******************************************************************************/ +u8 XCanPs_GetBaudRatePrescaler(XCanPs *InstancePtr) +{ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + return (u8) XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr, + XCANPS_BRPR_OFFSET); + +} + +/*****************************************************************************/ +/** +* +* This routine sets Bit time. Time segment 1, Time segment 2 and +* Synchronization Jump Width are set in this function. Device specification +* requires the values passed into this function be one less than the actual +* values of these fields. Read the device specification for details. +* +* Bit time can be set only if the CAN device is in Configuration Mode. +* Call XCanPs_EnterMode() to enter Configuration Mode before using this +* function. +* +* @param InstancePtr is a pointer to the XCanPs instance. +* @param SyncJumpWidth is the Synchronization Jump Width value to set. +* Valid values are from 0 to 3. +* @param TimeSegment2 is the Time Segment 2 value to set. Valid values +* are from 0 to 7. +* @param TimeSegment1 is the Time Segment 1 value to set. Valid values +* are from 0 to 15. +* +* @return +* - XST_SUCCESS if the Bit time is set successfully. +* - XST_FAILURE if CAN device is not in Configuration Mode. +* +* @note None. +* +******************************************************************************/ +int XCanPs_SetBitTiming(XCanPs *InstancePtr, u8 SyncJumpWidth, + u8 TimeSegment2, u8 TimeSegment1) +{ + u32 Value; + + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + Xil_AssertNonvoid(SyncJumpWidth <= 3); + Xil_AssertNonvoid(TimeSegment2 <= 7); + Xil_AssertNonvoid(TimeSegment1 <= 15 ); + + if (XCanPs_GetMode(InstancePtr) != XCANPS_MODE_CONFIG) { + return XST_FAILURE; + } + + Value = ((u32) TimeSegment1) & XCANPS_BTR_TS1_MASK; + Value |= (((u32) TimeSegment2) << XCANPS_BTR_TS2_SHIFT) & + XCANPS_BTR_TS2_MASK; + Value |= (((u32) SyncJumpWidth) << XCANPS_BTR_SJW_SHIFT) & + XCANPS_BTR_SJW_MASK; + + XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr, + XCANPS_BTR_OFFSET, Value); + + return XST_SUCCESS; +} + +/*****************************************************************************/ +/** +* +* This routine gets Bit time. Time segment 1, Time segment 2 and +* Synchronization Jump Width values are read in this function. According to +* device specification, the actual value of each of these fields is one +* more than the value read. Read the device specification for details. +* +* @param InstancePtr is a pointer to the XCanPs instance. +* @param SyncJumpWidth will store the Synchronization Jump Width value +* after this function returns. Its value ranges from 0 to 3. +* @param TimeSegment2 will store the Time Segment 2 value after this +* function returns. Its value ranges from 0 to 7. +* @param TimeSegment1 will store the Time Segment 1 value after this +* function returns. Its value ranges from 0 to 15. +* +* @return None. +* +* @note None. +* +******************************************************************************/ +void XCanPs_GetBitTiming(XCanPs *InstancePtr, u8 *SyncJumpWidth, + u8 *TimeSegment2, u8 *TimeSegment1) +{ + u32 Value; + + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + Xil_AssertVoid(SyncJumpWidth != NULL); + Xil_AssertVoid(TimeSegment2 != NULL); + Xil_AssertVoid(TimeSegment1 != NULL); + + Value = XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr, + XCANPS_BTR_OFFSET); + + *TimeSegment1 = (u8) (Value & XCANPS_BTR_TS1_MASK); + *TimeSegment2 = + (u8) ((Value & XCANPS_BTR_TS2_MASK) >> XCANPS_BTR_TS2_SHIFT); + *SyncJumpWidth = + (u8) ((Value & XCANPS_BTR_SJW_MASK) >> XCANPS_BTR_SJW_SHIFT); +} + + +/****************************************************************************/ +/** +* +* This routine sets the Rx Full threshold in the Watermark Interrupt Register. +* +* @param InstancePtr is a pointer to the XCanPs instance. +* @param Threshold is the threshold to be set. The valid values are +* from 1 to 63. +* +* @return +* - XST_FAILURE - If the CAN device is not in Configuration Mode. +* - XST_SUCCESS - If the Rx Full threshold is set in Watermark +* Interrupt Register. +* +* @note The threshold can only be set when the CAN device is in the +* configuration mode. +* +*****************************************************************************/ +int XCanPs_SetRxIntrWatermark(XCanPs *InstancePtr, u8 Threshold) +{ + + u32 ThrReg; + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + Xil_AssertNonvoid(Threshold <= 63); + + if (XCanPs_GetMode(InstancePtr) != XCANPS_MODE_CONFIG) + return XST_FAILURE; + + ThrReg = XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr, + XCANPS_WIR_OFFSET); + + ThrReg &= XCANPS_WIR_EW_MASK; + ThrReg |= ((u32)Threshold & XCANPS_WIR_FW_MASK); + XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr, + XCANPS_WIR_OFFSET, ThrReg); + + return XST_SUCCESS; +} + +/****************************************************************************/ +/** +* +* This routine gets the Rx Full threshold from the Watermark Interrupt Register. +* +* @param InstancePtr is a pointer to the XCanPs instance. +* +* @return The Rx FIFO full watermark threshold value. The valid values +* are 1 to 63. +* +* @note None. +* +*****************************************************************************/ +u8 XCanPs_GetRxIntrWatermark(XCanPs *InstancePtr) +{ + + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + + return (u8) (XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr, + XCANPS_WIR_OFFSET) & + XCANPS_WIR_FW_MASK); +} + + +/****************************************************************************/ +/** +* +* This routine sets the Tx Empty Threshold in the Watermark Interrupt Register. +* +* @param InstancePtr is a pointer to the XCanPs instance. +* @param Threshold is the threshold to be set. The valid values are +* from 1 to 63. +* +* @return +* - XST_FAILURE - If the CAN device is not in Configuration Mode. +* - XST_SUCCESS - If the threshold is set in Watermark +* Interrupt Register. +* +* @note The threshold can only be set when the CAN device is in the +* configuration mode. +* +*****************************************************************************/ +int XCanPs_SetTxIntrWatermark(XCanPs *InstancePtr, u8 Threshold) +{ + u32 ThrReg; + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + Xil_AssertNonvoid(Threshold <= 63); + + if (XCanPs_GetMode(InstancePtr) != XCANPS_MODE_CONFIG) + return XST_FAILURE; + + ThrReg = XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr, + XCANPS_WIR_OFFSET); + + ThrReg &= XCANPS_WIR_FW_MASK; + ThrReg |= ((u32)(Threshold << XCANPS_WIR_EW_SHIFT) + & XCANPS_WIR_EW_MASK); + XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr, + XCANPS_WIR_OFFSET, ThrReg); + + return XST_SUCCESS; +} + +/****************************************************************************/ +/** +* +* This routine gets the Tx Empty threshold from Watermark Interrupt Register. +* +* @param InstancePtr is a pointer to the XCanPs instance. +* +* @return The Tx Empty FIFO threshold value. The valid values are 1 to 63. +* +* @note None. +* +*****************************************************************************/ +u8 XCanPs_GetTxIntrWatermark(XCanPs *InstancePtr) +{ + + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + + return (u8) ((XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr, + XCANPS_WIR_OFFSET) & XCANPS_WIR_EW_MASK) >> + XCANPS_WIR_EW_SHIFT); +} + + + +/******************************************************************************/ +/* + * This routine is a stub for the asynchronous callbacks. The stub is here in + * case the upper layer forgot to set the handler(s). On initialization, all + * handlers are set to this callback. It is considered an error for this handler + * to be invoked. + * + ******************************************************************************/ +static void StubHandler(void) +{ + Xil_AssertVoidAlways(); +} diff --git a/XilinxProcessorIPLib/drivers/canps/src/xcanps.h b/XilinxProcessorIPLib/drivers/canps/src/xcanps.h new file mode 100755 index 00000000..6c3c4f44 --- /dev/null +++ b/XilinxProcessorIPLib/drivers/canps/src/xcanps.h @@ -0,0 +1,562 @@ +/****************************************************************************** +* +* 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 xcanps.h +* +* The Xilinx CAN driver component. This component supports the Xilinx +* CAN Controller. +* +* The CAN Controller supports the following features: +* - Confirms to the ISO 11898-1, CAN 2.0A and CAN 2.0B standards. +* - Supports both Standard (11 bit Identifier) and Extended (29 bit +* Identifier) frames. +* - Supports Bit Rates up to 1 Mbps. +* - Transmit message object FIFO with a user configurable depth of +* up to 64 message objects. +* - Transmit prioritization through one TX High Priority Buffer. +* - Receive message object FIFO with a user configurable depth of +* up to 64 message objects. +* - Watermark interrupts for Rx FIFO with configurable Watermark. +* - Acceptance filtering with 4 acceptance filters. +* - Sleep mode with automatic wake up. +* - Loop Back mode for diagnostic applications. +* - Snoop mode for diagnostic applications. +* - Maskable Error and Status Interrupts. +* - Readable Error Counters. +* - External PHY chip required. +* - Receive Timestamp. +* +* The device driver supports all the features listed above, if applicable. +* +* Driver Description +* +* The device driver enables higher layer software (e.g., an application) to +* communicate to the CAN. The driver handles transmission and reception of +* CAN frames, as well as configuration of the controller. The driver is simply a +* pass-through mechanism between a protocol stack and the CAN. A single device +* driver can support multiple CANs. +* +* Since the driver is a simple pass-through mechanism between a protocol stack +* and the CAN, no assembly or disassembly of CAN frames is done at the +* driver-level. This assumes that the protocol stack passes a correctly +* formatted CAN frame to the driver for transmission, and that the driver +* does not validate the contents of an incoming frame +* +* Operation Modes +* +* The CAN controller supports the following modes of operation: +* - Configuration Mode: In this mode the CAN timing parameters and +* Baud Rate Pre-scalar parameters can be changed. In this mode the CAN +* controller loses synchronization with the CAN bus and drives a +* constant recessive bit on the bus line. The Error Counter Register are +* reset. The CAN controller does not receive or transmit any messages +* even if there are pending transmit requests from the TX FIFO or the TX +* High Priority Buffer. The Storage FIFOs and the CAN configuration +* registers are still accessible. +* - Normal Mode:In Normal Mode the CAN controller participates in bus +* communication, by transmitting and receiving messages. +* - Sleep Mode: In Sleep Mode the CAN Controller does not transmit any +* messages. However, if any other node transmits a message, then the CAN +* Controller receives the transmitted message and exits from Sleep Mode. +* If there are new transmission requests from either the TX FIFO or the +* TX High Priority Buffer when the CAN Controller is in Sleep Mode, these +* requests are not serviced, and the CAN Controller continues to remain +* in Sleep Mode. Interrupts are generated when the CAN controller enters +* Sleep mode or Wakes up from Sleep mode. +* - Loop Back Mode: In Loop Back mode, the CAN controller transmits a +* recessive bit stream on to the CAN Bus. Any message that is transmitted +* is looped back to the �Rx� line and acknowledged. The CAN controller +* thus receives any message that it transmits. It does not participate in +* normal bus communication and does not receive any messages that are +* transmitted by other CAN nodes. This mode is used for diagnostic +* purposes. +* - Snoop Mode: In Snoop mode, the CAN controller transmits a +* recessive bit stream on to the CAN Bus and does not participate +* in normal bus communication but receives messages that are transmitted +* by other CAN nodes. This mode is used for diagnostic purposes. +* +* +* Buffer Alignment +* +* It is important to note that frame buffers passed to the driver must be +* 32-bit aligned. +* +* Receive Address Filtering +* +* The device can be set to accept frames whose Identifiers match any of the +* 4 filters set in the Acceptance Filter Mask/ID registers. +* +* The incoming Identifier is masked with the bits in the Acceptance Filter Mask +* Register. This value is compared with the result of masking the bits in the +* Acceptance Filter ID Register with the Acceptance Filter Mask Register. If +* both these values are equal, the message will be stored in the RX FIFO. +* +* Acceptance Filtering is performed by each of the defined acceptance filters. +* If the incoming identifier passes through any acceptance filter then the +* frame is stored in the RX FIFO. +* +* If the Accpetance Filters are not set up then all the received messages are +* stroed in the RX FIFO. +* +* PHY Communication +* +* This driver does not provide any mechanism for directly programming PHY. +* +* Interrupts +* +* The driver has no dependencies on the interrupt controller. The driver +* provides an interrupt handler. User of this driver needs to provide +* callback functions. An interrupt handler example is available with +* the driver. +* +* Threads +* +* This driver is not thread safe. Any needs for threads or thread mutual +* exclusion must be satisfied by the layer above this driver. +* +* Device Reset +* +* Bus Off interrupt that can occur in the device requires a device reset. +* The user is responsible for resetting the device and re-configuring it +* based on its needs (the driver does not save the current configuration). +* When integrating into an RTOS, these reset and re-configure obligations are +* taken care of by the OS adapter software if it exists for that RTOS. +* +* Device Configuration +* +* The device can be configured in various ways during the FPGA implementation +* process. Configuration parameters are stored in the xcanps_g.c files. +* A table is defined where each entry contains configuration information +* for a CAN device. This information includes such things as the base address +* of the memory-mapped device. +* +* Asserts +* +* Asserts are used within all Xilinx drivers to enforce constraints on argument +* values. Asserts can be turned off on a system-wide basis by defining, at +* compile time, the NDEBUG identifier. By default, asserts are turned on and it +* is recommended that users leave asserts on during development. +* +* Building the driver +* +* The XCanPs driver is composed of several source files. This allows the user +* to build and link only those parts of the driver that are necessary. +*
+* MODIFICATION HISTORY: +* +* Ver Who Date Changes +* ----- ----- -------- ----------------------------------------------- +* 1.00a xd/sv 01/12/10 First release +* 1.01a bss 12/27/11 Added the APIs XCanPs_SetTxIntrWatermark and +* XCanPs_GetTxIntrWatermark. +* Updated the Register/bit definitions +* Changed XCANPS_RXFWIR_RXFLL_MASK to XCANPS_WIR_FW_MASK +* Changed XCANPS_RXWIR_OFFSET to XCANPS_WIR_OFFSET +* Added XCANPS_IXR_TXFEMP_MASK for Tx Fifo Empty +* Changed XCANPS_IXR_RXFLL_MASK to +* XCANPS_IXR_RXFWMFLL_MASK +* Changed +* XCANPS_TXBUF_ID_OFFSET to XCANPS_TXHPB_ID_OFFSET +* XCANPS_TXBUF_DLC_OFFSET to XCANPS_TXHPB_DLC_OFFSET +* XCANPS_TXBUF_DW1_OFFSET to XCANPS_TXHPB_DW1_OFFSET +* XCANPS_TXBUF_DW2_OFFSET to XCANPS_TXHPB_DW2_OFFSET +* 2.1 adk 23/08/14 Fixed CR:798792 Peripheral test for CANPS IP in +* SDK claims a 40kbps baud rate but it's not. +*+* +******************************************************************************/ +#ifndef XCANPS_H /* prevent circular inclusions */ +#define XCANPS_H /* by using protection macros */ + +#ifdef __cplusplus +extern "C" { +#endif + +/***************************** Include Files *********************************/ + +#include "xstatus.h" +#include "xcanps_hw.h" + +/************************** Constant Definitions *****************************/ + +/** @name CAN operation modes + * @{ + */ +#define XCANPS_MODE_CONFIG 0x00000001 /**< Configuration mode */ +#define XCANPS_MODE_NORMAL 0x00000002 /**< Normal mode */ +#define XCANPS_MODE_LOOPBACK 0x00000004 /**< Loop Back mode */ +#define XCANPS_MODE_SLEEP 0x00000008 /**< Sleep mode */ +#define XCANPS_MODE_SNOOP 0x00000010 /**< Snoop mode */ +/* @} */ + +/** @name Callback identifiers used as parameters to XCanPs_SetHandler() + * @{ + */ +#define XCANPS_HANDLER_SEND 1 /**< Handler type for frame sending interrupt */ +#define XCANPS_HANDLER_RECV 2 /**< Handler type for frame reception interrupt*/ +#define XCANPS_HANDLER_ERROR 3 /**< Handler type for error interrupt */ +#define XCANPS_HANDLER_EVENT 4 /**< Handler type for all other interrupts */ +/* @} */ + +/**************************** Type Definitions *******************************/ + +/** + * This typedef contains configuration information for a device. + */ +typedef struct { + u16 DeviceId; /**< Unique ID of device */ + u32 BaseAddr; /**< Register base address */ +} XCanPs_Config; + +/******************************************************************************/ +/** + * Callback type for frame sending and reception interrupts. + * + * @param CallBackRef is a 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. +*******************************************************************************/ +typedef void (*XCanPs_SendRecvHandler) (void *CallBackRef); + +/******************************************************************************/ +/** + * Callback type for error interrupt. + * + * @param CallBackRef is a 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. + * @param ErrorMask is a bit mask indicating the cause of the error. Its + * value equals 'OR'ing one or more XCANPS_ESR_* values defined in + * xcanps_hw.h +*******************************************************************************/ +typedef void (*XCanPs_ErrorHandler) (void *CallBackRef, u32 ErrorMask); + +/******************************************************************************/ +/** + * Callback type for all kinds of interrupts except sending frame interrupt, + * receiving frame interrupt, and error interrupt. + * + * @param CallBackRef is a 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. + * @param Mask is a bit mask indicating the pending interrupts. Its value + * equals 'OR'ing one or more XCANPS_IXR_* defined in xcanps_hw.h +*******************************************************************************/ +typedef void (*XCanPs_EventHandler) (void *CallBackRef, u32 Mask); + +/** + * The XCanPs driver instance data. The user is required to allocate a + * variable of this type for every CAN device in the system. A pointer + * to a variable of this type is then passed to the driver API functions. + */ +typedef struct { + XCanPs_Config CanConfig; /**< Device configuration */ + u32 IsReady; /**< Device is initialized and ready */ + + /** + * Callback and callback reference for TXOK interrupt. + */ + XCanPs_SendRecvHandler SendHandler; + void *SendRef; + + /** + * Callback and callback reference for RXOK/RXNEMP/RXFLL interrupts. + */ + XCanPs_SendRecvHandler RecvHandler; + void *RecvRef; + + /** + * Callback and callback reference for ERROR interrupt. + */ + XCanPs_ErrorHandler ErrorHandler; + void *ErrorRef; + + /** + * Callback and callback reference for RXOFLW/RXUFLW/TXBFLL/TXFLL/ + * Wakeup/Sleep/Bus off/ARBLST interrupts. + */ + XCanPs_EventHandler EventHandler; + void *EventRef; + +} XCanPs; + + +/***************** Macros (Inline Functions) Definitions *********************/ + +/****************************************************************************/ +/** +* +* This macro checks if the transmission is complete. +* +* @param InstancePtr is a pointer to the XCanPs instance. +* +* @return +* - TRUE if the transmission is done. +* - FALSE if the transmission is not done. +* +* @note C-Style signature: +* int XCanPs_IsTxDone(XCanPs *InstancePtr); +* +*******************************************************************************/ +#define XCanPs_IsTxDone(InstancePtr) \ + ((XCanPs_ReadReg(((InstancePtr)->CanConfig.BaseAddr), \ + XCANPS_ISR_OFFSET) & XCANPS_IXR_TXOK_MASK) ? TRUE : FALSE) + + +/****************************************************************************/ +/** +* +* This macro checks if the transmission FIFO is full. +* +* @param InstancePtr is a pointer to the XCanPs instance. +* +* @return +* - TRUE if TX FIFO is full. +* - FALSE if the TX FIFO is NOT full. +* +* @note C-Style signature: +* int XCanPs_IsTxFifoFull(XCanPs *InstancePtr); +* +*****************************************************************************/ +#define XCanPs_IsTxFifoFull(InstancePtr) \ + ((XCanPs_ReadReg(((InstancePtr)->CanConfig.BaseAddr), \ + XCANPS_SR_OFFSET) & XCANPS_SR_TXFLL_MASK) ? TRUE : FALSE) + + +/****************************************************************************/ +/** +* +* This macro checks if the Transmission High Priority Buffer is full. +* +* @param InstancePtr is a pointer to the XCanPs instance. +* +* @return +* - TRUE if the TX High Priority Buffer is full. +* - FALSE if the TX High Priority Buffer is NOT full. +* +* @note C-Style signature: +* int XCanPs_IsHighPriorityBufFull(XCanPs *InstancePtr); +* +*****************************************************************************/ +#define XCanPs_IsHighPriorityBufFull(InstancePtr) \ + ((XCanPs_ReadReg(((InstancePtr)->CanConfig.BaseAddr), \ + XCANPS_SR_OFFSET) & XCANPS_SR_TXBFLL_MASK) ? TRUE : FALSE) + + +/****************************************************************************/ +/** +* +* This macro checks if the receive FIFO is empty. +* +* @param InstancePtr is a pointer to the XCanPs instance. +* +* @return +* - TRUE if RX FIFO is empty. +* - FALSE if the RX FIFO is NOT empty. +* +* @note C-Style signature: +* int XCanPs_IsRxEmpty(XCanPs *InstancePtr); +* +*****************************************************************************/ +#define XCanPs_IsRxEmpty(InstancePtr) \ + ((XCanPs_ReadReg(((InstancePtr)->CanConfig.BaseAddr), \ + XCANPS_ISR_OFFSET) & XCANPS_IXR_RXNEMP_MASK) ? FALSE : TRUE) + + +/****************************************************************************/ +/** +* +* This macro checks if the CAN device is ready for the driver to change +* Acceptance Filter Identifier Registers (AFIR) and Acceptance Filter Mask +* Registers (AFMR). +* +* AFIR and AFMR for a filter are changeable only after the filter is disabled +* and this routine returns FALSE. The filter can be disabled using the +* XCanPs_AcceptFilterDisable function. +* +* Use the XCanPs_Accept_* functions for configuring the acceptance filters. +* +* @param InstancePtr is a pointer to the XCanPs instance. +* +* @return +* - TRUE if the device is busy and NOT ready to accept writes to +* AFIR and AFMR. +* - FALSE if the device is ready to accept writes to AFIR and +* AFMR. +* +* @note C-Style signature: +* int XCanPs_IsAcceptFilterBusy(XCanPs *InstancePtr); +* +*****************************************************************************/ +#define XCanPs_IsAcceptFilterBusy(InstancePtr) \ + ((XCanPs_ReadReg(((InstancePtr)->CanConfig.BaseAddr), \ + XCANPS_SR_OFFSET) & XCANPS_SR_ACFBSY_MASK) ? TRUE : FALSE) + + +/****************************************************************************/ +/** +* +* This macro calculates CAN message identifier value given identifier field +* values. +* +* @param StandardId contains Standard Message ID value. +* @param SubRemoteTransReq contains Substitute Remote Transmission +* Request value. +* @param IdExtension contains Identifier Extension value. +* @param ExtendedId contains Extended Message ID value. +* @param RemoteTransReq contains Remote Transmission Request value. +* +* @return Message Identifier value. +* +* @note C-Style signature: +* u32 XCanPs_CreateIdValue(u32 StandardId, +* u32 SubRemoteTransReq, +* u32 IdExtension, u32 ExtendedId, +* u32 RemoteTransReq); +* +* Read the CAN specification for meaning of each parameter. +* +*****************************************************************************/ +#define XCanPs_CreateIdValue(StandardId, SubRemoteTransReq, IdExtension, \ + ExtendedId, RemoteTransReq) \ + ((((StandardId) << XCANPS_IDR_ID1_SHIFT) & XCANPS_IDR_ID1_MASK) | \ + (((SubRemoteTransReq) << XCANPS_IDR_SRR_SHIFT) & XCANPS_IDR_SRR_MASK)|\ + (((IdExtension) << XCANPS_IDR_IDE_SHIFT) & XCANPS_IDR_IDE_MASK) | \ + (((ExtendedId) << XCANPS_IDR_ID2_SHIFT) & XCANPS_IDR_ID2_MASK) | \ + ((RemoteTransReq) & XCANPS_IDR_RTR_MASK)) + + +/****************************************************************************/ +/** +* +* This macro calculates value for Data Length Code register given Data +* Length Code value. +* +* @param DataLengCode indicates Data Length Code value. +* +* @return Value that can be assigned to Data Length Code register. +* +* @note C-Style signature: +* u32 XCanPs_CreateDlcValue(u32 DataLengCode); +* +* Read the CAN specification for meaning of Data Length Code. +* +*****************************************************************************/ +#define XCanPs_CreateDlcValue(DataLengCode) \ + (((DataLengCode) << XCANPS_DLCR_DLC_SHIFT) & XCANPS_DLCR_DLC_MASK) + + +/****************************************************************************/ +/** +* +* This macro clears the timestamp in the Timestamp Control Register. +* +* @param InstancePtr is a pointer to the XCanPs instance. +* +* @return None. +* +* @note C-Style signature: +* void XCanPs_ClearTimestamp(XCanPs *InstancePtr); +* +*****************************************************************************/ +#define XCanPs_ClearTimestamp(InstancePtr) \ + XCanPs_WriteReg((InstancePtr)->CanConfig.BaseAddr, \ + XCANPS_TCR_OFFSET, XCANPS_TCR_CTS_MASK) + +/************************** Function Prototypes ******************************/ + +/* + * Functions in xcanps.c + */ +int XCanPs_CfgInitialize(XCanPs *InstancePtr, XCanPs_Config *ConfigPtr, + u32 EffectiveAddr); + +void XCanPs_Reset(XCanPs *InstancePtr); +u8 XCanPs_GetMode(XCanPs *InstancePtr); +void XCanPs_EnterMode(XCanPs *InstancePtr, u8 OperationMode); +u32 XCanPs_GetStatus(XCanPs *InstancePtr); +void XCanPs_GetBusErrorCounter(XCanPs *InstancePtr, u8 *RxErrorCount, + u8 *TxErrorCount); +u32 XCanPs_GetBusErrorStatus(XCanPs *InstancePtr); +void XCanPs_ClearBusErrorStatus(XCanPs *InstancePtr, u32 Mask); +int XCanPs_Send(XCanPs *InstancePtr, u32 *FramePtr); +int XCanPs_Recv(XCanPs *InstancePtr, u32 *FramePtr); +int XCanPs_SendHighPriority(XCanPs *InstancePtr, u32 *FramePtr); +void XCanPs_AcceptFilterEnable(XCanPs *InstancePtr, u32 FilterIndexes); +void XCanPs_AcceptFilterDisable(XCanPs *InstancePtr, u32 FilterIndexes); +u32 XCanPs_AcceptFilterGetEnabled(XCanPs *InstancePtr); +int XCanPs_AcceptFilterSet(XCanPs *InstancePtr, u32 FilterIndex, + u32 MaskValue, u32 IdValue); +void XCanPs_AcceptFilterGet(XCanPs *InstancePtr, u32 FilterIndex, + u32 *MaskValue, u32 *IdValue); + +int XCanPs_SetBaudRatePrescaler(XCanPs *InstancePtr, u8 Prescaler); +u8 XCanPs_GetBaudRatePrescaler(XCanPs *InstancePtr); +int XCanPs_SetBitTiming(XCanPs *InstancePtr, u8 SyncJumpWidth, + u8 TimeSegment2, u8 TimeSegment1); +void XCanPs_GetBitTiming(XCanPs *InstancePtr, u8 *SyncJumpWidth, + u8 *TimeSegment2, u8 *TimeSegment1); + +int XCanPs_SetRxIntrWatermark(XCanPs *InstancePtr, u8 Threshold); +u8 XCanPs_GetRxIntrWatermark(XCanPs *InstancePtr); + +/* + * Diagnostic functions in xcanps_selftest.c + */ +int XCanPs_SelfTest(XCanPs *InstancePtr); + +/* + * Functions in xcanps_intr.c + */ +void XCanPs_IntrEnable(XCanPs *InstancePtr, u32 Mask); +void XCanPs_IntrDisable(XCanPs *InstancePtr, u32 Mask); +u32 XCanPs_IntrGetEnabled(XCanPs *InstancePtr); +u32 XCanPs_IntrGetStatus(XCanPs *InstancePtr); +void XCanPs_IntrClear(XCanPs *InstancePtr, u32 Mask); +void XCanPs_IntrHandler(void *InstancePtr); +int XCanPs_SetHandler(XCanPs *InstancePtr, u32 HandlerType, + void *CallBackFunc, void *CallBackRef); + +/* + * Functions in xcanps_sinit.c + */ +XCanPs_Config *XCanPs_LookupConfig(u16 DeviceId); + +#ifdef __cplusplus +} +#endif + +#endif /* end of protection macro */ diff --git a/XilinxProcessorIPLib/drivers/canps/src/xcanps_g.c b/XilinxProcessorIPLib/drivers/canps/src/xcanps_g.c new file mode 100755 index 00000000..048d79b7 --- /dev/null +++ b/XilinxProcessorIPLib/drivers/canps/src/xcanps_g.c @@ -0,0 +1,85 @@ +/****************************************************************************** +* +* 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 xcanps_g.c +* +* This file contains a configuration table that specifies the configuration +* of CAN devices in the system. +* +*
+* MODIFICATION HISTORY: +* +* Ver Who Date Changes +* ----- ----- -------- ------------------------------------------------------- +* 1.00a xd/sv 01/12/10 First release +* 2.00 hk 22/01/14 Added check for picking second instance +*+* +******************************************************************************/ + +/***************************** Include Files *********************************/ + +#include "xcanps.h" +#include "xparameters.h" + +/************************** Constant Definitions *****************************/ + + +/**************************** Type Definitions *******************************/ + + +/***************** Macros (Inline Functions) Definitions *********************/ + + +/************************** Function Prototypes ******************************/ + + +/************************** Variable Prototypes ******************************/ + +/** + * This table contains configuration information for each CAN device + * in the system. + */ +XCanPs_Config XCanPs_ConfigTable[XPAR_XCANPS_NUM_INSTANCES] = { + { + XPAR_XCANPS_0_DEVICE_ID, /* Unique ID of device */ + XPAR_XCANPS_0_BASEADDR /* Base address of device */ + }, +#ifdef XPAR_XCANPS_1_DEVICE_ID + { + XPAR_XCANPS_1_DEVICE_ID, /* Unique ID of device */ + XPAR_XCANPS_1_BASEADDR /* Base address of device */ + } +#endif +}; diff --git a/XilinxProcessorIPLib/drivers/canps/src/xcanps_hw.c b/XilinxProcessorIPLib/drivers/canps/src/xcanps_hw.c new file mode 100755 index 00000000..b580c065 --- /dev/null +++ b/XilinxProcessorIPLib/drivers/canps/src/xcanps_hw.c @@ -0,0 +1,89 @@ +/****************************************************************************** +* +* 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 xcanps_hw.c +* +* This file contains the implementation of the canps interface reset sequence +* +*
+* MODIFICATION HISTORY: +* +* Ver Who Date Changes +* ----- ---- -------- ------------------------------------------------------- +* 1.02a adk 08/08/13 First release +*+* +******************************************************************************/ + +/***************************** Include Files *********************************/ + +#include "xparameters.h" +#include "xcanps_hw.h" + +/************************** Constant Definitions *****************************/ + + +/**************************** Type Definitions *******************************/ + + +/***************** Macros (Inline Functions) Definitions *********************/ + + +/************************** Function Prototypes ******************************/ + +/*****************************************************************************/ +/** +* +* This function resets the CAN device. Calling this function resets the device +* immediately, and any pending transmission or reception is terminated at once. +* Both Object Layer and Transfer Layer are reset. This function does not reset +* the Physical Layer. All registers are reset to the default values, and no +* previous status will be restored. TX FIFO, RX FIFO and TX High Priority +* Buffer are also reset. +* +* The CAN device will be in Configuration Mode immediately after this function +* returns. +* +* @param BaseAddr is the baseaddress of the interface. +* +* @return None. +* +* @note None. +* +******************************************************************************/ +void XCanPs_ResetHw(u32 BaseAddr) +{ + XCanPs_WriteReg(BaseAddr, XCANPS_SRR_OFFSET, \ + XCANPS_SRR_SRST_MASK); +} \ No newline at end of file diff --git a/XilinxProcessorIPLib/drivers/canps/src/xcanps_hw.h b/XilinxProcessorIPLib/drivers/canps/src/xcanps_hw.h new file mode 100755 index 00000000..68ec1835 --- /dev/null +++ b/XilinxProcessorIPLib/drivers/canps/src/xcanps_hw.h @@ -0,0 +1,365 @@ +/****************************************************************************** +* +* 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 xcanps_hw.h +* +* This header file contains the identifiers and basic driver functions (or +* macros) that can be used to access the device. Other driver functions +* are defined in xcanps.h. +* +*
+* MODIFICATION HISTORY: +* +* Ver Who Date Changes +* ----- ----- -------- ----------------------------------------------- +* 1.00a xd/sv 01/12/10 First release +* 1.01a sbs 12/27/11 Updated the Register/bit definitions +* Changed XCANPS_RXFWIR_RXFLL_MASK to XCANPS_WIR_FW_MASK +* Changed XCANPS_RXWIR_OFFSET to XCANPS_WIR_OFFSET +* Added XCANPS_IXR_TXFEMP_MASK for Tx Fifo Empty +* Changed XCANPS_IXR_RXFLL_MASK to +* XCANPS_IXR_RXFWMFLL_MASK +* Changed +* XCANPS_TXBUF_ID_OFFSET to XCANPS_TXHPB_ID_OFFSET +* XCANPS_TXBUF_DLC_OFFSET to XCANPS_TXHPB_DLC_OFFSET +* XCANPS_TXBUF_DW1_OFFSET to XCANPS_TXHPB_DW1_OFFSET +* XCANPS_TXBUF_DW2_OFFSET to XCANPS_TXHPB_DW2_OFFSET +* 1.02a adk 08/08/13 Updated for inclding the function prototype +*+* +******************************************************************************/ + +#ifndef XCANPS_HW_H /* prevent circular inclusions */ +#define XCANPS_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 offsets for the CAN. Each register is 32 bits. + * @{ + */ +#define XCANPS_SRR_OFFSET 0x00 /**< Software Reset Register */ +#define XCANPS_MSR_OFFSET 0x04 /**< Mode Select Register */ +#define XCANPS_BRPR_OFFSET 0x08 /**< Baud Rate Prescaler */ +#define XCANPS_BTR_OFFSET 0x0C /**< Bit Timing Register */ +#define XCANPS_ECR_OFFSET 0x10 /**< Error Counter Register */ +#define XCANPS_ESR_OFFSET 0x14 /**< Error Status Register */ +#define XCANPS_SR_OFFSET 0x18 /**< Status Register */ + +#define XCANPS_ISR_OFFSET 0x1C /**< Interrupt Status Register */ +#define XCANPS_IER_OFFSET 0x20 /**< Interrupt Enable Register */ +#define XCANPS_ICR_OFFSET 0x24 /**< Interrupt Clear Register */ +#define XCANPS_TCR_OFFSET 0x28 /**< Timestamp Control Register */ +#define XCANPS_WIR_OFFSET 0x2C /**< Watermark Interrupt Reg */ + +#define XCANPS_TXFIFO_ID_OFFSET 0x30 /**< TX FIFO ID */ +#define XCANPS_TXFIFO_DLC_OFFSET 0x34 /**< TX FIFO DLC */ +#define XCANPS_TXFIFO_DW1_OFFSET 0x38 /**< TX FIFO Data Word 1 */ +#define XCANPS_TXFIFO_DW2_OFFSET 0x3C /**< TX FIFO Data Word 2 */ + +#define XCANPS_TXHPB_ID_OFFSET 0x40 /**< TX High Priority Buffer ID */ +#define XCANPS_TXHPB_DLC_OFFSET 0x44 /**< TX High Priority Buffer DLC */ +#define XCANPS_TXHPB_DW1_OFFSET 0x48 /**< TX High Priority Buf Data 1 */ +#define XCANPS_TXHPB_DW2_OFFSET 0x4C /**< TX High Priority Buf Data Word 2 */ + +#define XCANPS_RXFIFO_ID_OFFSET 0x50 /**< RX FIFO ID */ +#define XCANPS_RXFIFO_DLC_OFFSET 0x54 /**< RX FIFO DLC */ +#define XCANPS_RXFIFO_DW1_OFFSET 0x58 /**< RX FIFO Data Word 1 */ +#define XCANPS_RXFIFO_DW2_OFFSET 0x5C /**< RX FIFO Data Word 2 */ + +#define XCANPS_AFR_OFFSET 0x60 /**< Acceptance Filter Register */ +#define XCANPS_AFMR1_OFFSET 0x64 /**< Acceptance Filter Mask 1 */ +#define XCANPS_AFIR1_OFFSET 0x68 /**< Acceptance Filter ID 1 */ +#define XCANPS_AFMR2_OFFSET 0x6C /**< Acceptance Filter Mask 2 */ +#define XCANPS_AFIR2_OFFSET 0x70 /**< Acceptance Filter ID 2 */ +#define XCANPS_AFMR3_OFFSET 0x74 /**< Acceptance Filter Mask 3 */ +#define XCANPS_AFIR3_OFFSET 0x78 /**< Acceptance Filter ID 3 */ +#define XCANPS_AFMR4_OFFSET 0x7C /**< Acceptance Filter Mask 4 */ +#define XCANPS_AFIR4_OFFSET 0x80 /**< Acceptance Filter ID 4 */ +/* @} */ + +/** @name Software Reset Register (SRR) Bit Definitions and Masks + * @{ + */ +#define XCANPS_SRR_CEN_MASK 0x00000002 /**< Can Enable */ +#define XCANPS_SRR_SRST_MASK 0x00000001 /**< Reset */ +/* @} */ + +/** @name Mode Select Register (MSR) Bit Definitions and Masks + * @{ + */ +#define XCANPS_MSR_SNOOP_MASK 0x00000004 /**< Snoop Mode Select */ +#define XCANPS_MSR_LBACK_MASK 0x00000002 /**< Loop Back Mode Select */ +#define XCANPS_MSR_SLEEP_MASK 0x00000001 /**< Sleep Mode Select */ +/* @} */ + +/** @name Baud Rate Prescaler register (BRPR) Bit Definitions and Masks + * @{ + */ +#define XCANPS_BRPR_BRP_MASK 0x000000FF /**< Baud Rate Prescaler */ +/* @} */ + +/** @name Bit Timing Register (BTR) Bit Definitions and Masks + * @{ + */ +#define XCANPS_BTR_SJW_MASK 0x00000180 /**< Synchronization Jump Width */ +#define XCANPS_BTR_SJW_SHIFT 7 +#define XCANPS_BTR_TS2_MASK 0x00000070 /**< Time Segment 2 */ +#define XCANPS_BTR_TS2_SHIFT 4 +#define XCANPS_BTR_TS1_MASK 0x0000000F /**< Time Segment 1 */ +/* @} */ + +/** @name Error Counter Register (ECR) Bit Definitions and Masks + * @{ + */ +#define XCANPS_ECR_REC_MASK 0x0000FF00 /**< Receive Error Counter */ +#define XCANPS_ECR_REC_SHIFT 8 +#define XCANPS_ECR_TEC_MASK 0x000000FF /**< Transmit Error Counter */ +/* @} */ + +/** @name Error Status Register (ESR) Bit Definitions and Masks + * @{ + */ +#define XCANPS_ESR_ACKER_MASK 0x00000010 /**< ACK Error */ +#define XCANPS_ESR_BERR_MASK 0x00000008 /**< Bit Error */ +#define XCANPS_ESR_STER_MASK 0x00000004 /**< Stuff Error */ +#define XCANPS_ESR_FMER_MASK 0x00000002 /**< Form Error */ +#define XCANPS_ESR_CRCER_MASK 0x00000001 /**< CRC Error */ +/* @} */ + +/** @name Status Register (SR) Bit Definitions and Masks + * @{ + */ +#define XCANPS_SR_SNOOP_MASK 0x00001000 /**< Snoop Mask */ +#define XCANPS_SR_ACFBSY_MASK 0x00000800 /**< Acceptance Filter busy */ +#define XCANPS_SR_TXFLL_MASK 0x00000400 /**< TX FIFO is full */ +#define XCANPS_SR_TXBFLL_MASK 0x00000200 /**< TX High Priority Buffer full */ +#define XCANPS_SR_ESTAT_MASK 0x00000180 /**< Error Status */ +#define XCANPS_SR_ESTAT_SHIFT 7 +#define XCANPS_SR_ERRWRN_MASK 0x00000040 /**< Error Warning */ +#define XCANPS_SR_BBSY_MASK 0x00000020 /**< Bus Busy */ +#define XCANPS_SR_BIDLE_MASK 0x00000010 /**< Bus Idle */ +#define XCANPS_SR_NORMAL_MASK 0x00000008 /**< Normal Mode */ +#define XCANPS_SR_SLEEP_MASK 0x00000004 /**< Sleep Mode */ +#define XCANPS_SR_LBACK_MASK 0x00000002 /**< Loop Back Mode */ +#define XCANPS_SR_CONFIG_MASK 0x00000001 /**< Configuration Mode */ +/* @} */ + +/** @name Interrupt Status/Enable/Clear Register Bit Definitions and Masks + * @{ + */ +#define XCANPS_IXR_TXFEMP_MASK 0x00004000 /**< Tx Fifo Empty Interrupt */ +#define XCANPS_IXR_TXFWMEMP_MASK 0x00002000 /**< Tx Fifo Watermark Empty */ +#define XCANPS_IXR_RXFWMFLL_MASK 0x00001000 /**< Rx FIFO Watermark Full */ +#define XCANPS_IXR_WKUP_MASK 0x00000800 /**< Wake up Interrupt */ +#define XCANPS_IXR_SLP_MASK 0x00000400 /**< Sleep Interrupt */ +#define XCANPS_IXR_BSOFF_MASK 0x00000200 /**< Bus Off Interrupt */ +#define XCANPS_IXR_ERROR_MASK 0x00000100 /**< Error Interrupt */ +#define XCANPS_IXR_RXNEMP_MASK 0x00000080 /**< RX FIFO Not Empty Interrupt */ +#define XCANPS_IXR_RXOFLW_MASK 0x00000040 /**< RX FIFO Overflow Interrupt */ +#define XCANPS_IXR_RXUFLW_MASK 0x00000020 /**< RX FIFO Underflow Interrupt */ +#define XCANPS_IXR_RXOK_MASK 0x00000010 /**< New Message Received Intr */ +#define XCANPS_IXR_TXBFLL_MASK 0x00000008 /**< TX High Priority Buf Full */ +#define XCANPS_IXR_TXFLL_MASK 0x00000004 /**< TX FIFO Full Interrupt */ +#define XCANPS_IXR_TXOK_MASK 0x00000002 /**< TX Successful Interrupt */ +#define XCANPS_IXR_ARBLST_MASK 0x00000001 /**< Arbitration Lost Interrupt */ +#define XCANPS_IXR_ALL (XCANPS_IXR_RXFWMFLL_MASK | \ + XCANPS_IXR_WKUP_MASK | \ + XCANPS_IXR_SLP_MASK | \ + XCANPS_IXR_BSOFF_MASK | \ + XCANPS_IXR_ERROR_MASK | \ + XCANPS_IXR_RXNEMP_MASK | \ + XCANPS_IXR_RXOFLW_MASK | \ + XCANPS_IXR_RXUFLW_MASK | \ + XCANPS_IXR_RXOK_MASK | \ + XCANPS_IXR_TXBFLL_MASK | \ + XCANPS_IXR_TXFLL_MASK | \ + XCANPS_IXR_TXOK_MASK | \ + XCANPS_IXR_ARBLST_MASK) +/* @} */ + +/** @name CAN Timestamp Control Register (TCR) Bit Definitions and Masks + * @{ + */ +#define XCANPS_TCR_CTS_MASK 0x00000001 /**< Clear Timestamp counter mask */ +/* @} */ + +/** @name CAN Watermark Register (WIR) Bit Definitions and Masks + * @{ + */ +#define XCANPS_WIR_FW_MASK 0x0000003F /**< Rx Full Threshold mask */ +#define XCANPS_WIR_EW_MASK 0x00003F00 /**< Tx Empty Threshold mask */ +#define XCANPS_WIR_EW_SHIFT 0x00000008 /**< Tx Empty Threshold shift */ + +/* @} */ + +/** @name CAN Frame Identifier (TX High Priority Buffer/TX/RX/Acceptance Filter + Mask/Acceptance Filter ID) + * @{ + */ +#define XCANPS_IDR_ID1_MASK 0xFFE00000 /**< Standard Messg Identifier */ +#define XCANPS_IDR_ID1_SHIFT 21 +#define XCANPS_IDR_SRR_MASK 0x00100000 /**< Substitute Remote TX Req */ +#define XCANPS_IDR_SRR_SHIFT 20 +#define XCANPS_IDR_IDE_MASK 0x00080000 /**< Identifier Extension */ +#define XCANPS_IDR_IDE_SHIFT 19 +#define XCANPS_IDR_ID2_MASK 0x0007FFFE /**< Extended Message Ident */ +#define XCANPS_IDR_ID2_SHIFT 1 +#define XCANPS_IDR_RTR_MASK 0x00000001 /**< Remote TX Request */ +/* @} */ + +/** @name CAN Frame Data Length Code (TX High Priority Buffer/TX/RX) + * @{ + */ +#define XCANPS_DLCR_DLC_MASK 0xF0000000 /**< Data Length Code */ +#define XCANPS_DLCR_DLC_SHIFT 28 +#define XCANPS_DLCR_TIMESTAMP_MASK 0x0000FFFF /**< Timestamp Mask (Rx only) */ + +/* @} */ + +/** @name CAN Frame Data Word 1 (TX High Priority Buffer/TX/RX) + * @{ + */ +#define XCANPS_DW1R_DB0_MASK 0xFF000000 /**< Data Byte 0 */ +#define XCANPS_DW1R_DB0_SHIFT 24 +#define XCANPS_DW1R_DB1_MASK 0x00FF0000 /**< Data Byte 1 */ +#define XCANPS_DW1R_DB1_SHIFT 16 +#define XCANPS_DW1R_DB2_MASK 0x0000FF00 /**< Data Byte 2 */ +#define XCANPS_DW1R_DB2_SHIFT 8 +#define XCANPS_DW1R_DB3_MASK 0x000000FF /**< Data Byte 3 */ +/* @} */ + +/** @name CAN Frame Data Word 2 (TX High Priority Buffer/TX/RX) + * @{ + */ +#define XCANPS_DW2R_DB4_MASK 0xFF000000 /**< Data Byte 4 */ +#define XCANPS_DW2R_DB4_SHIFT 24 +#define XCANPS_DW2R_DB5_MASK 0x00FF0000 /**< Data Byte 5 */ +#define XCANPS_DW2R_DB5_SHIFT 16 +#define XCANPS_DW2R_DB6_MASK 0x0000FF00 /**< Data Byte 6 */ +#define XCANPS_DW2R_DB6_SHIFT 8 +#define XCANPS_DW2R_DB7_MASK 0x000000FF /**< Data Byte 7 */ +/* @} */ + +/** @name Acceptance Filter Register (AFR) Bit Definitions and Masks + * @{ + */ +#define XCANPS_AFR_UAF4_MASK 0x00000008 /**< Use Acceptance Filter No.4 */ +#define XCANPS_AFR_UAF3_MASK 0x00000004 /**< Use Acceptance Filter No.3 */ +#define XCANPS_AFR_UAF2_MASK 0x00000002 /**< Use Acceptance Filter No.2 */ +#define XCANPS_AFR_UAF1_MASK 0x00000001 /**< Use Acceptance Filter No.1 */ +#define XCANPS_AFR_UAF_ALL_MASK (XCANPS_AFR_UAF4_MASK | \ + XCANPS_AFR_UAF3_MASK | \ + XCANPS_AFR_UAF2_MASK | \ + XCANPS_AFR_UAF1_MASK) +/* @} */ + +/** @name CAN frame length constants + * @{ + */ +#define XCANPS_MAX_FRAME_SIZE 16 /**< Maximum CAN frame length in bytes */ +/* @} */ + +/* For backwards compatibilty */ +#define XCANPS_TXBUF_ID_OFFSET XCANPS_TXHPB_ID_OFFSET +#define XCANPS_TXBUF_DLC_OFFSET XCANPS_TXHPB_DLC_OFFSET +#define XCANPS_TXBUF_DW1_OFFSET XCANPS_TXHPB_DW1_OFFSET +#define XCANPS_TXBUF_DW2_OFFSET XCANPS_TXHPB_DW2_OFFSET + +#define XCANPS_RXFWIR_RXFLL_MASK XCANPS_WIR_FW_MASK +#define XCANPS_RXWIR_OFFSET XCANPS_WIR_OFFSET +#define XCANPS_IXR_RXFLL_MASK XCANPS_IXR_RXFWMFLL_MASK + + + + +/**************************** Type Definitions *******************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ + +/****************************************************************************/ +/** +* +* This macro reads the given register. +* +* @param BaseAddr is the base address of the device. +* @param RegOffset is the register offset to be read. +* +* @return The 32-bit value of the register +* +* @note None. +* +*****************************************************************************/ +#define XCanPs_ReadReg(BaseAddr, RegOffset) \ + Xil_In32((BaseAddr) + (RegOffset)) + + +/****************************************************************************/ +/** +* +* This macro writes the given register. +* +* @param BaseAddr is the base address of the device. +* @param RegOffset is the register offset to be written. +* @param Data is the 32-bit value to write to the register. +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +#define XCanPs_WriteReg(BaseAddr, RegOffset, Data) \ + Xil_Out32((BaseAddr) + (RegOffset), (Data)) + +/************************** Function Prototypes ******************************/ +/* + * Perform reset operation to the CanPs interface + */ +void XCanPs_ResetHw(u32 BaseAddr); + +#ifdef __cplusplus +} +#endif + +#endif /* end of protection macro */ diff --git a/XilinxProcessorIPLib/drivers/canps/src/xcanps_intr.c b/XilinxProcessorIPLib/drivers/canps/src/xcanps_intr.c new file mode 100755 index 00000000..7f1933fc --- /dev/null +++ b/XilinxProcessorIPLib/drivers/canps/src/xcanps_intr.c @@ -0,0 +1,402 @@ +/****************************************************************************** +* +* 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 xcanps_intr.c +* +* This file contains functions related to CAN interrupt handling. +* +*
+* MODIFICATION HISTORY: +* +* Ver Who Date Changes +* ----- ----- -------- ----------------------------------------------- +* 1.00a xd/sv 01/12/10 First release +*+* +******************************************************************************/ + +/***************************** Include Files *********************************/ + +#include "xcanps.h" + +/************************** Constant Definitions *****************************/ + +/**************************** Type Definitions *******************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ + +/************************** Variable Definitions *****************************/ + +/************************** Function Prototypes ******************************/ + +/****************************************************************************/ +/** +* +* This routine enables interrupt(s). Use the XCANPS_IXR_* constants defined in +* xcanps_hw.h to create the bit-mask to enable interrupts. +* +* @param InstancePtr is a pointer to the XCanPs instance. +* @param Mask is the mask to enable. Bit positions of 1 will be enabled. +* Bit positions of 0 will keep the previous setting. This mask is +* formed by OR'ing XCANPS_IXR_* bits defined in xcanps_hw.h. +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +void XCanPs_IntrEnable(XCanPs *InstancePtr, u32 Mask) +{ + u32 IntrValue; + + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Write to the IER to enable the specified interrupts. + */ + IntrValue = XCanPs_IntrGetEnabled(InstancePtr); + IntrValue |= Mask & XCANPS_IXR_ALL; + XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr, + XCANPS_IER_OFFSET, IntrValue); +} + +/****************************************************************************/ +/** +* +* This routine disables interrupt(s). Use the XCANPS_IXR_* constants defined in +* xcanps_hw.h to create the bit-mask to disable interrupt(s). +* +* @param InstancePtr is a pointer to the XCanPs instance. +* @param Mask is the mask to disable. Bit positions of 1 will be +* disabled. Bit positions of 0 will keep the previous setting. +* This mask is formed by OR'ing XCANPS_IXR_* bits defined in +* xcanps_hw.h. +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +void XCanPs_IntrDisable(XCanPs *InstancePtr, u32 Mask) +{ + u32 IntrValue; + + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Write to the IER to disable the specified interrupts. + */ + IntrValue = XCanPs_IntrGetEnabled(InstancePtr); + IntrValue &= ~Mask; + XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr, + XCANPS_IER_OFFSET, IntrValue); +} + +/****************************************************************************/ +/** +* +* This routine returns enabled interrupt(s). Use the XCANPS_IXR_* constants +* defined in xcanps_hw.h to interpret the returned value. +* +* @param InstancePtr is a pointer to the XCanPs instance. +* +* @return Enabled interrupt(s) in a 32-bit format. +* +* @note None. +* +*****************************************************************************/ +u32 XCanPs_IntrGetEnabled(XCanPs *InstancePtr) +{ + + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + return XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr, + XCANPS_IER_OFFSET); +} + + +/****************************************************************************/ +/** +* +* This routine returns interrupt status read from Interrupt Status Register. +* Use the XCANPS_IXR_* constants defined in xcanps_hw.h to interpret the +* returned value. +* +* @param InstancePtr is a pointer to the XCanPs instance. +* +* @return The value stored in Interrupt Status Register. +* +* @note None. +* +*****************************************************************************/ +u32 XCanPs_IntrGetStatus(XCanPs *InstancePtr) +{ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + return XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr, + XCANPS_ISR_OFFSET); +} + +/****************************************************************************/ +/** +* +* This function clears interrupt(s). Every bit set in Interrupt Status +* Register indicates that a specific type of interrupt is occurring, and this +* function clears one or more interrupts by writing a bit mask to Interrupt +* Clear Register. +* +* @param InstancePtr is a pointer to the XCanPs instance. +* @param Mask is the mask to clear. Bit positions of 1 will be cleared. +* Bit positions of 0 will not change the previous interrupt +* status. This mask is formed by OR'ing XCANPS_IXR_* bits defined +* in xcanps_hw.h. +* +* @note None. +* +*****************************************************************************/ +void XCanPs_IntrClear(XCanPs *InstancePtr, u32 Mask) +{ + u32 IntrValue; + + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Clear the currently pending interrupts. + */ + IntrValue = XCanPs_IntrGetStatus(InstancePtr); + IntrValue &= Mask; + XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr, XCANPS_ICR_OFFSET, + IntrValue); +} + +/*****************************************************************************/ +/** +* +* This routine is the interrupt handler for the CAN driver. +* +* This handler reads the interrupt status from the ISR, determines the source of +* the interrupts, calls according callbacks, and finally clears the interrupts. +* +* Application beyond this driver is responsible for providing callbacks to +* handle interrupts and installing the callbacks using XCanPs_SetHandler() +* during initialization phase. An example delivered with this driver +* demonstrates how this could be done. +* +* @param InstancePtr is a pointer to the XCanPs instance that just +* interrupted. +* +* @return None. +* +* @note None. +* +******************************************************************************/ +void XCanPs_IntrHandler(void *InstancePtr) +{ + u32 PendingIntr; + u32 EventIntr; + u32 ErrorStatus; + XCanPs *CanPtr = (XCanPs *) InstancePtr; + + Xil_AssertVoid(CanPtr != NULL); + Xil_AssertVoid(CanPtr->IsReady == XIL_COMPONENT_IS_READY); + + PendingIntr = XCanPs_IntrGetStatus(CanPtr); + PendingIntr &= XCanPs_IntrGetEnabled(CanPtr); + + /* + * Clear all pending interrupts. + * Rising Edge interrupt + */ + XCanPs_IntrClear(CanPtr, PendingIntr); + + /* + * An error interrupt is occurring. + */ + if ((PendingIntr & XCANPS_IXR_ERROR_MASK)) { + ErrorStatus = XCanPs_GetBusErrorStatus(CanPtr); + CanPtr->ErrorHandler(CanPtr->ErrorRef, ErrorStatus); + + /* + * Clear Error Status Register. + */ + XCanPs_ClearBusErrorStatus(CanPtr, ErrorStatus); + } + + /* + * Check if any following event interrupt is pending: + * - RX FIFO Overflow + * - RX FIFO Underflow + * - TX High Priority Buffer full + * - TX FIFO Full + * - Wake up from sleep mode + * - Enter sleep mode + * - Enter Bus off status + * - Arbitration is lost + * + * If so, call event callback provided by upper level. + */ + EventIntr = PendingIntr & (XCANPS_IXR_RXOFLW_MASK | + XCANPS_IXR_RXUFLW_MASK | + XCANPS_IXR_TXBFLL_MASK | + XCANPS_IXR_TXFLL_MASK | + XCANPS_IXR_WKUP_MASK | + XCANPS_IXR_SLP_MASK | + XCANPS_IXR_BSOFF_MASK | + XCANPS_IXR_ARBLST_MASK); + if (EventIntr) { + CanPtr->EventHandler(CanPtr->EventRef, EventIntr); + + if ((EventIntr & XCANPS_IXR_BSOFF_MASK)) { + /* + * Event callback should reset whole device if "Enter + * Bus Off Status" interrupt occurred. All pending + * interrupts are cleared and no further checking and + * handling of other interrupts is needed any more. + */ + return; + } + } + + + if ((PendingIntr & (XCANPS_IXR_RXFWMFLL_MASK | + XCANPS_IXR_RXNEMP_MASK))) { + + /* + * This case happens when + * A number of frames depending on the Rx FIFO Watermark + * threshold are received. + * And also when frame was received and is sitting in RX FIFO. + * + * XCANPS_IXR_RXOK_MASK is not used because the bit is set + * just once even if there are multiple frames sitting + * in the RX FIFO. + * + * XCANPS_IXR_RXNEMP_MASK is used because the bit can be + * set again and again automatically as long as there is + * at least one frame in RX FIFO. + */ + CanPtr->RecvHandler(CanPtr->RecvRef); + } + + /* + * A frame was transmitted successfully. + */ + if ((PendingIntr & XCANPS_IXR_TXOK_MASK)) { + CanPtr->SendHandler(CanPtr->SendRef); + } +} + + +/*****************************************************************************/ +/** +* +* This routine installs an asynchronous callback function for the given +* HandlerType: +* +*
+* HandlerType Callback Function Type +* ----------------------- ------------------------ +* XCANPS_HANDLER_SEND XCanPs_SendRecvHandler +* XCANPS_HANDLER_RECV XCanPs_SendRecvHandler +* XCANPS_HANDLER_ERROR XCanPs_ErrorHandler +* XCANPS_HANDLER_EVENT XCanPs_EventHandler +* +* HandlerType Invoked by this driver when: +* ------------------------------------------------------------------------- +* XCANPS_HANDLER_SEND A frame transmitted by a call to +* XCanPs_Send() has been sent successfully. +* +* XCANPS_HANDLER_RECV A frame(s) has been received and is sitting in +* the RX FIFO. +* +* XCANPS_HANDLER_ERROR An error interrupt is occurring. +* +* XCANPS_HANDLER_EVENT Any other kind of interrupt is occurring. +*+* +* @param InstancePtr is a pointer to the XCanPs instance. +* @param HandlerType specifies which handler is to be attached. +* @param CallBackFunc is the address of the callback function. +* @param CallBackRef is a user data item that will be passed to the +* callback function when it is invoked. +* +* @return +* - XST_SUCCESS when handler is installed. +* - XST_INVALID_PARAM when HandlerType is invalid. +* +* @note +* Invoking this function for a handler that already has been installed replaces +* it with the new handler. +* +******************************************************************************/ +int XCanPs_SetHandler(XCanPs *InstancePtr, u32 HandlerType, + void *CallBackFunc, void *CallBackRef) +{ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + switch (HandlerType) { + case XCANPS_HANDLER_SEND: + InstancePtr->SendHandler = + (XCanPs_SendRecvHandler) CallBackFunc; + InstancePtr->SendRef = CallBackRef; + break; + + case XCANPS_HANDLER_RECV: + InstancePtr->RecvHandler = + (XCanPs_SendRecvHandler) CallBackFunc; + InstancePtr->RecvRef = CallBackRef; + break; + + case XCANPS_HANDLER_ERROR: + InstancePtr->ErrorHandler = (XCanPs_ErrorHandler) CallBackFunc; + InstancePtr->ErrorRef = CallBackRef; + break; + + case XCANPS_HANDLER_EVENT: + InstancePtr->EventHandler = (XCanPs_EventHandler) CallBackFunc; + InstancePtr->EventRef = CallBackRef; + break; + + default: + return (XST_INVALID_PARAM); + + } + return (XST_SUCCESS); +} diff --git a/XilinxProcessorIPLib/drivers/canps/src/xcanps_selftest.c b/XilinxProcessorIPLib/drivers/canps/src/xcanps_selftest.c new file mode 100755 index 00000000..f768258c --- /dev/null +++ b/XilinxProcessorIPLib/drivers/canps/src/xcanps_selftest.c @@ -0,0 +1,207 @@ +/****************************************************************************** +* +* 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 xcanps_selftest.c +* +* This file contains a diagnostic self-test function for the XCanPs driver. +* +* Read xcanps.h file for more information. +* +* @note +* The Baud Rate Prescaler Register (BRPR) and Bit Timing Register(BTR) +* are setup such that CAN baud rate equals 40Kbps, given the CAN clock +* equal to 24MHz. These need to be changed based on the desired baudrate +* and CAN clock frequency. +* +*
+* MODIFICATION HISTORY: +* +* Ver Who Date Changes +* ----- ----- -------- ----------------------------------------------- +* 1.00a xd/sv 01/12/10 First release +* 2.1 adk 23/08/14 Fixed CR:798792 Peripheral test for CANPS IP in +* SDK claims a 40kbps baud rate but it's not. +*+* +*****************************************************************************/ + +/***************************** Include Files ********************************/ + +#include "xstatus.h" +#include "xcanps.h" + +/************************** Constant Definitions ****************************/ + +#define XCANPS_MAX_FRAME_SIZE_IN_WORDS (XCANPS_MAX_FRAME_SIZE / sizeof(u32)) + +#define FRAME_DATA_LENGTH 8 /* Frame Data field length */ + +/**************************** Type Definitions ******************************/ + +/***************** Macros (Inline Functions) Definitions ********************/ + +/************************** Variable Definitions ****************************/ + +/* + * Buffers to hold frames to send and receive. These are declared as global so + * that they are not on the stack. + */ +static u32 TxFrame[XCANPS_MAX_FRAME_SIZE_IN_WORDS]; +static u32 RxFrame[XCANPS_MAX_FRAME_SIZE_IN_WORDS]; + +/************************** Function Prototypes *****************************/ + +/*****************************************************************************/ +/** +* +* This function runs a self-test on the CAN driver/device. The test resets +* the device, sets up the Loop Back mode, sends a standard frame, receives the +* frame, verifies the contents, and resets the device again. +* +* Note that this is a destructive test in that resets of the device are +* performed. Refer the device specification for the device status after +* the reset operation. +* +* +* @param InstancePtr is a pointer to the XCanPs instance. +* +* @return +* - XST_SUCCESS if the self-test passed. i.e., the frame +* received via the internal loop back has the same contents as +* the frame sent. +* - XST_FAILURE Otherwise. +* +* @note +* +* If the CAN device does not work properly, this function may enter an +* infinite loop and will never return to the caller. +*
+* +* MODIFICATION HISTORY: +* +* Ver Who Date Changes +* ----- ----- -------- ----------------------------------------------- +* 1.00a xd/sv 01/12/10 First release +* +* +*+* +******************************************************************************/ + +/***************************** Include Files *********************************/ + +#include "xparameters.h" +#include "xcanps.h" + +/************************** Constant Definitions *****************************/ + +/**************************** Type Definitions *******************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ + +/************************** Function Prototypes ******************************/ + +/************************** Variable Definitions *****************************/ +extern XCanPs_Config XCanPs_ConfigTable[]; + +/*****************************************************************************/ +/** +* +* This function looks for the device configuration based on the unique device +* ID. The table XCanPs_ConfigTable[] contains the configuration information for +* each device in the system. +* +* @param DeviceId is the unique device ID of the device being looked up. +* +* @return A pointer to the configuration table entry corresponding to the +* given device ID, or NULL if no match is found. +* +* @note None. +* +******************************************************************************/ +XCanPs_Config *XCanPs_LookupConfig(u16 DeviceId) +{ + XCanPs_Config *CfgPtr = NULL; + u32 Index; + + for (Index = 0; Index < XPAR_XCANPS_NUM_INSTANCES; Index++) { + if (XCanPs_ConfigTable[Index].DeviceId == DeviceId) { + CfgPtr = &XCanPs_ConfigTable[Index]; + break; + } + } + + return CfgPtr; +}