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 <appanad@xilinx.com>
This commit is contained in:
Kedareswara rao Appana 2014-12-09 17:47:44 +05:30 committed by Suneel Garapati
parent e4948b3972
commit 7db965cedc
17 changed files with 5217 additions and 0 deletions

View file

@ -0,0 +1,42 @@
###############################################################################
#
# Copyright (C) 2011 - 2014 Xilinx, Inc. All rights reserved.
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# Use of the Software is limited solely to applications:
# (a) running on a Xilinx device, or
# (b) that interact with a Xilinx device through a bus or interconnect.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
# OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
#
# Except as contained in this notice, the name of the Xilinx shall not be used
# in advertising or otherwise to promote the sale, use or other dealings in
# this Software without prior written authorization from Xilinx.
#
###############################################################################
OPTION psf_version = 2.1;
BEGIN driver canps
OPTION supported_peripherals = (ps7_can);
OPTION driver_state = ACTIVE;
OPTION copyfiles = all;
OPTION VERSION = 3.0;
OPTION NAME = canps;
END driver

View file

@ -0,0 +1,51 @@
###############################################################################
#
# Copyright (C) 2011 - 2014 Xilinx, Inc. All rights reserved.
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# Use of the Software is limited solely to applications:
# (a) running on a Xilinx device, or
# (b) that interact with a Xilinx device through a bus or interconnect.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
# OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
#
# Except as contained in this notice, the name of the Xilinx shall not be used
# in advertising or otherwise to promote the sale, use or other dealings in
# this Software without prior written authorization from Xilinx.
#
###############################################################################
##############################################################################
#
# Modification History
#
# Ver Who Date Changes
# ----- ---- -------- -----------------------------------------------
# 1.00a sdm 11/22/11 Created
#
##############################################################################
#uses "xillib.tcl"
proc generate {drv_handle} {
xdefine_zynq_include_file $drv_handle "xparameters.h" "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"
}

View file

@ -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

View file

@ -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
}

View file

@ -0,0 +1,19 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<html>
<head>
<meta http-equiv="Content-Language" content="en-us">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Driver example applications</title>
<link rel="stylesheet" type="text/css" href="../help.css">
</head>
<body bgcolor="#FFFFFF">
<h1> Example Applications for the driver canps_v2_1 </h1>
<HR>
<ul>
<li>xcanps_watermark_intr_example.c <a href="xcanps_watermark_intr_example.c">(source)</a> </li>
<li>xcanps_intr_example.c <a href="xcanps_intr_example.c">(source)</a> </li>
<li>xcanps_polled_example.c <a href="xcanps_polled_example.c">(source)</a> </li>
</ul>
<p><font face="Times New Roman" color="#800000">Copyright <20> 1995-2014 Xilinx, Inc. All rights reserved.</font></p>
</body>
</html>

View file

@ -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.
*
* <pre>
* 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.
* </pre>
*
******************************************************************************/
/***************************** 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_<CANPS_instance>_DEVICE_ID value from xparameters.h.
* @param CanIntrId is the interrupt Id and is typically
* XPAR_<CANPS_instance>_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_<CANPS_instance>_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;
}

View file

@ -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.
*
* <pre>
* 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.
* </pre>
*
******************************************************************************/
/***************************** 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_<CANPS_instance>_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;
}

View file

@ -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.
*
* <pre>
*
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ----- -------- -----------------------------------------------
* 1.00a xd/sv 01/12/10 First release
*
*
* </pre>
*
******************************************************************************/
/***************************** 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_<CANPS_instance>_DEVICE_ID value from xparameters.h.
* @param CanIntrId is the interrupt Id and is typically
* XPAR_<CANPS_instance>_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_<CANPS_instance>_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;
}

View file

@ -0,0 +1,40 @@
COMPILER=
ARCHIVER=
CP=cp
COMPILER_FLAGS=
EXTRA_COMPILER_FLAGS=
LIB=libxil.a
CC_FLAGS = $(COMPILER_FLAGS)
ECC_FLAGS = $(EXTRA_COMPILER_FLAGS)
RELEASEDIR=../../../lib
INCLUDEDIR=../../../include
INCLUDES=-I./. -I${INCLUDEDIR}
OUTS = *.o
LIBSOURCES:=*.c
INCLUDEFILES:=*.h
OBJECTS = $(addsuffix .o, $(basename $(wildcard *.c)))
libs: banner 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}

File diff suppressed because it is too large Load diff

View file

@ -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.
*
* <b>Driver Description</b>
*
* 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
*
* <b>Operation Modes</b>
*
* The CAN controller supports the following modes of operation:
* - <b>Configuration Mode</b>: 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.
* - <b>Normal Mode</b>:In Normal Mode the CAN controller participates in bus
* communication, by transmitting and receiving messages.
* - <b>Sleep Mode</b>: 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.
* - <b>Loop Back Mode</b>: 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 <EFBFBD>Rx<EFBFBD> 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.
* - <b>Snoop Mode</b>: 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.
*
*
* <b>Buffer Alignment</b>
*
* It is important to note that frame buffers passed to the driver must be
* 32-bit aligned.
*
* <b>Receive Address Filtering</b>
*
* 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.
*
* <b>PHY Communication</b>
*
* This driver does not provide any mechanism for directly programming PHY.
*
* <b>Interrupts</b>
*
* 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.
*
* <b>Threads</b>
*
* This driver is not thread safe. Any needs for threads or thread mutual
* exclusion must be satisfied by the layer above this driver.
*
* <b>Device Reset</b>
*
* 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.
*
* <b>Device Configuration</b>
*
* 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.
*
* <b>Asserts</b>
*
* 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.
*
* <b>Building the driver</b>
*
* 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.
* <br><br>
*
* <pre>
* 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.
* </pre>
*
******************************************************************************/
#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 */

View file

@ -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.
*
* <pre>
* 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
* </pre>
*
******************************************************************************/
/***************************** 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
};

View file

@ -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
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -------------------------------------------------------
* 1.02a adk 08/08/13 First release
* </pre>
*
******************************************************************************/
/***************************** 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);
}

View file

@ -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.
*
* <pre>
* 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
* </pre>
*
******************************************************************************/
#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 */

View file

@ -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.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ----- -------- -----------------------------------------------
* 1.00a xd/sv 01/12/10 First release
* </pre>
*
******************************************************************************/
/***************************** 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:
*
* <pre>
* 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.
* </pre>
*
* @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);
}

View file

@ -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.
*
* <pre>
* 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.
* </pre>
*
*****************************************************************************/
/***************************** 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.
* <br><br>
* 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;
}

View file

@ -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.
*
* <pre>
*
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ----- -------- -----------------------------------------------
* 1.00a xd/sv 01/12/10 First release
*
*
* </pre>
*
******************************************************************************/
/***************************** 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;
}