From 7db965cedc1a42c84b8dd66bce65333673087f3d Mon Sep 17 00:00:00 2001 From: Kedareswara rao Appana Date: Tue, 9 Dec 2014 17:47:44 +0530 Subject: [PATCH] can: Added new version and deprecate older version of the driver Added new version of the driver canps_v3_0 and deprecated canps_v2_1. Signed-off-by: Kedareswara rao Appana --- .../drivers/canps/data/canps.mdd | 42 + .../drivers/canps/data/canps.tcl | 51 + .../drivers/canps/data/canps_header.h | 45 + .../drivers/canps/data/canps_tapp.tcl | 191 +++ .../drivers/canps/examples/index.html | 19 + .../canps/examples/xcanps_intr_example.c | 704 ++++++++++ .../canps/examples/xcanps_polled_example.c | 363 ++++++ .../examples/xcanps_watermark_intr_example.c | 799 ++++++++++++ .../drivers/canps/src/Makefile | 40 + .../drivers/canps/src/xcanps.c | 1154 +++++++++++++++++ .../drivers/canps/src/xcanps.h | 562 ++++++++ .../drivers/canps/src/xcanps_g.c | 85 ++ .../drivers/canps/src/xcanps_hw.c | 89 ++ .../drivers/canps/src/xcanps_hw.h | 365 ++++++ .../drivers/canps/src/xcanps_intr.c | 402 ++++++ .../drivers/canps/src/xcanps_selftest.c | 207 +++ .../drivers/canps/src/xcanps_sinit.c | 99 ++ 17 files changed, 5217 insertions(+) create mode 100755 XilinxProcessorIPLib/drivers/canps/data/canps.mdd create mode 100755 XilinxProcessorIPLib/drivers/canps/data/canps.tcl create mode 100755 XilinxProcessorIPLib/drivers/canps/data/canps_header.h create mode 100755 XilinxProcessorIPLib/drivers/canps/data/canps_tapp.tcl create mode 100755 XilinxProcessorIPLib/drivers/canps/examples/index.html create mode 100755 XilinxProcessorIPLib/drivers/canps/examples/xcanps_intr_example.c create mode 100755 XilinxProcessorIPLib/drivers/canps/examples/xcanps_polled_example.c create mode 100755 XilinxProcessorIPLib/drivers/canps/examples/xcanps_watermark_intr_example.c create mode 100755 XilinxProcessorIPLib/drivers/canps/src/Makefile create mode 100755 XilinxProcessorIPLib/drivers/canps/src/xcanps.c create mode 100755 XilinxProcessorIPLib/drivers/canps/src/xcanps.h create mode 100755 XilinxProcessorIPLib/drivers/canps/src/xcanps_g.c create mode 100755 XilinxProcessorIPLib/drivers/canps/src/xcanps_hw.c create mode 100755 XilinxProcessorIPLib/drivers/canps/src/xcanps_hw.h create mode 100755 XilinxProcessorIPLib/drivers/canps/src/xcanps_intr.c create mode 100755 XilinxProcessorIPLib/drivers/canps/src/xcanps_selftest.c create mode 100755 XilinxProcessorIPLib/drivers/canps/src/xcanps_sinit.c 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 @@ + + + + + +Driver example applications + + + +

Example Applications for the driver canps_v2_1

+
+ +

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__DEVICE_ID value from xparameters.h. +* @param CanIntrId is the interrupt Id and is typically +* XPAR__INTR value from xparameters.h. +* +* @return XST_SUCCESS if successful, otherwise driver-specific error code. +* +* @note If the device is not working correctly, this function may enter +* an infinite loop and will never return to the caller. +* +******************************************************************************/ +int CanPsIntrExample(XScuGic *IntcInstPtr, XCanPs *CanInstPtr, + u16 CanDeviceId, u16 CanIntrId) +{ + int Status; + XCanPs_Config *ConfigPtr; + + /* + * Initialize the Can device. + */ + ConfigPtr = XCanPs_LookupConfig(CanDeviceId); + if (ConfigPtr == NULL) { + return XST_FAILURE; + } + XCanPs_CfgInitialize(CanInstPtr, + ConfigPtr, + ConfigPtr->BaseAddr); + + /* + * Run self-test on the device, which verifies basic sanity of the + * device and the driver. + */ + Status = XCanPs_SelfTest(CanInstPtr); + if (Status != XST_SUCCESS) { + return XST_FAILURE; + } + + /* + * Configure CAN device. + */ + Config(CanInstPtr); + + /* + * Set interrupt handlers. + */ + XCanPs_SetHandler(CanInstPtr, XCANPS_HANDLER_SEND, + (void *)SendHandler, (void *)CanInstPtr); + XCanPs_SetHandler(CanInstPtr, XCANPS_HANDLER_RECV, + (void *)RecvHandler, (void *)CanInstPtr); + XCanPs_SetHandler(CanInstPtr, XCANPS_HANDLER_ERROR, + (void *)ErrorHandler, (void *)CanInstPtr); + XCanPs_SetHandler(CanInstPtr, XCANPS_HANDLER_EVENT, + (void *)EventHandler, (void *)CanInstPtr); + + /* + * Initialize the flags. + */ + SendDone = FALSE; + RecvDone = FALSE; + LoopbackError = FALSE; + + /* + * Connect to the interrupt controller. + */ + Status = SetupInterruptSystem(IntcInstPtr, + CanInstPtr, + CanIntrId); + if (Status != XST_SUCCESS) { + return XST_FAILURE; + } + + /* + * Enable all interrupts in CAN device. + */ + XCanPs_IntrEnable(CanInstPtr, XCANPS_IXR_ALL); + + /* + * Enter Loop Back Mode. + */ + XCanPs_EnterMode(CanInstPtr, XCANPS_MODE_LOOPBACK); + while(XCanPs_GetMode(CanInstPtr) != XCANPS_MODE_LOOPBACK); + + /* + * Loop back a frame. The RecvHandler is expected to handle + * the frame reception. + */ + SendFrame(CanInstPtr); /* Send a frame */ + + /* + * Wait here until both sending and reception have been completed. + */ + while ((SendDone != TRUE) || (RecvDone != TRUE)); + + /* + * Check for errors found in the callbacks. + */ + if (LoopbackError == TRUE) { + return XST_LOOPBACK_ERROR; + } + + return XST_SUCCESS; +} + +/*****************************************************************************/ +/** +* +* This function configures CAN device. Baud Rate Prescaler Register (BRPR) and +* Bit Timing Register (BTR) are set in this function. +* +* @param InstancePtr is a pointer to the driver instance. +* +* @return None. +* +* @note If the CAN device is not working correctly, this function may +* enter an infinite loop and will never return to the caller. +* +******************************************************************************/ +static void Config(XCanPs *InstancePtr) +{ + /* + * Enter Configuration Mode if the device is not currently in + * Configuration Mode. + */ + XCanPs_EnterMode(InstancePtr, XCANPS_MODE_CONFIG); + while(XCanPs_GetMode(InstancePtr) != XCANPS_MODE_CONFIG); + + /* + * Setup Baud Rate Prescaler Register (BRPR) and + * Bit Timing Register (BTR). + */ + XCanPs_SetBaudRatePrescaler(InstancePtr, TEST_BRPR_BAUD_PRESCALAR); + XCanPs_SetBitTiming(InstancePtr, TEST_BTR_SYNCJUMPWIDTH, + TEST_BTR_SECOND_TIMESEGMENT, + TEST_BTR_FIRST_TIMESEGMENT); + +} + +/*****************************************************************************/ +/** +* +* Send a CAN frame. +* +* @param InstancePtr is a pointer to the driver instance. +* +* @return None. +* +* @note None. +* +******************************************************************************/ +static void SendFrame(XCanPs *InstancePtr) +{ + u8 *FramePtr; + int Index; + int Status; + + /* + * Create correct values for Identifier and Data Length Code Register. + */ + TxFrame[0] = (u32)XCanPs_CreateIdValue((u32)TEST_MESSAGE_ID, 0, 0, 0, 0); + TxFrame[1] = (u32)XCanPs_CreateDlcValue((u32)FRAME_DATA_LENGTH); + + /* + * Now fill in the data field with known values so we can verify them + * on receive. + */ + FramePtr = (u8 *)(&TxFrame[2]); + for (Index = 0; Index < FRAME_DATA_LENGTH; Index++) { + *FramePtr++ = (u8)Index; + } + + /* + * Now wait until the TX FIFO is not full and send the frame. + */ + while (XCanPs_IsTxFifoFull(InstancePtr) == TRUE); + + Status = XCanPs_Send(InstancePtr, TxFrame); + if (Status != XST_SUCCESS) { + /* + * The frame could not be sent successfully. + */ + LoopbackError = TRUE; + SendDone = TRUE; + RecvDone = TRUE; + } +} + + +/*****************************************************************************/ +/** +* +* Callback function (called from interrupt handler) to handle confirmation of +* transmit events when in interrupt mode. +* +* @param CallBackRef is the callback reference passed from the interrupt +* handler, which in our case is a pointer to the driver instance. +* +* @return None. +* +* @note This function is called by the driver within interrupt context. +* +******************************************************************************/ +static void SendHandler(void *CallBackRef) +{ + /* + * The frame was sent successfully. Notify the task context. + */ + SendDone = TRUE; +} + + +/*****************************************************************************/ +/** +* +* Callback function (called from interrupt handler) to handle frames received in +* interrupt mode. This function is called once per frame received. +* The driver's receive function is called to read the frame from RX FIFO. +* +* @param CallBackRef is the callback reference passed from the interrupt +* handler, which in our case is a pointer to the device instance. +* +* @return None. +* +* @note This function is called by the driver within interrupt context. +* +******************************************************************************/ +static void RecvHandler(void *CallBackRef) +{ + XCanPs *CanPtr = (XCanPs *)CallBackRef; + int Status; + int Index; + u8 *FramePtr; + + Status = XCanPs_Recv(CanPtr, RxFrame); + if (Status != XST_SUCCESS) { + LoopbackError = TRUE; + RecvDone = TRUE; + return; + } + + /* + * Verify Identifier and Data Length Code. + */ + if (RxFrame[0] != (u32)XCanPs_CreateIdValue((u32)TEST_MESSAGE_ID, 0, 0, 0, 0)) { + LoopbackError = TRUE; + RecvDone = TRUE; + return; + } + + if ((RxFrame[1] & ~XCANPS_DLCR_TIMESTAMP_MASK) != TxFrame[1]) { + LoopbackError = TRUE; + RecvDone = TRUE; + return; + } + + /* + * Verify the Data field contents. + */ + FramePtr = (u8 *)(&RxFrame[2]); + for (Index = 0; Index < FRAME_DATA_LENGTH; Index++) { + if (*FramePtr++ != (u8)Index) { + LoopbackError = TRUE; + break; + } + } + + RecvDone = TRUE; +} + + +/*****************************************************************************/ +/** +* +* Callback function (called from interrupt handler) to handle error interrupt. +* Error code read from Error Status register is passed into this function. +* +* @param CallBackRef is the callback reference passed from the interrupt +* handler, which in our case is a pointer to the driver instance. +* @param ErrorMask is a bit mask indicating the cause of the error. +* Its value equals 'OR'ing one or more XCANPS_ESR_* defined in +* xcanps_hw.h. +* +* @return None. +* +* @note This function is called by the driver within interrupt context. +* +******************************************************************************/ +static void ErrorHandler(void *CallBackRef, u32 ErrorMask) +{ + + if(ErrorMask & XCANPS_ESR_ACKER_MASK) { + /* + * ACK Error handling code should be put here. + */ + } + + if(ErrorMask & XCANPS_ESR_BERR_MASK) { + /* + * Bit Error handling code should be put here. + */ + } + + if(ErrorMask & XCANPS_ESR_STER_MASK) { + /* + * Stuff Error handling code should be put here. + */ + } + + if(ErrorMask & XCANPS_ESR_FMER_MASK) { + /* + * Form Error handling code should be put here. + */ + } + + if(ErrorMask & XCANPS_ESR_CRCER_MASK) { + /* + * CRC Error handling code should be put here. + */ + } + + /* + * Set the shared variables. + */ + LoopbackError = TRUE; + RecvDone = TRUE; + SendDone = TRUE; +} + + +/*****************************************************************************/ +/** +* +* Callback function (called from interrupt handler) to handle the following +* interrupts: +* - XCANPS_IXR_BSOFF_MASK: Bus Off Interrupt +* - XCANPS_IXR_RXOFLW_MASK: RX FIFO Overflow Interrupt +* - XCANPS_IXR_RXUFLW_MASK: RX FIFO Underflow Interrupt +* - XCANPS_IXR_TXBFLL_MASK: TX High Priority Buffer Full Interrupt +* - XCANPS_IXR_TXFLL_MASK: TX FIFO Full Interrupt +* - XCANPS_IXR_WKUP_MASK: Wake up Interrupt +* - XCANPS_IXR_SLP_MASK: Sleep Interrupt +* - XCANPS_IXR_ARBLST_MASK: Arbitration Lost Interrupt +* +* +* @param CallBackRef is the callback reference passed from the +* interrupt Handler, which in our case is a pointer to the +* driver instance. +* @param IntrMask is a bit mask indicating pending interrupts. +* Its value equals 'OR'ing one or more of the XCANPS_IXR_*_MASK +* value(s) mentioned above. +* +* @return None. +* +* @note This function is called by the driver within interrupt context. +* This function should be changed to meet specific application +* needs. +* +******************************************************************************/ +static void EventHandler(void *CallBackRef, u32 IntrMask) +{ + XCanPs *CanPtr = (XCanPs *)CallBackRef; + + if (IntrMask & XCANPS_IXR_BSOFF_MASK) { + /* + * Entering Bus off status interrupt requires + * the CAN device be reset and reconfigured. + */ + XCanPs_Reset(CanPtr); + Config(CanPtr); + return; + } + + if(IntrMask & XCANPS_IXR_RXOFLW_MASK) { + /* + * Code to handle RX FIFO Overflow Interrupt should be put here. + */ + } + + if(IntrMask & XCANPS_IXR_RXUFLW_MASK) { + /* + * Code to handle RX FIFO Underflow Interrupt + * should be put here. + */ + } + + if(IntrMask & XCANPS_IXR_TXBFLL_MASK) { + /* + * Code to handle TX High Priority Buffer Full + * Interrupt should be put here. + */ + } + + if(IntrMask & XCANPS_IXR_TXFLL_MASK) { + /* + * Code to handle TX FIFO Full Interrupt should be put here. + */ + } + + if (IntrMask & XCANPS_IXR_WKUP_MASK) { + /* + * Code to handle Wake up from sleep mode Interrupt + * should be put here. + */ + } + + if (IntrMask & XCANPS_IXR_SLP_MASK) { + /* + * Code to handle Enter sleep mode Interrupt should be put here. + */ + } + + if (IntrMask & XCANPS_IXR_ARBLST_MASK) { + /* + * Code to handle Lost bus arbitration Interrupt + * should be put here. + */ + } +} + + +/*****************************************************************************/ +/** +* +* This function sets up the interrupt system so interrupts can occur for the +* CAN. This function is application-specific since the actual system may or +* may not have an interrupt controller. The CAN could be directly connected +* to a processor without an interrupt controller. The user should modify this +* function to fit the application. +* +* @param IntcInstancePtr is a pointer to the instance of the ScuGic. +* @param CanInstancePtr contains a pointer to the instance of the CAN +* which is going to be connected to the interrupt +* controller. +* @param CanIntrId is the interrupt Id and is typically +* XPAR__INTR value from xparameters.h. +* +* @return XST_SUCCESS if successful, otherwise XST_FAILURE. +* +* @note None. +* +****************************************************************************/ +static int SetupInterruptSystem(XScuGic *IntcInstancePtr, + XCanPs *CanInstancePtr, + u16 CanIntrId) +{ + int Status; + +#ifndef TESTAPP_GEN + XScuGic_Config *IntcConfig; /* Instance of the interrupt controller */ + + Xil_ExceptionInit(); + + /* + * Initialize the interrupt controller driver so that it is ready to + * use. + */ + IntcConfig = XScuGic_LookupConfig(INTC_DEVICE_ID); + if (NULL == IntcConfig) { + return XST_FAILURE; + } + + Status = XScuGic_CfgInitialize(IntcInstancePtr, IntcConfig, + IntcConfig->CpuBaseAddress); + if (Status != XST_SUCCESS) { + return XST_FAILURE; + } + + + /* + * Connect the interrupt controller interrupt handler to the hardware + * interrupt handling logic in the processor. + */ + Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_IRQ_INT, + (Xil_ExceptionHandler)XScuGic_InterruptHandler, + IntcInstancePtr); +#endif + + /* + * Connect the device driver handler that will be called when an + * interrupt for the device occurs, the handler defined above performs + * the specific interrupt processing for the device. + */ + Status = XScuGic_Connect(IntcInstancePtr, CanIntrId, + (Xil_InterruptHandler)XCanPs_IntrHandler, + (void *)CanInstancePtr); + if (Status != XST_SUCCESS) { + return Status; + } + + /* + * Enable the interrupt for the CAN device. + */ + XScuGic_Enable(IntcInstancePtr, CanIntrId); + +#ifndef TESTAPP_GEN + /* + * Enable interrupts in the Processor. + */ + Xil_ExceptionEnable(); +#endif + return XST_SUCCESS; +} diff --git a/XilinxProcessorIPLib/drivers/canps/examples/xcanps_polled_example.c b/XilinxProcessorIPLib/drivers/canps/examples/xcanps_polled_example.c new file mode 100755 index 00000000..26d04ba1 --- /dev/null +++ b/XilinxProcessorIPLib/drivers/canps/examples/xcanps_polled_example.c @@ -0,0 +1,363 @@ +/****************************************************************************** +* +* 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_polled_example.c +* +* Contains an example of how to use the XCanPs driver directly. +* This example shows the using the driver/device in polled mode. +* +* @note +* +* None. +* +*
+* 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__DEVICE_ID value from +* xparameters.h +* +* @return XST_SUCCESS if successful, otherwise driver-specific error code. +* +* @note +* +* If the device is not working correctly, this function may enter an infinite +* loop and will never return to the caller. +* +******************************************************************************/ +int CanPsPolledExample(u16 DeviceId) +{ + int Status; + XCanPs *CanInstPtr = &Can; + XCanPs_Config *ConfigPtr; + + /* + * Initialize the Can device. + */ + ConfigPtr = XCanPs_LookupConfig(DeviceId); + if (CanInstPtr == NULL) { + return XST_FAILURE; + } + Status = XCanPs_CfgInitialize(CanInstPtr, + ConfigPtr, + ConfigPtr->BaseAddr); + if (Status != XST_SUCCESS) { + return XST_FAILURE; + } + + /* + * Run self-test on the device, which verifies basic sanity of the + * device and the driver. + */ + Status = XCanPs_SelfTest(CanInstPtr); + if (Status != XST_SUCCESS) { + return XST_FAILURE; + } + + /* + * Enter Configuration Mode so we can setup Baud Rate Prescaler + * Register (BRPR) and Bit Timing Register (BTR). + */ + XCanPs_EnterMode(CanInstPtr, XCANPS_MODE_CONFIG); + while(XCanPs_GetMode(CanInstPtr) != XCANPS_MODE_CONFIG); + + /* + * Setup Baud Rate Prescaler Register (BRPR) and + * Bit Timing Register (BTR). + */ + XCanPs_SetBaudRatePrescaler(CanInstPtr, TEST_BRPR_BAUD_PRESCALAR); + XCanPs_SetBitTiming(CanInstPtr, TEST_BTR_SYNCJUMPWIDTH, + TEST_BTR_SECOND_TIMESEGMENT, + + TEST_BTR_FIRST_TIMESEGMENT); + + /* + * Enter Loop Back Mode. + */ + XCanPs_EnterMode(CanInstPtr, XCANPS_MODE_LOOPBACK); + while(XCanPs_GetMode(CanInstPtr) != XCANPS_MODE_LOOPBACK); + + /* + * Send a frame, receive the frame via the loop back and verify its + * contents. + */ + Status = SendFrame(CanInstPtr); + if (Status != XST_SUCCESS) { + return Status; + } + + Status = RecvFrame(CanInstPtr); + + return Status; +} + + +/*****************************************************************************/ +/** +* +* Send a CAN frame. +* +* @param InstancePtr is a pointer to the driver instance +* +* @return XST_SUCCESS if successful, a driver-specific return code if not. +* +* @note +* +* This function waits until TX FIFO has room for at least one frame before +* sending a frame. So this function may block if the hardware is not built +* correctly. +* +******************************************************************************/ +static int SendFrame(XCanPs *InstancePtr) +{ + u8 *FramePtr; + int Index; + int Status; + + /* + * Create correct values for Identifier and Data Length Code Register. + */ + TxFrame[0] = (u32)XCanPs_CreateIdValue((u32)TEST_MESSAGE_ID, 0, 0, 0, 0); + TxFrame[1] = (u32)XCanPs_CreateDlcValue((u32)FRAME_DATA_LENGTH); + + /* + * Now fill in the data field with known values so we can verify them + * on receive. + */ + FramePtr = (u8 *)(&TxFrame[2]); + for (Index = 0; Index < FRAME_DATA_LENGTH; Index++) { + *FramePtr++ = (u8)Index; + } + + /* + * Wait until TX FIFO has room. + */ + while (XCanPs_IsTxFifoFull(InstancePtr) == TRUE); + + /* + * Now send the frame. + * + * Another way to send a frame is keep calling XCanPs_Send() until it + * returns XST_SUCCESS. No check on if TX FIFO is full is needed anymore + * in that case. + */ + Status = XCanPs_Send(InstancePtr, TxFrame); + + return Status; +} + + +/*****************************************************************************/ +/** +* +* This function receives a frame and verifies its contents. +* +* @param InstancePtr is a pointer to the driver instance. +* +* @return XST_SUCCESS if successful, a driver-specific return code if not. +* +* @note +* +* This function waits until RX FIFO becomes not empty before reading a frame +* from it. So this function may block if the hardware is not built +* correctly. +* +******************************************************************************/ +static int RecvFrame(XCanPs *InstancePtr) +{ + u8 *FramePtr; + int Status; + int Index; + + /* + * Wait until a frame is received. + */ + while (XCanPs_IsRxEmpty(InstancePtr) == TRUE); + + /* + * Receive a frame and verify its contents. + */ + Status = XCanPs_Recv(InstancePtr, RxFrame); + if (Status == XST_SUCCESS) { + /* + * Verify Identifier and Data Length Code. + */ + if (RxFrame[0] != + (u32)XCanPs_CreateIdValue((u32)TEST_MESSAGE_ID, 0, 0, 0, 0)) + return XST_LOOPBACK_ERROR; + + if ((RxFrame[1] & ~XCANPS_DLCR_TIMESTAMP_MASK) != TxFrame[1]) + return XST_LOOPBACK_ERROR; + + /* + * Verify Data field contents. + */ + FramePtr = (u8 *)(&RxFrame[2]); + for (Index = 0; Index < FRAME_DATA_LENGTH; Index++) { + if (*FramePtr++ != (u8)Index) { + return XST_LOOPBACK_ERROR; + } + } + } + + return Status; +} diff --git a/XilinxProcessorIPLib/drivers/canps/examples/xcanps_watermark_intr_example.c b/XilinxProcessorIPLib/drivers/canps/examples/xcanps_watermark_intr_example.c new file mode 100755 index 00000000..1afd37d5 --- /dev/null +++ b/XilinxProcessorIPLib/drivers/canps/examples/xcanps_watermark_intr_example.c @@ -0,0 +1,799 @@ +/****************************************************************************** +* +* 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_watermark_intr_example.c +* +* This example shows how to use the CAN driver/device in interrupt mode using +* the Rx Watermark Interrupt. +* +* +* @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 bau 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
+*
+*
+* 
+* +******************************************************************************/ + +/***************************** 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__DEVICE_ID value from xparameters.h. +* @param CanIntrId is the interrupt Id and is typically +* XPAR__INTR value from xparameters.h. +* +* @return XST_SUCCESS if successful, otherwise driver-specific error code. +* +* @note If the device is not working correctly, this function may enter +* an infinite loop and will never return to the caller. +* +******************************************************************************/ +int CanPsWatermarkIntrExample(XScuGic *IntcInstPtr, XCanPs *CanInstPtr, + u16 CanDeviceId, u16 CanIntrId) +{ + int Status; + XCanPs_Config *ConfigPtr; + u32 Index; + + /* + * Initialize the Can device. + */ + ConfigPtr = XCanPs_LookupConfig(CanDeviceId); + if (ConfigPtr == NULL) { + return XST_FAILURE; + } + + Status = XCanPs_CfgInitialize(CanInstPtr, + ConfigPtr, + ConfigPtr->BaseAddr); + if (Status != XST_SUCCESS) { + return XST_FAILURE; + } + + /* + * Run self-test on the device, which verifies basic sanity of the + * device and the driver. + */ + Status = XCanPs_SelfTest(CanInstPtr); + if (Status != XST_SUCCESS) { + return XST_FAILURE; + } + + /* + * Configure the CAN device. + */ + Config(CanInstPtr); + + /* + * Set the interrupt handlers. + */ + XCanPs_SetHandler(CanInstPtr, XCANPS_HANDLER_SEND, + (void *)SendHandler, (void *)CanInstPtr); + XCanPs_SetHandler(CanInstPtr, XCANPS_HANDLER_RECV, + (void *)RecvHandler, (void *)CanInstPtr); + XCanPs_SetHandler(CanInstPtr, XCANPS_HANDLER_ERROR, + (void *)ErrorHandler, (void *)CanInstPtr); + XCanPs_SetHandler(CanInstPtr, XCANPS_HANDLER_EVENT, + (void *)EventHandler, (void *)CanInstPtr); + + /* + * Initialize flags. + */ + SendDone = FALSE; + RecvDone = FALSE; + LoopbackError = FALSE; + + /* + * Connect to the interrupt controller. + */ + Status = SetupInterruptSystem(IntcInstPtr, + CanInstPtr, + CanIntrId); + if (Status != XST_SUCCESS) { + return XST_FAILURE; + } + + /* + * Enable all interrupts in CAN device. + */ + XCanPs_IntrEnable(CanInstPtr, XCANPS_IXR_ALL); + + /* + * Disable the Receive FIFO Not Empty Interrupt and the + * New Message Received Interrupt. + */ + XCanPs_IntrDisable(CanInstPtr, + XCANPS_IXR_RXNEMP_MASK | + XCANPS_IXR_RXOK_MASK); + + /* + * Enter Loop Back Mode. + */ + XCanPs_EnterMode(CanInstPtr, XCANPS_MODE_LOOPBACK); + while(XCanPs_GetMode(CanInstPtr) != XCANPS_MODE_LOOPBACK); + + /* + * Send a number of frames. + */ + TestDataOffset = 1; + for (Index = 0; Index < TEST_THRESHOLD; Index++) { + + SendFrame(CanInstPtr); /* Send a frame */ + TestDataOffset++; + } + + /* + * Wait here until both sending and reception have been completed. + */ + while ((SendDone < TEST_THRESHOLD) || (RecvDone != TRUE)); + + /* + * Check for errors found in the callbacks. + */ + if (LoopbackError == TRUE) { + return XST_FAILURE; + } + + /* + * Read the Received Frames from the FIFO. + */ + TestDataOffset = 1; + Status = ReceiveData(CanInstPtr); + if (Status != XST_SUCCESS) { + return XST_FAILURE; + } + + /* + * Check for errors found in the callbacks. + */ + if (LoopbackError == TRUE) { + return XST_LOOPBACK_ERROR; + } + + return XST_SUCCESS; +} + +/*****************************************************************************/ +/** +* +* This function configures CAN device. Baud Rate Prescaler Register (BRPR), +* Bit Timing Register (BTR) and RXFIFO Watermark Interrupt Register (RXWIR) +* are set in this function. +* +* @param InstancePtr is a pointer to the driver instance. +* +* @return None. +* +* @note If the CAN device is not working correctly, this function may +* enter an infinite loop and will never return to the caller. +* +******************************************************************************/ +static void Config(XCanPs *InstancePtr) +{ + /* + * Enter Configuration Mode if the device is not currently in + * Configuration Mode. + */ + XCanPs_EnterMode(InstancePtr, XCANPS_MODE_CONFIG); + while(XCanPs_GetMode(InstancePtr) != XCANPS_MODE_CONFIG); + + /* + * Setup Baud Rate Prescaler Register (BRPR) and + * Bit Timing Register (BTR) . + */ + XCanPs_SetBaudRatePrescaler(InstancePtr, TEST_BRPR_BAUD_PRESCALAR); + XCanPs_SetBitTiming(InstancePtr, TEST_BTR_SYNCJUMPWIDTH, + TEST_BTR_SECOND_TIMESEGMENT, + TEST_BTR_FIRST_TIMESEGMENT); + + /* + * Set the threshold value for the Rx FIFO Watermark interrupt. + */ + XCanPs_SetRxIntrWatermark(InstancePtr, TEST_THRESHOLD - 1); +} + +/*****************************************************************************/ +/** +* +* Send a CAN frame. +* +* @param InstancePtr is a pointer to the driver instance. +* +* @return None. +* +* @note None. +* +******************************************************************************/ +static void SendFrame(XCanPs *InstancePtr) +{ + u8 *FramePtr; + int Index; + int Status; + + /* + * Create correct values for Identifier and Data Length Code Register. + */ + TxFrame[0] = (u32)XCanPs_CreateIdValue((u32)TEST_MESSAGE_ID, 0, 0, 0, 0); + TxFrame[1] = (u32)XCanPs_CreateDlcValue((u32)FRAME_DATA_LENGTH); + + /* + * Now fill in the data field with known values so we can verify them + * on receive. + */ + FramePtr = (u8 *)(&TxFrame[2]); + for (Index = 0; Index < FRAME_DATA_LENGTH; Index++) { + *FramePtr++ = ((u8)Index + TestDataOffset); + } + + /* + * Now wait until the TX FIFO is not full and send the frame. + */ + while (XCanPs_IsTxFifoFull(InstancePtr) == TRUE); + + Status = XCanPs_Send(InstancePtr, TxFrame); + if (Status != XST_SUCCESS) { + /* + * The frame could not be sent successfully. + */ + LoopbackError = TRUE; + SendDone = TEST_THRESHOLD; + RecvDone = TRUE; + } +} + +/*****************************************************************************/ +/** +* +* Read the Received CAN frames from the FIFO. +* +* @param InstancePtr is a pointer to the driver instance. +* +* @return +* - XST_SUCCESS if all the CAN Frames are received and the +* data is the same as that was sent. +* - XST_FAILURE if the required number of CAN frames have not +* been received or if the Received Data is not the same as the +* data that was sent. +* +* @note None. +* +******************************************************************************/ +static int ReceiveData(XCanPs *InstancePtr) +{ + int Status; + int Index; + u8 *FramePtr; + u8 NumRxFrames; + + /* + * Initialize the number of received frames to Zero. + */ + NumRxFrames = 0; + + /* + * Read the received CAN Frames from the FIFO till the FIFO is Empty. + */ + while (XCanPs_IntrGetStatus(InstancePtr) & XCANPS_IXR_RXNEMP_MASK) { + + Status = XCanPs_Recv(InstancePtr, RxFrame); + if (Status != XST_SUCCESS) { + LoopbackError = TRUE; + return XST_FAILURE; + } + + /* + * Verify Identifier and Data Length Code. + */ + if (RxFrame[0] != + (u32)XCanPs_CreateIdValue((u32)TEST_MESSAGE_ID, 0, 0, 0, 0)) { + + LoopbackError = TRUE; + return XST_FAILURE; + } + if ((RxFrame[1] & ~XCANPS_DLCR_TIMESTAMP_MASK) != TxFrame[1]) { + LoopbackError = TRUE; + return XST_FAILURE; + } + + /* + * Verify Data field contents. + */ + FramePtr = (u8 *)(&RxFrame[2]); + for (Index = 0; Index < FRAME_DATA_LENGTH; Index++) { + if (*FramePtr++ != ((u8)Index + TestDataOffset)) { + LoopbackError = TRUE; + return XST_FAILURE; + } + } + + /* + * Increment the number of frames received. + */ + TestDataOffset++; + NumRxFrames++; + + } + + if (NumRxFrames == TEST_THRESHOLD) { + LoopbackError = FALSE; + return XST_SUCCESS; + } + return XST_FAILURE; +} + +/*****************************************************************************/ +/** +* +* Callback function (called from interrupt handler) to handle confirmation of +* transmit events when in interrupt mode. +* +* @param CallBackRef is the callback reference passed from the interrupt +* handler, which in our case is a pointer to the driver instance. +* +* @return None. +* +* @note This function is called by the driver within interrupt context. +* +******************************************************************************/ +static void SendHandler(void *CallBackRef) +{ + /* + * The frame was sent successfully. Notify the task context. + */ + SendDone++; +} + + +/*****************************************************************************/ +/** +* +* Callback function (called from interrupt handler) to handle frames received in +* interrupt mode. This function is called once all the frames are received. +* +* @param CallBackRef is the callback reference passed from the interrupt +* handler, which in our case is a pointer to the device instance. +* +* @return None. +* +* @note This function is called by the driver within interrupt context. +* +******************************************************************************/ +static void RecvHandler(void *CallBackRef) +{ + XCanPs *CanInstPtr = (XCanPs *)CallBackRef; + + /* + * The RX FIFO is Full to the Watermark level specified. + */ + XCanPs_IntrDisable(CanInstPtr, XCANPS_IXR_RXFWMFLL_MASK); + RecvDone = TRUE; +} + + +/*****************************************************************************/ +/** +* +* Callback function (called from interrupt handler) to handle error interrupt. +* Error code read from Error Status register is passed into this function +* +* @param CallBackRef is the callback reference passed from the interrupt +* handler, which in our case is a pointer to the driver instance. +* @param ErrorMask is a bit mask indicating the cause of the error. +* Its value equals 'OR'ing one or more XCANPS_ESR_* defined in +* xcanps_hw.h +* +* @return None. +* +* @note This function is called by the driver within interrupt context. +* +******************************************************************************/ +static void ErrorHandler(void *CallBackRef, u32 ErrorMask) +{ + if(ErrorMask & XCANPS_ESR_ACKER_MASK) { + /* + * ACK Error handling code should be put here. + */ + } + + if(ErrorMask & XCANPS_ESR_BERR_MASK) { + /* + * Bit Error handling code should be put here. + */ + } + + if(ErrorMask & XCANPS_ESR_STER_MASK) { + /* + * Stuff Error handling code should be put here. + */ + } + + if(ErrorMask & XCANPS_ESR_FMER_MASK) { + /* + * Form Error handling code should be put here. + */ + } + + if(ErrorMask & XCANPS_ESR_CRCER_MASK) { + /* + * CRC Error handling code should be put here. + */ + } + + /* + * Set the shared variables. + */ + LoopbackError = TRUE; + RecvDone = TRUE; + SendDone = TEST_THRESHOLD; +} + + +/*****************************************************************************/ +/** +* +* Callback function (called from interrupt handler) to handle the following +* interrupts: +* - XCANPS_IXR_BSOFF_MASK: Bus Off Interrupt +* - XCANPS_IXR_RXOFLW_MASK: RX FIFO Overflow Interrupt +* - XCANPS_IXR_RXUFLW_MASK: RX FIFO Underflow Interrupt +* - XCANPS_IXR_TXBFLL_MASK: TX High Priority Buffer Full Interrupt +* - XCANPS_IXR_TXFLL_MASK: TX FIFO Full Interrupt +* - XCANPS_IXR_WKUP_MASK: Wake up Interrupt +* - XCANPS_IXR_SLP_MASK: Sleep Interrupt +* - XCANPS_IXR_ARBLST_MASK: Arbitration Lost Interrupt +* +* +* @param CallBackRef is the callback reference passed from the +* interrupt Handler, which in our case is a pointer to the +* driver instance. +* @param IntrMask is a bit mask indicating pending interrupts. +* Its value equals 'OR'ing one or more of the XCANPS_IXR_*_MASK +* value(s) mentioned above. +* +* @return None. +* +* @note This function is called by the driver within interrupt context. +* This function needs to be changed to meet specific application +* needs. +* +******************************************************************************/ +static void EventHandler(void *CallBackRef, u32 IntrMask) +{ + XCanPs *CanPtr = (XCanPs *)CallBackRef; + + if (IntrMask & XCANPS_IXR_BSOFF_MASK) { + /* + * Entering Bus off status interrupt requires + * the CAN device be reset and reconfigured. + */ + XCanPs_Reset(CanPtr); + Config(CanPtr); + return; + } + + if(IntrMask & XCANPS_IXR_RXOFLW_MASK) { + /* + * Code to handle RX FIFO Overflow + * Interrupt should be put here. + */ + } + + if(IntrMask & XCANPS_IXR_RXUFLW_MASK) { + /* + * Code to handle RX FIFO Underflow + * Interrupt should be put here. + */ + } + + if(IntrMask & XCANPS_IXR_TXBFLL_MASK) { + /* + * Code to handle TX High Priority Buffer Full + * Interrupt should be put here. + */ + } + + if(IntrMask & XCANPS_IXR_TXFLL_MASK) { + /* + * Code to handle TX FIFO Full + * Interrupt should be put here. + */ + } + + if (IntrMask & XCANPS_IXR_WKUP_MASK) { + /* + * Code to handle Wake up from sleep mode + * Interrupt should be put here. + */ + } + + if (IntrMask & XCANPS_IXR_SLP_MASK) { + /* + * Code to handle Enter sleep mode + * Interrupt should be put here. + */ + } + + if (IntrMask & XCANPS_IXR_ARBLST_MASK) { + /* + * Code to handle Lost bus arbitration + * Interrupt should be put here. + */ + } +} + +/*****************************************************************************/ +/** +* +* This function sets up the interrupt system so interrupts can occur for the +* CAN. This function is application-specific since the actual system may or +* may not have an interrupt controller. The CAN could be directly connected +* to a processor without an interrupt controller. The user should modify this +* function to fit the application. +* +* @param IntcInstancePtr is a pointer to the instance of ScuGic driver. +* @param CanInstancePtr contains a pointer to the instance of the CAN +* which is going to be connected to the interrupt controller. +* @param CanIntrId is the interrupt Id and is typically +* XPAR__INTR value from xparameters.h. +* +* @return XST_SUCCESS if successful, otherwise XST_FAILURE. +* +* @note None. +* +****************************************************************************/ +static int SetupInterruptSystem(XScuGic *IntcInstancePtr, + XCanPs *CanInstancePtr, + u16 CanIntrId) +{ + int Status; + +#ifndef TESTAPP_GEN + XScuGic_Config *IntcConfig; /* Instance of the interrupt controller */ + + Xil_ExceptionInit(); + + /* + * Initialize the interrupt controller driver so that it is ready to + * use. + */ + IntcConfig = XScuGic_LookupConfig(INTC_DEVICE_ID); + if (NULL == IntcConfig) { + return XST_FAILURE; + } + + Status = XScuGic_CfgInitialize(IntcInstancePtr, IntcConfig, + IntcConfig->CpuBaseAddress); + if (Status != XST_SUCCESS) { + return XST_FAILURE; + } + + + /* + * Connect the interrupt controller interrupt handler to the hardware + * interrupt handling logic in the processor. + */ + Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_IRQ_INT, + (Xil_ExceptionHandler)XScuGic_InterruptHandler, + IntcInstancePtr); +#endif + + /* + * Connect the device driver handler that will be called when an + * interrupt for the device occurs, the handler defined above performs + * the specific interrupt processing for the device. + */ + Status = XScuGic_Connect(IntcInstancePtr, CanIntrId, + (Xil_InterruptHandler)XCanPs_IntrHandler, + (void *)CanInstancePtr); + if (Status != XST_SUCCESS) { + return Status; + } + + /* + * Enable the interrupt for the CAN device. + */ + XScuGic_Enable(IntcInstancePtr, CanIntrId); + +#ifndef TESTAPP_GEN + /* + * Enable interrupts in the Processor. + */ + Xil_ExceptionEnable(); +#endif + return XST_SUCCESS; +} diff --git a/XilinxProcessorIPLib/drivers/canps/src/Makefile b/XilinxProcessorIPLib/drivers/canps/src/Makefile new file mode 100755 index 00000000..55565709 --- /dev/null +++ b/XilinxProcessorIPLib/drivers/canps/src/Makefile @@ -0,0 +1,40 @@ +COMPILER= +ARCHIVER= +CP=cp +COMPILER_FLAGS= +EXTRA_COMPILER_FLAGS= +LIB=libxil.a + +CC_FLAGS = $(COMPILER_FLAGS) +ECC_FLAGS = $(EXTRA_COMPILER_FLAGS) + +RELEASEDIR=../../../lib +INCLUDEDIR=../../../include +INCLUDES=-I./. -I${INCLUDEDIR} + +OUTS = *.o + +LIBSOURCES:=*.c +INCLUDEFILES:=*.h + +OBJECTS = $(addsuffix .o, $(basename $(wildcard *.c))) + +libs: banner xcanps_libs clean + +%.o: %.c + ${COMPILER} $(CC_FLAGS) $(ECC_FLAGS) $(INCLUDES) -o $@ $< + +banner: + echo "Compiling canps" + +xcanps_libs: ${OBJECTS} + $(ARCHIVER) -r ${RELEASEDIR}/${LIB} ${OBJECTS} + +.PHONY: include +include: xcanps_includes + +xcanps_includes: + ${CP} ${INCLUDEFILES} ${INCLUDEDIR} + +clean: + rm -rf ${OBJECTS} diff --git a/XilinxProcessorIPLib/drivers/canps/src/xcanps.c b/XilinxProcessorIPLib/drivers/canps/src/xcanps.c new file mode 100755 index 00000000..3fd73403 --- /dev/null +++ b/XilinxProcessorIPLib/drivers/canps/src/xcanps.c @@ -0,0 +1,1154 @@ +/****************************************************************************** +* +* 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.c +* +* Functions in this file are the minimum required functions for the XCanPs +* driver. See xcanps.h for a detailed description of the driver. +* +* @note None. +* +* +*
+* 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. +*

+* If XST_FAILURE is returned, the device is not reset so that the caller could +* have a chance to check reason(s) causing the failure. +* +******************************************************************************/ +int XCanPs_SelfTest(XCanPs *InstancePtr) +{ + u8 *FramePtr; + u32 Status; + u32 Index; + + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + XCanPs_Reset(InstancePtr); + + /* + * The device should enter Configuration Mode immediately after + * reset above is finished. Now check the mode and return error code if + * it is not Configuration Mode. + */ + if (XCanPs_GetMode(InstancePtr) != XCANPS_MODE_CONFIG) { + return XST_FAILURE; + } + + /* + * Setup Baud Rate Prescaler Register (BRPR) and Bit Timing Register + * (BTR) such that CAN baud rate equals 40Kbps, given the CAN clock + * equal to 24MHz. For more information see the CAN 2.0A, CAN 2.0B, + * ISO 11898-1 specifications. + */ + XCanPs_SetBaudRatePrescaler(InstancePtr, 29); + XCanPs_SetBitTiming(InstancePtr, 3, 2, 15); + + /* + * Enter the loop back mode. + */ + XCanPs_EnterMode(InstancePtr, XCANPS_MODE_LOOPBACK); + while (XCanPs_GetMode(InstancePtr) != XCANPS_MODE_LOOPBACK); + + /* + * Create a frame to send with known values so we can verify them + * on receive. + */ + TxFrame[0] = (u32)XCanPs_CreateIdValue((u32)2000, 0, 0, 0, 0); + TxFrame[1] = (u32)XCanPs_CreateDlcValue((u32)8); + + FramePtr = (u8 *) (&TxFrame[2]); + for (Index = 0; Index < 8; Index++) { + *FramePtr++ = (u8) Index; + } + + /* + * Send the frame. + */ + Status = XCanPs_Send(InstancePtr, TxFrame); + if (Status != XST_SUCCESS) { + return XST_FAILURE; + } + + /* + * Wait until the frame arrives RX FIFO via internal loop back. + */ + while (XCanPs_IsRxEmpty(InstancePtr) == TRUE); + + /* + * Receive the frame. + */ + Status = XCanPs_Recv(InstancePtr, RxFrame); + if (Status != XST_SUCCESS) { + return XST_FAILURE; + } + + /* + * Verify Identifier and Data Length Code. + */ + if (RxFrame[0] != + (u32)XCanPs_CreateIdValue((u32)2000, 0, 0, 0, 0)) { + return XST_FAILURE; + } + + if ((RxFrame[1] & ~XCANPS_DLCR_TIMESTAMP_MASK) != TxFrame[1]) { + return XST_FAILURE; + } + + + for (Index = 2; Index < XCANPS_MAX_FRAME_SIZE_IN_WORDS; Index++) { + if (RxFrame[Index] != TxFrame[Index]) { + return XST_FAILURE; + } + } + + /* + * Reset device again before returning to the caller. + */ + XCanPs_Reset(InstancePtr); + + return XST_SUCCESS; +} diff --git a/XilinxProcessorIPLib/drivers/canps/src/xcanps_sinit.c b/XilinxProcessorIPLib/drivers/canps/src/xcanps_sinit.c new file mode 100755 index 00000000..dd1e7604 --- /dev/null +++ b/XilinxProcessorIPLib/drivers/canps/src/xcanps_sinit.c @@ -0,0 +1,99 @@ +/****************************************************************************** +* +* 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_sinit.c +* +* This file contains the implementation of the XCanPs driver's static +* initialization functionality. +* +* @note None. +* +*
+*
+* 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; +}