canfd_v1_0 : Added initial version for CanFd Driver.

This patch adds support for CanFd soft ip

Signed-off-by: naga sureshkumar relli <nagasure@xilinx.com>
This commit is contained in:
naga sureshkumar relli 2015-04-10 14:50:45 +05:30 committed by Nava kishore Manne
parent 0706340b26
commit 42234e4dd3
14 changed files with 6431 additions and 0 deletions

View file

@ -0,0 +1,54 @@
###############################################################################
#
# Copyright (C) 2015 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.0 nsk 06/04/15 First version of CANFD
##############################################################################
## @BEGIN_CHANGELOG EDK_M
##
## @END_CHANGELOG
## @BEGIN_CHANGELOG EDK_MS3
## @END_CHANGELOG
OPTION psf_version = 2.1;
BEGIN driver canfd
OPTION supported_peripherals = (canfd );
OPTION driver_state = ACTIVE;
OPTION copyfiles = all;
OPTION VERSION = 1.0;
OPTION NAME = canfd;
END driver

View file

@ -0,0 +1,39 @@
###############################################################################
#
# Copyright (C) 2015 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.
#
###############################################################################
#uses "xillib.tcl"
proc generate {drv_handle} {
xdefine_include_file $drv_handle "xparameters.h" "XCanfd" "NUM_INSTANCES" "DEVICE_ID" "C_BASEADDR" "C_HIGHADDR" "C_CAN_RX_DPTH" "C_CAN_TX_DPTH" "RX_MODE" "NUM_OF_RX_MB_BUF"
xdefine_config_file $drv_handle "xcanfd_g.c" "XCanFd" "DEVICE_ID" "C_BASEADDR" "RX_MODE" "NUM_OF_RX_MB_BUF"
xdefine_canonical_xpars $drv_handle "xparameters.h" "Canfd" "DEVICE_ID" "C_BASEADDR" "C_HIGHADDR" "C_CAN_RX_DPTH" "C_CAN_TX_DPTH" "RX_MODE" "NUM_OF_RX_MB_BUF"
}

View file

@ -0,0 +1,18 @@
<!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 canfd_v1_0 </h1>
<HR>
<ul>
<li>xcanfd_intr_example.c <a href="xcanfd_intr_example.c">(source)</a> </li>
<li>xcanfd_polled_example.c <a href="xcanfd_polled_example.c">(source)</a> </li>
</ul>
<p><font face="Times New Roman" color="#800000">Copyright @1995-2015 Xilinx, Inc. All rights reserved.</font></p>
</body>
</html>

View file

@ -0,0 +1,770 @@
/******************************************************************************
*
* Copyright (C) 2015 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 xcan_intr_example.c
*
* Contains an example of how to use the XCan driver directly. The example here
* shows using the driver/device in interrupt mode.
*
* @note
*
* This code assumes that Xilinx interrupt controller (XIntc) is used in the
* system to forward the CAN device interrupt output to the processor and no
* operating system is being used.
*
* 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 nsk 06/04/15 First release
*
* </pre>
*
******************************************************************************/
/***************************** Include Files *********************************/
#include "xcanfd.h"
#include "xparameters.h"
#include "xstatus.h"
#include "xil_exception.h"
#ifdef XPAR_INTC_0_DEVICE_ID
#include "xintc.h"
#include <stdio.h>
#else /* SCU GIC */
#include "xscugic.h"
#include "xil_printf.h"
#endif
/************************** 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_CAN_0_DEVICE_ID
#define CAN_INTR_VEC_ID XPAR_INTC_0_CANFD_0_VEC_ID
#ifdef XPAR_INTC_0_DEVICE_ID
#define INTC_DEVICE_ID XPAR_INTC_0_DEVICE_ID
#else
#define INTC_DEVICE_ID XPAR_SCUGIC_SINGLE_DEVICE_ID
#endif /* XPAR_INTC_0_DEVICE_ID */
/* Maximum CAN frame length in Bytes */
#define XCANFD_MAX_FRAME_SIZE_IN_BYTES 72
/* Frame Data field length */
#define FRAME_DATA_LENGTH 64
/* Message Id Constant */
#define TEST_MESSAGE_ID 2650
/* Data length code */
#define TEST_CANFD_DLC 15
/* Mail Box Mask */
#define TEST_MAILBOX_MASK 0xFFFFFFFF
/*
* The Baud Rate Prescaler Register (BRPR) and Bit Timing Register (BTR)
* are setup such that CANFD 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.
*/
#define TEST_BRPR_BAUD_PRESCALAR 29
#define TEST_BTR_SYNCJUMPWIDTH 3
#define TEST_BTR_SECOND_TIMESEGMENT 2
#define TEST_BTR_FIRST_TIMESEGMENT 15
#define TEST_FBRPR_BAUD_PRESCALAR 29
#define TEST_FBTR_SYNCJUMPWIDTH 3
#define TEST_FBTR_SECOND_TIMESEGMENT 2
#define TEST_FBTR_FIRST_TIMESEGMENT 15
#ifdef XPAR_INTC_0_DEVICE_ID
#define INTC XIntc
#define INTC_HANDLER XIntc_InterruptHandler
#else
#define INTC XScuGic
#define INTC_HANDLER XScuGic_InterruptHandler
#endif /* XPAR_INTC_0_DEVICE_ID */
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Function Prototypes ******************************/
static int XCanIntrExample(u16 DeviceId);
static void Config(XCanFd *InstancePtr);
void Create_CanFD_Frame();
static int SendFrame(XCanFd *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(XCanFd *InstancePtr);
/************************** Variable Definitions *****************************/
/* Allocate an instance of the XCan driver */
static XCanFd CanFd;
/*
* 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[XCANFD_MAX_FRAME_SIZE_IN_BYTES];
static u32 RxFrame[XCANFD_MAX_FRAME_SIZE_IN_BYTES];
/* Asynchronous error occurred */
volatile static int LoopbackError;
/* Received a frame */
volatile static int RecvDone;
/* Frame was sent successfully */
volatile static int SendDone;
/*****************************************************************************/
/**
*
* 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.
*
*****************************************************************************/
int main()
{
/* Run the Can interrupt example */
if (XCanIntrExample(CAN_DEVICE_ID)) {
xil_printf("XCanFd Interrupt Mode example Failed\n\r");
return XST_FAILURE;
}
xil_printf("XCanFd Interrupt Mode example Passed\n\r");
return XST_SUCCESS;
}
/*****************************************************************************/
/**
*
* The main entry point for showing the XCan driver in interrupt mode.
* The example configures the device for internal loopback mode, then
* sends a CAN frame and receives the same CAN frame.
*
* @param DeviceId contains the CAN device ID.
*
* @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.
*
******************************************************************************/
static int XCanIntrExample(u16 DeviceId)
{
int Status;
XCanFd *CanFdInstPtr = &CanFd;
XCanFd_Config *ConfigPtr;
/* Initialize the XCan driver */
ConfigPtr = XCanFd_LookupConfig(DeviceId);
if (CanFdInstPtr == NULL) {
return XST_FAILURE;
}
Status = XCanFd_CfgInitialize(CanFdInstPtr,
ConfigPtr,ConfigPtr->BaseAddress);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
/*
* Run self-test on the device, which verifies basic sanity of the
* device and the driver.
*/
Status = XCanFd_SelfTest(CanFdInstPtr);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
/* Configure the CAN device */
Config(CanFdInstPtr);
XCanFd_SetHandler(CanFdInstPtr, XCANFD_HANDLER_SEND,
(void *)SendHandler, (void *)CanFdInstPtr);
XCanFd_SetHandler(CanFdInstPtr, XCANFD_HANDLER_RECV,
(void *)RecvHandler, (void *)CanFdInstPtr);
XCanFd_SetHandler(CanFdInstPtr, XCANFD_HANDLER_ERROR,
(void *)ErrorHandler, (void *)CanFdInstPtr);
XCanFd_SetHandler(CanFdInstPtr, XCANFD_HANDLER_EVENT,
(void *)EventHandler, (void *)CanFdInstPtr);
/* Initialize flags */
SendDone = FALSE;
RecvDone = FALSE;
LoopbackError = FALSE;
/* Connect to the interrupt controller */
Status = SetupInterruptSystem(CanFdInstPtr);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
/* Enable all interrupts in CAN device */
XCanFd_InterruptEnable(CanFdInstPtr, XCANFD_IXR_ALL);
/* Set the CAN Mode to LOOP Back */
XCanFd_EnterMode(CanFdInstPtr, XCANFD_MODE_LOOPBACK);
while (XCanFd_GetMode(CanFdInstPtr) != XCANFD_MODE_LOOPBACK);
Status = SendFrame(CanFdInstPtr);
if (Status != XST_SUCCESS)
return Status;
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.
*
* @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.
* basically this configures BRPR,BTR in both Arbitration and
* Data phase. also configures Acceptance filters(in SequentialMode)
* or RxBuffers(in Mailbox).
*
******************************************************************************/
static void Config(XCanFd *InstancePtr)
{
u32 RxBuffer;
u32 IdValue;
u8 RxBuffers;
XCanFd_EnterMode(InstancePtr, XCANFD_MODE_CONFIG);
while (XCanFd_GetMode(InstancePtr) != XCANFD_MODE_CONFIG);
/* Configure the Baud Rate Prescalar in Arbitration Phase */
XCanFd_SetBaudRatePrescaler(InstancePtr, TEST_BRPR_BAUD_PRESCALAR);
/* Configure the Bit Timing Values in Arbitration Phase */
XCanFd_SetBitTiming(InstancePtr, TEST_BTR_SYNCJUMPWIDTH,\
TEST_BTR_SECOND_TIMESEGMENT,TEST_BTR_FIRST_TIMESEGMENT);
/* Configure the Baud Rate Prescalar in Data Phase */
XCanFd_SetFBaudRatePrescaler(InstancePtr, TEST_FBRPR_BAUD_PRESCALAR);
/* Configure the Bit Timing Values in Data Phase */
XCanFd_SetFBitTiming(InstancePtr,TEST_FBTR_SYNCJUMPWIDTH,\
TEST_FBTR_SECOND_TIMESEGMENT,TEST_FBTR_FIRST_TIMESEGMENT);
/*
* Disable the Global BRS Disable so that at the time of sending the can
* frame we will choose whether we need Bit Rate Switch or not.
*/
XCanFd_SetBitRateSwitch_DisableNominal(InstancePtr);
/* Configure Acceptance Filter/Mail box depends on design */
if (XCANFD_GET_RX_MODE(InstancePtr) == 0) {
XCanFd_AcceptFilterDisable(InstancePtr,XCANFD_AFR_UAF_ALL_MASK);
XCanFd_AcceptFilterEnable(InstancePtr,XCANFD_AFR_UAF_ALL_MASK);
}
else {
RxBuffers = XCanFd_Get_RxBuffers(InstancePtr);
IdValue = XCanFd_CreateIdValue(TEST_MESSAGE_ID, 0, 0, 0, 0);
for (RxBuffer = 0;RxBuffer < RxBuffers;RxBuffer++) {
XCanFd_RxBuff_MailBox_DeActive(InstancePtr,RxBuffer);
XCanFd_Set_MailBox_IdMask(InstancePtr,RxBuffer,\
TEST_MAILBOX_MASK,IdValue);
XCanFd_RxBuff_MailBox_Active(InstancePtr,RxBuffer);
}
}
/* Configure the CAN Device to Enter Loop Back Mode */
XCanFd_EnterMode(InstancePtr, XCANFD_MODE_LOOPBACK);
while (XCanFd_GetMode(InstancePtr) != XCANFD_MODE_LOOPBACK);
}
/*****************************************************************************/
/**
*
* Send a CAN frame.
*
* @param InstancePtr is a pointer to the driver instance.
*
* @return None.
*
* @note None.
*
******************************************************************************/
static int SendFrame(XCanFd *InstancePtr)
{
int Status;
u32 TxBufferNumber;
u8 *FramePtr;
u32 Index;
int NofBytes;
/*
* Create correct values for Identifier and Data Length Code Register.
* Here Data Length Code value is 8
* but CAN FD Can support upto DLC 15(64Bytes).
*/
TxFrame[0] = XCanFd_CreateIdValue(TEST_MESSAGE_ID, 0, 0, 0, 0);
TxFrame[1] = XCanFd_Create_CanFD_Dlc_BrsValue(TEST_CANFD_DLC);
NofBytes = XCanFd_GetDlc2len(TxFrame[1] & XCANFD_DLCR_DLC_MASK);
/*
* Now fill in the data field with known values so we can verify them
* on receive.
*/
FramePtr = (u8 *)(&TxFrame[2]);
for (Index = 0; Index < NofBytes; Index++) {
*FramePtr++ = (u8)Index;
}
/* Now send the frame */
Status = XCanFd_Send(InstancePtr, TxFrame,&TxBufferNumber);
if (Status == XST_FIFO_NO_ROOM)
return Status;
if (Status != XST_SUCCESS) {
/* The frame could not be sent successfully */
LoopbackError = TRUE;
SendDone = TRUE;
RecvDone = TRUE;
}
return Status;
}
/*****************************************************************************/
/**
*
* 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)
{
XCanFd *CanPtr = (XCanFd *)CallBackRef;
int Status;
int Index;
u8 *FramePtr;
u32 Dlc;
/* Check for the design 1 - MailBox 0 - Sequential */
if (XCANFD_GET_RX_MODE(CanPtr) == 1) {
Status = XCanFd_Recv_Mailbox(CanPtr, RxFrame);
}
else {
Status = XCanFd_Recv_Sequential(CanPtr, RxFrame);
}
/* Get the Dlc inthe form of bytes */
Dlc = XCanFd_GetDlc2len(RxFrame[1] & XCANFD_DLCR_DLC_MASK);
if (Status != XST_SUCCESS) {
LoopbackError = TRUE;
RecvDone = TRUE;
return;
}
/* Verify Identifier and Data Length Code */
if (RxFrame[0] != XCanFd_CreateIdValue(TEST_MESSAGE_ID, 0, 0, 0, 0)) {
LoopbackError = TRUE;
RecvDone = TRUE;
return;
}
if (TEST_CANFD_DLC != XCanFd_GetLen2Dlc(Dlc)) {
LoopbackError = TRUE;
RecvDone = TRUE;
return;
}
/* Verify Data field contents */
FramePtr = (u8 *)(&RxFrame[2]);
for (Index = 0; Index < Dlc; 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 XCANFD_ESR_* defined in
* xcanfd_l.h
*
* @return None.
*
* @note This function is called by the driver within interrupt context.
*
******************************************************************************/
static void ErrorHandler(void *CallBackRef, u32 ErrorMask)
{
XCanFd *CanPtr = (XCanFd *)CallBackRef;
if (ErrorMask & XCANFD_ESR_ACKER_MASK) {
/* ACK Error handling code should be put here */
}
if (ErrorMask & XCANFD_ESR_BERR_MASK) {
/* Bit Error handling code should be put here */
}
if (ErrorMask & XCANFD_ESR_STER_MASK) {
/* Stuff Error handling code should be put here */
}
if (ErrorMask & XCANFD_ESR_FMER_MASK) {
/* Form Error handling code should be put here */
}
if (ErrorMask & XCANFD_ESR_CRCER_MASK) {
/* CRC Error handling code should be put here */
}
if (ErrorMask & XCANFD_ESR_F_BERR_MASK) {
/* Bit Error handling code should be put here */
}
if (ErrorMask & XCANFD_ESR_F_STER_MASK) {
/* Stuff Error handling code should be put here */
}
if (ErrorMask & XCANFD_ESR_F_FMER_MASK) {
/* Form Error handling code should be put here */
}
if (ErrorMask & XCANFD_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:
* - XCANFD_IXR_BSOFF_MASK: Bus Off Interrupt
* - XCANFD_IXR_RXOFLW_MASK: RX FIFO Overflow Interrupt
* - XCANFD_IXR_RXUFLW_MASK: RX FIFO Underflow Interrupt
* - XCANFD_IXR_TXBFLL_MASK: TX High Priority Buffer Full Interrupt
* - XCANFD_IXR_TXFLL_MASK: TX FIFO Full Interrupt
* - XCANFD_IXR_WKUP_MASK: Wake up Interrupt
* - XCANFD_IXR_SLP_MASK: Sleep Interrupt
* - XCANFD_IXR_ARBLST_MASK: Arbitration Lost Interrupt
*
* Please feel free to change this function to meet specific application needs.
*
* @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 XCANFD_IXR_*_MASK value(s)
* mentioned above.
*
* @return None.
*
* @note This function is called by the driver within interrupt context.
*
******************************************************************************/
static void EventHandler(void *CallBackRef, u32 IntrMask)
{
XCanFd *CanPtr = (XCanFd *)CallBackRef;
if (IntrMask & XCANFD_IXR_BSOFF_MASK) {
/*
* Entering Bus off status interrupt requires the CAN device be
* reset and re-configurated.
*/
XCanFd_Reset(CanPtr);
Config(CanPtr);
return;
}
if (IntrMask & XCANFD_IXR_RXFOFLW_MASK) {
/*
* Code to handle RX FIFO Overflow Interrupt should be put here
*/
}
if (IntrMask & XCANFD_IXR_RXMNF_MASK) {
/*
* Code to handle RX Match Not Finished Interrupt should be put
* here
*/
}
if (IntrMask & XCANFD_IXR_RXBOFLW_MASK) {
/*
* Code to handle RX Buffer Overflow Interrupt should be put
* here
*/
}
if (IntrMask & XCANFD_IXR_RXRBF_MASK) {
/*
* Code to handle RX Buffer Full Interrupt should be put here
*/
}
if (IntrMask & XCANFD_IXR_TXCRS_MASK) {
/*
* Code to handle Tx Cancelation Request Served Interrupt
* should be put here.
*/
}
if (IntrMask & XCANFD_IXR_TXRRS_MASK) {
/*
* Code to handle Tx Ready Request Served Interrupt should be
* put here
*/
}
if (IntrMask & XCANFD_IXR_WKUP_MASK) {
/*
* Code to handle Wake up from sleep mode Interrupt should be
* put here.
*/
}
if (IntrMask & XCANFD_IXR_SLP_MASK) {
/*
* Code to handle Enter sleep mode Interrupt should be put here
*/
}
if (IntrMask & XCANFD_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.
*
* @para InstancePtr is a pointer to the instance of the CAN
* which is going to be connected to the interrupt controller.
*
* @return XST_SUCCESS if successful, otherwise XST_FAILURE.
*
* @note None.
*
****************************************************************************/
static int SetupInterruptSystem(XCanFd *InstancePtr)
{
static INTC InterruptController;
int Status;
#ifdef XPAR_INTC_0_DEVICE_ID
/*
* Initialize the interrupt controller driver so that it's ready to use.
* INTC_DEVICE_ID specifies the XINTC device ID that is generated in
* xparameters.h.
*/
Status = XIntc_Initialize(&InterruptController, INTC_DEVICE_ID);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
/*
* Connect the device driver handler that will be called when an
* interrupt for the device occurs, the device driver handler performs
* the specific interrupt processing for the device.
*/
Status = XIntc_Connect(&InterruptController,
CAN_INTR_VEC_ID,
(XInterruptHandler)XCanFd_IntrHandler,
InstancePtr);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
/*
* Start the interrupt controller so interrupts are enabled for all
* devices that cause interrupts. Specify real mode so that the CAN
* can cause interrupts through the interrupt controller.
*/
Status = XIntc_Start(&InterruptController, XIN_REAL_MODE);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
/* Enable the interrupt for the CAN. */
XIntc_Enable(&InterruptController, CAN_INTR_VEC_ID);
#else /* SCUGIC */
XScuGic_Config *IntcConfig;
/*
* Initialize the interrupt controller driver so that it is ready to
* use.
*/
IntcConfig = XScuGic_LookupConfig(INTC_DEVICE_ID);
if (NULL == IntcConfig) {
return XST_FAILURE;
}
Status = XScuGic_CfgInitialize(&InterruptController, IntcConfig,
IntcConfig->CpuBaseAddress);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
XScuGic_SetPriorityTriggerType(&InterruptController, CAN_INTR_VEC_ID,
0xA0, 0x3);
/*
* Connect the interrupt handler that will be called when an
* interrupt occurs for the device.
*/
Status = XScuGic_Connect(&InterruptController, CAN_INTR_VEC_ID,
(Xil_ExceptionHandler)XCanFd_IntrHandler,
InstancePtr);
if (Status != XST_SUCCESS) {
return Status;
}
/* Enable the interrupt for the Can device */
XScuGic_Enable(&InterruptController, CAN_INTR_VEC_ID);
#endif
/* Initialize the exception table */
Xil_ExceptionInit();
/*
* Register the interrupt controller handler with the exception table.
*/
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
(Xil_ExceptionHandler)INTC_HANDLER,
&InterruptController);
/* Enable exceptions */
Xil_ExceptionEnable();
return XST_SUCCESS;
}

View file

@ -0,0 +1,392 @@
/******************************************************************************
*
* Copyright (C) 2015 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 XCanFd_polled_example.c
*
* Contains an example of how to use the XCan driver directly. The example here
* shows using the driver/device in polled 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 frequency 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 nsk 06/04/2015 First release
*
* </pre>
*
******************************************************************************/
/***************************** Include Files *********************************/
#include "xparameters.h"
#include "xcanfd.h"
#include "xstatus.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_CAN_0_DEVICE_ID
/* Maximum CAN frame length in Bytes */
#define XCANFD_MAX_FRAME_SIZE_IN_BYTES 72
#define FRAME_DATA_LENGTH 64
/* Message Id Constant */
#define TEST_MESSAGE_ID 2650
/*
* 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 frequency 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.
* both in DataPhase and Arbitration Phase.
*/
#define TEST_BRPR_BAUD_PRESCALAR 29
#define TEST_BTR_SYNCJUMPWIDTH 3
#define TEST_BTR_SECOND_TIMESEGMENT 2
#define TEST_BTR_FIRST_TIMESEGMENT 15
#define TEST_FBRPR_BAUD_PRESCALAR 29
#define TEST_FBTR_SYNCJUMPWIDTH 3
#define TEST_FBTR_SECOND_TIMESEGMENT 2
#define TEST_FBTR_FIRST_TIMESEGMENT 15
/* Mask for MailBox */
#define TEST_MAILBOX_MASK 0xFFFFFFFF
/* Test Message Dlc */
#define TESTMSG_DLC 15
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Function Prototypes ******************************/
int XCanPolledExample(u16 DeviceId);
static int SendFrame(XCanFd *InstancePtr);
static int RecvFrame(XCanFd *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[XCANFD_MAX_FRAME_SIZE_IN_BYTES];
static u32 RxFrame[XCANFD_MAX_FRAME_SIZE_IN_BYTES];
/* Driver instance */
static XCanFd CanFd;
/*****************************************************************************/
/**
*
* Main function to call the example. This function is not included if the
* example is generated from the TestAppGen test tool.
*
* @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(void)
{
/*
* Run the Can Polled example, specify the Device ID that is generated
* in xparameters.h .
*/
if (XCanPolledExample(CAN_DEVICE_ID)) {
xil_printf("XCanFd Polled Mode example Failed\n\r");
return XST_FAILURE;
}
xil_printf("XCanFd Polled Mode example Passed\n\r");
return XST_SUCCESS;
}
#endif
/*****************************************************************************/
/**
*
* The entry point for showing the XCan driver in polled mode. The example
* configures the device for internal loopback mode, then sends a Can
* frame, receives the same Can frame, and verifies the frame contents.
*
* @param DeviceId is the XPAR_CAN_<instance_num>_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 XCanPolledExample(u16 DeviceId)
{
int Status;
XCanFd *CanFdInstPtr = &CanFd;
XCanFd_Config *ConfigPtr;
u32 IdValue;
u32 BuffNr;
u8 RxBuffers;
/* Initialize the Can device */
ConfigPtr = XCanFd_LookupConfig(DeviceId);
if (CanFdInstPtr == NULL) {
return XST_FAILURE;
}
Status = XCanFd_CfgInitialize(CanFdInstPtr,
ConfigPtr,
ConfigPtr->BaseAddress);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
/*
* Run self-test on the device, which verifies basic sanity of the
* device and the driver.
*/
Status = XCanFd_SelfTest(CanFdInstPtr);
if (Status != XST_SUCCESS) {
return Status;
}
/*
* Enter Configuration Mode so we can setup Baud Rate Prescaler
* Register (BRPR) and Bit Timing Register (BTR)
*/
XCanFd_EnterMode(CanFdInstPtr, XCANFD_MODE_CONFIG);
while (XCanFd_GetMode(CanFdInstPtr) != XCANFD_MODE_CONFIG);
/*
* Configure the Baud Rate Prescalar in
* Arbitration Phase
*/
XCanFd_SetBaudRatePrescaler(CanFdInstPtr, TEST_BRPR_BAUD_PRESCALAR);
/*
* Configure the Bit Timing Values in
* Arbitration Phase.
*/
XCanFd_SetBitTiming(CanFdInstPtr, TEST_BTR_SYNCJUMPWIDTH,
TEST_BTR_SECOND_TIMESEGMENT,TEST_BTR_FIRST_TIMESEGMENT);
/* Configure the Baud Rate Prescalar in Data Phase */
XCanFd_SetFBaudRatePrescaler(CanFdInstPtr, TEST_FBRPR_BAUD_PRESCALAR);
/* Configure the Bit Timing Values in Data Phase */
XCanFd_SetFBitTiming(CanFdInstPtr,TEST_FBTR_SYNCJUMPWIDTH,
TEST_FBTR_SECOND_TIMESEGMENT,TEST_FBTR_FIRST_TIMESEGMENT);
/*
* Disable the Global BRS Disable so that
* at the time of sending the can frame
* we will choose whether we need Bit
* Rate Switch or not.
*/
XCanFd_SetBitRateSwitch_DisableNominal(CanFdInstPtr);
/*
* Check for the design
* 0 - Sequential Mode
* 1 - MailBox Mode.
*/
if (XCANFD_GET_RX_MODE(CanFdInstPtr) == 0) {
XCanFd_AcceptFilterDisable(CanFdInstPtr,
XCANFD_AFR_UAF_ALL_MASK);
XCanFd_AcceptFilterEnable(CanFdInstPtr,
XCANFD_AFR_UAF_ALL_MASK);
}
else {
RxBuffers = XCanFd_Get_RxBuffers(CanFdInstPtr);
IdValue = XCanFd_CreateIdValue(TEST_MESSAGE_ID, 0, 0, 0, 0);
for (BuffNr = 0;BuffNr < RxBuffers;BuffNr++) {
XCanFd_RxBuff_MailBox_DeActive(CanFdInstPtr,BuffNr);
XCanFd_Set_MailBox_IdMask(CanFdInstPtr,BuffNr,
TEST_MAILBOX_MASK,IdValue);
XCanFd_RxBuff_MailBox_Active(CanFdInstPtr,BuffNr);
}
}
/* Configure CAN Device to enter to Loop Back Mode */
XCanFd_EnterMode(CanFdInstPtr, XCANFD_MODE_LOOPBACK);
while (XCanFd_GetMode(CanFdInstPtr) != XCANFD_MODE_LOOPBACK);
/* Send Frame */
Status = SendFrame(CanFdInstPtr);
if (Status != XST_SUCCESS) {
return Status;
}
/* Receive The Frame */
Status = RecvFrame(CanFdInstPtr);
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(XCanFd *InstancePtr)
{
int Status;
u32 TxBufferNumber;
u8 *FramePtr;
u32 Index;
int NofBytes;
/* Create correct values for Identifier and Data Length Code Register */
TxFrame[0] = XCanFd_CreateIdValue(TEST_MESSAGE_ID, 0, 0, 0, 0);
TxFrame[1] = XCanFd_Create_CanFD_Dlc_BrsValue(TESTMSG_DLC);
/*
* Get the number of bytes to transmit so that we can buffer with those
* many bytes
*/
NofBytes = XCanFd_GetDlc2len(TxFrame[1] & XCANFD_DLCR_DLC_MASK);
/*
* Now fill in the data field with known values so we can verify them
* on receive.
*/
FramePtr = (u8 *)(&TxFrame[2]);
for (Index = 0; Index < NofBytes; Index++) {
*FramePtr++ = (u8)Index;
}
/* Now send the frame */
Status = XCanFd_Send(InstancePtr, TxFrame,&TxBufferNumber);
if (Status == XST_FIFO_NO_ROOM)
return Status;
/* Wait until Buffer is Transmitted */
while (XCanFd_IsBufferTransmitted(InstancePtr,TxBufferNumber)
== FALSE);
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(XCanFd *InstancePtr)
{
int Status;
int Dlc;
u8 *FramePtr;
u32 Index;
/* Receive a frame and verify its contents */
if (XCANFD_GET_RX_MODE(InstancePtr) == 1) {
Status = XCanFd_Recv_Mailbox(InstancePtr, RxFrame);
}
else {
Status = XCanFd_Recv_Sequential(InstancePtr, RxFrame);
}
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
/* Get Dlc value */
Dlc = XCanFd_GetDlc2len(RxFrame[1] & XCANFD_DLCR_DLC_MASK);
/* Verify Identifier and Data Length Code */
if (RxFrame[0] != XCanFd_CreateIdValue(TEST_MESSAGE_ID, 0, 0, 0, 0)) {
return XST_FAILURE;
}
if (TESTMSG_DLC != XCanFd_GetLen2Dlc(Dlc)) {
return XST_FAILURE;
}
/* Verify Data field contents */
FramePtr = (u8 *)(&RxFrame[2]);
for (Index = 0; Index < Dlc; Index++) {
if (*FramePtr++ != (u8)Index) {
return XST_FAILURE;
}
}
return Status;
}

View file

@ -0,0 +1,27 @@
COMPILER=
ARCHIVER=
CP=cp
COMPILER_FLAGS=
EXTRA_COMPILER_FLAGS=
LIB=libxil.a
RELEASEDIR=../../../lib
INCLUDEDIR=../../../include
INCLUDES=-I./. -I${INCLUDEDIR}
INCLUDEFILES=*.h
LIBSOURCES=*.c
OUTS = *.o
libs:
echo "Compiling can"
$(COMPILER) $(COMPILER_FLAGS) $(EXTRA_COMPILER_FLAGS) $(INCLUDES) $(LIBSOURCES)
$(ARCHIVER) -r ${RELEASEDIR}/${LIB} ${OUTS}
make clean
include:
${CP} ${INCLUDEFILES} ${INCLUDEDIR}
clean:
rm -rf ${OUTS}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,928 @@
/******************************************************************************
*
* Copyright (C) 2015 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 xcanfd.h
*
* The Xilinx CANFD driver. This driver supports the Xilinx CANFD Controller.
*
* The CANFD 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 8 Mbps.
* - Transmit message object FIFO with a user configurable depth of up to 64
* message objects.
* - Receive message object FIFO with a user configurable depth of up to 64
* message objects.
* - Acceptance filtering through a user configurable number of up to 32
* acceptance filters.
* - Loop Back mode for diagnostic applications.
* - Maskable Error and Status Interrupts.
* - Readable Error Counters.
* - External PHY chip required.
* - Backward compatiable for Legacy CAN.
* - Supports reception in Milibox and Sequential Mode
*
* 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 CANFD. 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 CANFD. A single device
* driver can support multiple CANFDs.
*
* Since the driver is a simple pass-through mechanism between a protocol stack
* and the CANFD, no assembly or disassembly of CANFD frames is done at the
* driver-level. This assumes that the protocol stack passes a correctly
* formatted CANFD frame to the driver for transmission, and that the driver
* does not validate the contents of an incoming frame
*
* <b>Operation Modes</b>
*
* The CANFD 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 loop backed to the rx line and acknowledged. The CAN controller
* thus receives any message that it transmits. It does not participate in
* normal bus communication and does not receive any messages that are
* transmitted by other CAN nodes. This mode is used for diagnostic
* purposes.
* - <b>Snoop mode</b>:in Snoop Mode,The CAN controller transmits recessive
* bit stream on to CAN bus and does not participate in normal bus
* communication but receives messages that are transmitted by other
* CAN nodes.Received messages are stored based on receive ID match result.
* Error counters are disabled and cleared to 0. Reads to error counter
* register will return zero.
*
* <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 up to
* 32 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.
*
* <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>Virtual Memory</b>
*
* This driver supports Virtual Memory. The RTOS is responsible for calculating
* the correct device base address in Virtual Memory space and invoking function
* XCanFd_VmInitialize(), instead of XCanFd_Initialize(), to initialize the device
* at first.
*
* <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 xcan_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, and the number of acceptance filters.
*
* <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 XCanFd 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>
* Temp Change
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -------------------------------------------------------
* 1.00a nsk 06/04/15 First release
*
* </pre>
*
******************************************************************************/
#ifndef XCANFD_H /* prevent circular inclusions */
#define XCANFD_H /* by using protection macros */
#ifdef __cplusplus
extern "C" {
#endif
/***************************** Include Files *********************************/
#include "xstatus.h"
#include "xcanfd_l.h"
/************************** Constant Definitions *****************************/
/** @name CAN operation modes
* @{
*/
#define XCANFD_MODE_CONFIG 0x00000001 /**< Configuration mode */
#define XCANFD_MODE_NORMAL 0x00000002 /**< Normal mode */
#define XCANFD_MODE_LOOPBACK 0x00000004 /**< Loop Back mode */
#define XCANFD_MODE_SLEEP 0x00000008 /**< Sleep mode */
#define XCANFD_MODE_SNOOP 0x00000010
/* @} */
/** @name Callback identifiers used as parameters to XCanFd_SetHandler()
* @{
*/
#define XCANFD_HANDLER_SEND 1 /**< Handler type for frame sending interrupt
*/
#define XCANFD_HANDLER_RECV 2 /**< Handler type for frame reception interrupt
*/
#define XCANFD_HANDLER_ERROR 3 /**< Handler type for error interrupt */
#define XCANFD_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 BaseAddress; /**< Register base address */
u32 Rx_Mode; /**< 1-Mailbox 0-sequential */
u32 NumofRxMbBuf; /**< Number of RxBuffers */
} XCanFd_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 (*XCanFd_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 XCANFD_ESR_* values defined in
* xcan_l.h
******************************************************************************/
typedef void (*XCanFd_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 XCANFD_IXR_* defined in xcanfd_l.h
******************************************************************************/
typedef void (*XCanFd_EventHandler) (void *CallBackRef, u32 Mask);
/*****************************************************************************/
/**
* The XCanFd 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 {
XCanFd_Config CanFdConfig; /**< Device Configuration */
u32 IsReady; /**< Device is initialized and ready */
u32 MultiBuffTrr; /**< used in multibuffer send case
to update TRR Register */
u8 FreeBuffStatus[32]; /**< Buffer Status */
XCanFd_SendRecvHandler SendHandler;
void *SendRef;
XCanFd_SendRecvHandler RecvHandler;
void *RecvRef;
XCanFd_ErrorHandler ErrorHandler;
void *ErrorRef;
XCanFd_EventHandler EventHandler;
void *EventRef;
}XCanFd;
/***************** Macros (Inline Functions) Definitions *********************/
/*****************************************************************************/
/**
*
* This macro checks if the transmission is complete.
*
* @param InstancePtr is a pointer to the XCanFd instance to be worked on.
*
* @return - TRUE if the transmission is done (completed).
* - FALSE if the transmission is not completed.
*
* @note C-Style signature:
* int XCanFd_IsTxDone(XCanFd *InstancePtr);
*
*****************************************************************************/
#define XCanFd_IsTxDone(InstancePtr) \
((XCanFd_ReadReg(((InstancePtr)->CanFdConfig.BaseAddress), \
XCANFD_ISR_OFFSET) & XCANFD_IXR_TXOK_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 XCanFd_CreateIdValue(u32 StandardId, u32 SubRemoteTransReq,
* u32 IdExtension, u32 ExtendedId,
* u32 RemoteTransReq);
*
* Read the CAN specification for meaning of each parameter.
*
*****************************************************************************/
#define XCanFd_CreateIdValue(StandardId, SubRemoteTransReq, IdExtension, \
ExtendedId, RemoteTransReq) \
((((StandardId) << XCANFD_IDR_ID1_SHIFT) & XCANFD_IDR_ID1_MASK) | \
(((SubRemoteTransReq) << XCANFD_IDR_SRR_SHIFT) & XCANFD_IDR_SRR_MASK) | \
(((IdExtension) << XCANFD_IDR_IDE_SHIFT) & XCANFD_IDR_IDE_MASK) | \
(((ExtendedId) << XCANFD_IDR_ID2_SHIFT) & XCANFD_IDR_ID2_MASK) | \
((RemoteTransReq) & XCANFD_IDR_RTR_MASK))
/****************************************************************************/
/**
*
* This macro calculates value for Data Length Code register given Data
* Length Code value with EDL set to 1(Only Can FD frames).
*
* @param DataLengCode indicates Data Length Code value.
*
* @return Value that can be assigned to Data Length Code register.
*
* @note C-Style signature:
* u32 XCanFd_Create_CanFD_DlcValue(u32 DataLengCode);
*
* Read the CAN specification for meaning of Data Length Code.
*
*****************************************************************************/
#define XCanFd_Create_CanFD_DlcValue(DataLengCode) \
((((DataLengCode) << XCANFD_DLCR_DLC_SHIFT) & XCANFD_DLCR_DLC_MASK) \
|(XCANFD_DLCR_EDL_MASK))
/****************************************************************************/
/**
*
* This macro calculates value for Data Length Code register given Data
* Length Code value with EDL set to 1(Only Can FD frames) and Setting the BRS.
*
* @param DataLengCode indicates Data Length Code value.
*
* @return Value that can be assigned to Data Length Code register.
*
* @note C-Style signature:
* u32 XCanFd_Create_CanFD_Dlc_BrsValue(u32 DataLengCode);
*
* Read the CAN specification for meaning of Data Length Code.
*
*****************************************************************************/
#define XCanFd_Create_CanFD_Dlc_BrsValue(DataLengCode) \
((((DataLengCode) << XCANFD_DLCR_DLC_SHIFT) & XCANFD_DLCR_DLC_MASK) \
|(XCANFD_DLCR_EDL_MASK) |(XCANFD_DLCR_BRS_MASK))
/****************************************************************************/
/**
*
* This macro calculates value for Data Length Code register given Data
* Length Code value i.e Only Stand.. Can frames.
*
* @param DataLengCode indicates Data Length Code value.
*
* @return Value that can be assigned to Data Length Code register.
*
* @note C-Style signature:
* u32 XCanFd_CreateDlcValue(u32 DataLengCode);
*
* Read the CAN specification for meaning of Data Length Code.
*
*****************************************************************************/
#define XCanFd_CreateDlcValue(DataLengCode) \
((((DataLengCode) << XCANFD_DLCR_DLC_SHIFT) & XCANFD_DLCR_DLC_MASK))
/****************************************************************************/
/**
*
* This macro checks whether Particular Buffer is Transmitted or not
*
* Transmit Ready Request Register gives which Buffer is transmitted
* if you trigger the Buffer1 then
* TRR Reg : 0x00000001
* After transmission Core clears the bit
* TRR Reg : 0x00000000
*
* @param InstancePtr is a pointer to the XCanFd instance to be worked on.
*
* @param TxBuffer is the buffer where driver has written user data\
*
* @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 XCanFd_IsAcceptFilterBusy(XCanFd *InstancePtr);
*
*****************************************************************************/
#define XCanFd_IsBufferTransmitted(InstancePtr,TxBuffer) \
((XCanFd_ReadReg(InstancePtr->CanFdConfig.BaseAddress, \
XCANFD_TRR_OFFSET) & (1 << TxBuffer)) ? FALSE : TRUE)
/****************************************************************************/
/**
* This macro initializes CurrentBuffer[32] to zeros.
*
* @param InstancePtr is a pointer to the XCanFd instance to be worked on.
*
* @return none
*
* @note makes bufferstatus to zero.
*
*****************************************************************************/
#define MAKE_CURRENTBUFFER_ZERO(InstancePtr) \
for (BufferNr = 0;BufferNr <= 31; BufferNr++) \
InstancePtr->FreeBuffStatus[BufferNr] = 0
/*****************************************************************************/
/**
* This macro Returns the TXBUFFER ID Offset
*
* @param FreeBuffer is the Buffer number to locate the FIFO Index
*
* @note none
*
*****************************************************************************/
#define XCANFD_TXID_OFFSET(FreeBuffer) \
(XCANFD_TXFIFO_0_BASE_ID_OFFSET+(FreeTxBuffer*XCANFD_MAX_FRAME_SIZE))
/*****************************************************************************/
/**
* This macro Returns the TXBUFFER DLC Offset
*
* @param FreeBuffer is the Buffer number to locate the FIFO
*
* @note none
*
*****************************************************************************/
#define XCANFD_TXDLC_OFFSET(FreeBuffer) \
(XCANFD_TXFIFO_0_BASE_DLC_OFFSET+(FreeTxBuffer*XCANFD_MAX_FRAME_SIZE))
/*****************************************************************************/
/**
* This macro Returns the TXBUFFER DW Offset
*
* @param FreeBuffer is the Buffer number to locate the FIFO
*
* @note none
*
*****************************************************************************/
#define XCANFD_TXDW_OFFSET(FreeBuffer) \
(XCANFD_TXFIFO_0_BASE_DW0_OFFSET+(FreeTxBuffer*XCANFD_MAX_FRAME_SIZE))
/*****************************************************************************/
/**
* This macro Returns the RXBUFFER ID Offset
*
* @param ReadIndex is the Buffer number to locate the FIFO
*
* @note none
*
*****************************************************************************/
#define XCANFD_RXID_OFFSET(ReadIndex) \
(XCANFD_RXFIFO_0_BASE_ID_OFFSET+(ReadIndex*XCANFD_MAX_FRAME_SIZE))
/*****************************************************************************/
/**
* This macro Returns the RXBUFFER DLC Offset
*
* @param ReadIndex is the Buffer number to locate the FIFO
*
* @note none
*
*****************************************************************************/
#define XCANFD_RXDLC_OFFSET(ReadIndex) \
(XCANFD_RXFIFO_0_BASE_DLC_OFFSET+(ReadIndex*XCANFD_MAX_FRAME_SIZE))
/*****************************************************************************/
/**
* This macro Returns the RXBUFFER DW Offset
*
* @param ReadIndex is the Buffer number to locate the FIFO
*
* @note none
*
*****************************************************************************/
#define XCANFD_RXDW_OFFSET(ReadIndex) \
(XCANFD_RXFIFO_0_BASE_DW0_OFFSET+(ReadIndex*XCANFD_MAX_FRAME_SIZE))
/*****************************************************************************/
/**
* This macro Returns the RCS Register Offset
*
* @param NoCtrlStatus is to locate RCS Registers
*
* @note NoCtrlStatus = 0 -> RCS0
* 1 -> RCS1
* 2 -> RCS2
*
*****************************************************************************/
#define XCANFD_RCS_OFFSET(NoCtrlStatus) \
(XCANFD_RCS0_OFFSET+(NoCtrlStatus*4))
/*****************************************************************************/
/**
* This macro Returns the AFMR Register Offset
*
* @param FilterIndex is the Index number of Mask Register
*
* @note none
*
*****************************************************************************/
#define XCANFD_AFMR_OFFSET(FilterIndex) \
(XCANFD_AFMR_BASE_OFFSET+\
(FilterIndex*8))
/*****************************************************************************/
/**
* This macro Returns the AFIDR Registger Offset
*
* @param FilterIndex is the Index of Id Register
*
* @note none
*
*****************************************************************************/
#define XCANFD_AFIDR_OFFSET(FilterIndex) \
(XCANFD_AFIDR_BASE_OFFSET+\
(FilterIndex*8))
/*****************************************************************************/
/**
* This macro Returns the MAILBOX MODE RXMASK Offset
*
* @param BufferNr is the Buffer number to locate the FIFO
*
* @note none
*
*****************************************************************************/
#define XCANFD_MAILBOX_MASK_OFFSET(BufferNr) \
(XCANFD_MAILBOX_RB_MASK_BASE_OFFSET+(BufferNr*4))
/*****************************************************************************/
/**
* This macro Returns the MAILBOX MODE ID Offset
*
* @param BufferNr is the Buffer number to locate the FIFO
*
* @note none
*
*****************************************************************************/
#define XCANFD_MAILBOX_ID_OFFSET(BufferNr) \
(XCANFD_RXFIFO_0_BASE_ID_OFFSET+(BufferNr*XCANFD_MAX_FRAME_SIZE))
/*****************************************************************************/
/**
* This macro Returns Design mode
* 1- Mailbox
* 0- Sequential
*
* @param InstancePtr is a pointer to the XCanFd instance to be worked
* on.
*
* @note none
*
*****************************************************************************/
#define XCANFD_GET_RX_MODE(InstancePtr)\
InstancePtr->CanFdConfig.Rx_Mode
/*****************************************************************************/
/**
*
* This function resets the CAN device. Calling this function resets the device
* immediately, and any pending transmission or reception is terminated at once.
* Both Object Layer and Transfer Layer are reset. This function does not reset
* the Physical Layer. All registers are reset to the default values, and no
* previous status will be restored. TX FIFO, RX FIFO and TX High Priority
* Buffer are also reset.
*
* When a reset is required due to an internal error, the driver notifies the
* upper layer software of this need through the error status code or interrupts
* The upper layer software is responsible for calling this Reset function and
* then re-configuring the device.
*
* The CAN device will be in Configuration Mode immediately after this function
* returns.
*
* @param InstancePtr is a pointer to the XCanFd instance to be worked on.
*
* @return None.
*
* @note None.
*
******************************************************************************/
#define XCanFd_Reset(InstancePtr) \
XCanFd_WriteReg(InstancePtr->CanFdConfig.BaseAddress, XCANFD_SRR_OFFSET,\
XCANFD_SRR_SRST_MASK)
/*****************************************************************************/
/**
*
* This function reads Error Status value from Error Status Register (ESR). Use
* the XCANFD_ESR_* constants defined in xcanfd_l.h to interpret the returned value.
*
*
* @param InstancePtr is a pointer to the XCanFd instance to be worked on.
*
* @return The 32-bit value read from Error Status Register.
*
* @note None.
*
******************************************************************************/
#define XCanFd_GetBusErrorStatus(InstancePtr) \
XCanFd_ReadReg(InstancePtr->CanFdConfig.BaseAddress, XCANFD_ESR_OFFSET)
/*****************************************************************************/
/**
*
* This function returns Status value from Status Register (SR). Use the
* XCANFD_SR_* constants defined in xcanfd_l.h to interpret the returned value.
*
* @param InstancePtr is a pointer to the XCanFd instance to be worked on.
*
* @return The 32-bit value read from Status Register.
*
* @note None.
*
******************************************************************************/
#define XCanFd_GetStatus(InstancePtr) \
XCanFd_ReadReg(InstancePtr->CanFdConfig.BaseAddress, XCANFD_SR_OFFSET)
/*****************************************************************************/
/**
*
* This function clears Error Status bit(s) previously set in Error
* Status Register (ESR). Use the XCANFD_ESR_* constants defined in xcanfd_l.h to
* create the value to pass in. If a bit was cleared in Error Status Register
* before this function is called, it will not be touched.
*
*
* @param InstancePtr is a pointer to the XCanFd instance to be worked on.
*
* @param Mask is he 32-bit mask used to clear bits in Error Status
* Register. Multiple XCANFD_ESR_* values could be 'OR'ed to clear
* multiple bits
*
* @note None.
*
******************************************************************************/
#define XCanFd_ClearBusErrorStatus(InstancePtr,Mask) \
XCanFd_WriteReg(InstancePtr->CanFdConfig.BaseAddress, XCANFD_ESR_OFFSET, \
Mask)
/*****************************************************************************/
/**
*
* This function returns the Tranceive delay comensation Offset.
* This function can call when user sends multiple Buffers using Addto_Queue()
* and XCanFd_Send_Queue().
*
* @param InstancePtr is a pointer to the XCanFd instance to be worked on.
*
* @return None.
*
*
* @note None.
*
******************************************************************************/
#define XCanFd_Get_Tranceiver_Delay_CompensationOffset(InstancePtr) \
((XCanFd_ReadReg(InstancePtr->CanFdConfig.BaseAddress,\
XCANFD_F_BRPR_OFFSET) & XCANFD_F_BRPR_TDCMASK) >> 8)
/*****************************************************************************/
/**
*
* This function Clears Time Stamp Counter Value.
*
* @param InstancePtr is a pointer to the XCanFd instance to be worked on.
*
* @return none
*
*
* @note None.
*
******************************************************************************/
#define XCanFd_ClearTImeStamp_Count(InstancePtr) \
XCanFd_WriteReg(InstancePtr->CanFdConfig.BaseAddress, \
XCANFD_TIMESTAMPR_OFFSET,XCANFD_CTS_MASK)
/*****************************************************************************/
/**
*
* This function returns Time Stamp Counter Value.
*
* @param InstancePtr is a pointer to the XCanFd instance to be worked on.
*
* @return TimeStampCount
*
*
* @note None.
*
******************************************************************************/
#define XCanFd_GetTImeStamp_Count(InstancePtr) \
(XCanFd_ReadReg(InstancePtr->CanFdConfig.BaseAddress,\
XCANFD_TIMESTAMPR_OFFSET) >> 16)
/*****************************************************************************/
/**
*
* This function Disables the Auto retransmissions.
*
* @param InstancePtr is a pointer to the XCanFd instance to be worked on.
*
* @return TimeStampCount
*
*
* @note None.
*
******************************************************************************/
#define XCanFd_DisableAuto_Retransmission(InstancePtr) \
XCanFd_WriteReg(InstancePtr->CanFdConfig.BaseAddress, XCANFD_MSR_OFFSET, \
(XCanFd_ReadReg(InstancePtr->CanFdConfig.BaseAddress, XCANFD_MSR_OFFSET) \
| XCANFD_DAR_MASK));
/****************************************************************************/
/**
*
* This routine returns the Rx water Mark threshold Value.
*
* @param InstancePtr is a pointer to the XCanFd instance.
*
*
* @return Threshold Value.
*
* @note none
*
*****************************************************************************/
#define XCanFd_GetRxIntrWatermark(InstancePtr) \
(XCanFd_ReadReg(InstancePtr->CanFdConfig.BaseAddress, \
XCANFD_WIR_OFFSET) & XCANFD_WIR_MASK)
/****************************************************************************/
/**
*
* This routine returns enabled interrupt(s). Use the XCANFD_IXR_* constants
* defined in xcanfd_l.h to interpret the returned value.
*
* @param InstancePtr is a pointer to the XCanFd instance to be worked on.
*
* @return Enabled interrupt(s) in a 32-bit format.
*
* @note None.
*
*****************************************************************************/
#define XCanFd_InterruptGetEnabled(InstancePtr) \
XCanFd_ReadReg(InstancePtr->CanFdConfig.BaseAddress, XCANFD_IER_OFFSET)
/****************************************************************************/
/**
*
* This routine returns interrupt status read from Interrupt Status Register.
* Use the XCANFD_IXR_* constants defined in xcanfd_l.h to interpret the returned
* value.
*
* @param InstancePtr is a pointer to the XCanFd instance to be worked on.
*
* @return The value stored in Interrupt Status Register.
*
* @note None.
*
*****************************************************************************/
#define XCanFd_InterruptGetStatus(InstancePtr) \
XCanFd_ReadReg(InstancePtr->CanFdConfig.BaseAddress, XCANFD_ISR_OFFSET)
/****************************************************************************/
/**
*
* This routine returns Number of RCS registers to access
* because in Mail box mode user can configure 48,32,16 Rx Buffers.
*
* @param InstancePtr is a pointer to the XCanFd instance to be worked on.
*
* @return The value stored in Interrupt Status Register.
*
* @note None.
*
*****************************************************************************/
#define XCanFd_Get_NofRxBuffers(InstancePtr) \
((InstancePtr->CanFdConfig.NumofRxMbBuf == 48) ? (3) \
:((InstancePtr->CanFdConfig.NumofRxMbBuf == 32) ? \
(2) : (1)))
/****************************************************************************/
/**
*
* This routine returns Number of RxBuffers
* user can Desing RxBuffers as 48,32,16.
*
* @param InstancePtr is a pointer to the XCanFd instance to be worked on.
*
* @return The value stored in Interrupt Status Register.
*
* @note None.
*
*****************************************************************************/
#define XCanFd_Get_RxBuffers(InstancePtr) \
InstancePtr->CanFdConfig.NumofRxMbBuf;
/* Functions in xcan.c */
int XCanFd_CfgInitialize(XCanFd *InstancePtr, XCanFd_Config *ConfigPtr,
u32 EffectiveAddr);
u8 XCanFd_GetMode(XCanFd *InstancePtr);
void XCanFd_EnterMode(XCanFd *InstancePtr, u8 OperationMode);
void XCanFd_GetBusErrorCounter(XCanFd *InstancePtr, u8 *RxErrorCount,
u8 *TxErrorCount);
int XCanFd_Send(XCanFd *InstancePtr,u32 *FramePtr,u32 *TxBufferNumber);
int XCanFd_Recv(XCanFd *InstancePtr, u32 *FramePtr);
int XCanFd_SendHighPriority(XCanFd *InstancePtr, u32 *FramePtr);
void XCanFd_AcceptFilterEnable(XCanFd *InstancePtr, u32 FilterIndexMask);
void XCanFd_AcceptFilterDisable(XCanFd *InstancePtr, u32 FilterIndexMask);
u32 XCanFd_AcceptFilterGetEnabled(XCanFd *InstancePtr);
int XCanFd_AcceptFilterSet(XCanFd *InstancePtr, u32 FilterIndex,
u32 MaskValue, u32 IdValue);
void XCanFd_AcceptFilterGet(XCanFd *InstancePtr, u32 FilterIndex,
u32 *MaskValue, u32 *IdValue);
XCanFd_Config *XCanFd_LookupConfig(u16 DeviceId);
XCanFd_Config *XCanFd_GetConfig(unsigned int InstanceIndex);
int XCanFd_GetNofMessages_Stored(XCanFd *InstancePtr);
int XCanFd_GetDlc2len(u32 Dlc);
u8 XCanFd_GetLen2Dlc(int len);
int XCanFd_GetFreeBuffer(XCanFd *InstancePtr);
int XCanFd_Send_Queue(XCanFd *InstancePtr);
int XCanFd_GetNofMessages_Stored(XCanFd *InstancePtr);
int XCanFd_Addto_Queue(XCanFd *InstancePtr, u32 *FramePtr,u32 *TxBufferNumber);
void XCanFd_PollQueue_Buffer(XCanFd *InstancePtr);
int XCanFd_TxBuffer_Cancel_Request(XCanFd *InstancePtr,u32 BufferNumber);
int XCanFd_Get_Tranceiver_Delay_Compensation(XCanFd *InstancePtr);
/* Configuration functions in xcan_config.c */
int XCanFd_SetBaudRatePrescaler(XCanFd *InstancePtr, u8 Prescaler);
u8 XCanFd_GetBaudRatePrescaler(XCanFd *InstancePtr);
u8 XCanFd_GetFBaudRatePrescaler(XCanFd *InstancePtr);
int XCanFd_SetBitTiming(XCanFd *InstancePtr, u8 SyncJumpWidth,
u8 TimeSegment2, u8 TimeSegment1);
void XCanFd_GetBitTiming(XCanFd *InstancePtr, u8 *SyncJumpWidth,
u8 *TimeSegment2, u8 *TimeSegment1);
void XCanFd_GetFBitTiming(XCanFd *InstancePtr, u8 *SyncJumpWidth,
u8 *TimeSegment2, u8 *TimeSegment1);
int XCanFd_SetFBaudRatePrescaler(XCanFd *InstancePtr, u8 Prescaler);
int XCanFd_SetFBitTiming(XCanFd *InstancePtr, u8 SyncJumpWidth,
u8 TimeSegment2, u8 TimeSegment1);
void XCanFd_SetBitRateSwitch_DisableNominal(XCanFd *InstancePtr);
void XCanFd_SetBitRateSwitch_EnableNominal(XCanFd *InstancePtr);
/* Diagnostic functions in xcan_selftest.c */
int XCanFd_SelfTest(XCanFd *InstancePtr);
/* Functions in xcan_intr.c */
void XCanFd_InterruptEnable(XCanFd *InstancePtr, u32 Mask);
void XCanFd_InterruptDisable(XCanFd *InstancePtr, u32 Mask);
void XCanFd_InterruptClear(XCanFd *InstancePtr, u32 Mask);
void XCanFd_IntrHandler(void *InstancePtr);
int XCanFd_SetHandler(XCanFd *InstancePtr, u32 HandlerType,
void *CallBackFunc, void *CallBackRef);
void XCanFd_InterruptEnable_ReadyRqt(XCanFd *InstancePtr, u32 Mask);
void XCanFd_InterruptEnable_CancelRqt(XCanFd *InstancePtr, u32 Mask);
void XCanFd_InterruptDisable_ReadyRqt(XCanFd *InstancePtr, u32 Mask);
void XCanFd_InterruptDisable_CancelRqt(XCanFd *InstancePtr, u32 Mask);
void XCanFd_InterruptEnable_RxBuffFull(XCanFd *InstancePtr, u32 Mask,
u32 RxBuffNumber);
void XCanFd_InterruptDisable_RxBuffFull(XCanFd *InstancePtr, u32 Mask,
u32 RxBuffNumber);
u32 XCanFd_SetRxIntrWatermark(XCanFd *InstancePtr, u8 Threshold);
void XCanFd_PollTxBuffer(XCanFd *InstancePtr,u32 TxBuffer);
u32 XCanFd_RxBuff_MailBox_Active(XCanFd *InstancePtr, u32 RxBuffer);
u32 XCanFd_RxBuff_MailBox_DeActive(XCanFd *InstancePtr, u32 RxBuffer);
u32 XCanFd_Set_MailBox_IdMask(XCanFd *InstancePtr, u32 RxBuffer,
u32 MaskValue, u32 IdValue);
u32 XCanFd_Recv_Sequential(XCanFd *InstancePtr, u32 *FramePtr);
u32 XCanFd_Recv_Mailbox(XCanFd *InstancePtr, u32 *FramePtr);
/* Functions in xcanfd_sinit.c */
XCanFd_Config *XCanFd_LookupConfig(u16 Deviceid);
#ifdef __cplusplus
}
#endif
#endif /* end of protection macro */

View file

@ -0,0 +1,470 @@
/******************************************************************************
*
* Copyright (C) 2015 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 xcanfd_config.c
*
* Functions in this file are CAN Configuration Register access related.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -------------------------------------------------------
* 1.00a nsk 06/04/15 First release
*
* </pre>
******************************************************************************/
/***************************** Include Files *********************************/
#include "xil_types.h"
#include "xil_assert.h"
#include "xcanfd.h"
/************************** Constant Definitions *****************************/
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Function Prototypes ******************************/
/*****************************************************************************/
/**
*
* This routine sets Baud Rate Prescaler value in Arbitration Phse.
* The system clock for the CAN controller is divided by (Prescaler + 1)
* to generate the quantum clock needed for sampling and synchronization.
* Read the device specification for details.
*
* Baud Rate Prescaler could be set only after CAN device entered Configuration
* Mode. So please call XCanFd_EnterMode() to enter Configuration Mode before
* using this function.
*
* @param InstancePtr is a pointer to the XCanFd instance to be worked on.
* @param Prescaler is the value to set. Valid values are from 0 to 255.
*
* @return - XST_SUCCESS if the Baud Rate Prescaler value is set
* successfully.
* - XST_FAILURE if CAN device is not in Configuration Mode.
*
* @note None.
*
******************************************************************************/
int XCanFd_SetBaudRatePrescaler(XCanFd *InstancePtr, u8 Prescaler)
{
Xil_AssertNonvoid(InstancePtr != NULL);
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
/*
* Return error code if the device currently is NOT in Configuration
* Mode
*/
if (XCanFd_GetMode(InstancePtr) != XCANFD_MODE_CONFIG) {
return XST_FAILURE;
}
XCanFd_WriteReg(InstancePtr->CanFdConfig.BaseAddress, XCANFD_BRPR_OFFSET,
(u32) Prescaler);
return XST_SUCCESS;
}
/*****************************************************************************/
/**
*
* This routine gets Baud Rate Prescaler value. The system clock for the CAN
* controller is divided by (Prescaler + 1) to generate the quantum clock
* needed for sampling and synchronization. Read the device specification for
* details.
*
* @param InstancePtr is a pointer to the XCanFd instance to be worked on.
*
* @return Current used Baud Rate Prescaler value. The value's range is
* from 0 to 255.
*
* @note None.
*
******************************************************************************/
u8 XCanFd_GetBaudRatePrescaler(XCanFd *InstancePtr)
{
u8 Result;
Xil_AssertNonvoid(InstancePtr != NULL);
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
Result = (u8) XCanFd_ReadReg(InstancePtr->CanFdConfig.BaseAddress,
XCANFD_BRPR_OFFSET);
return Result;
}
/*****************************************************************************/
/**
*
* This routine sets Bit time. Time segment 1, Time segment 2 and
* Synchronization Jump Width are set in this function. Device specification
* requires the values passed into this function be one less than the actual
* values of these fields. Read the device specification for details.
*
* Bit time could be set only after CAN device entered Configuration Mode.
* Please call XCanFd_EnterMode() to enter Configuration Mode before using this
* function.
*
* @param InstancePtr is a pointer to the XCanFd instance to be worked on.
* @param SyncJumpWidth is the Synchronization Jump Width value to set.
* Valid values are from 0 to 3.
* @param TimeSegment2 is the Time Segment 2 value to set. Valid values
* are from 0 to 7.
* @param TimeSegment1 is the Time Segment 1 value to set. Valid values
* are from 0 to 15.
*
* @return - XST_SUCCESS if the Bit time is set successfully.
* - XST_FAILURE if CAN device is not in Configuration Mode.
* - XST_INVALID_PARAM if any value of SyncJumpWidth, TimeSegment2
* and TimeSegment1 is invalid.
*
* @note None.
*
******************************************************************************/
int XCanFd_SetBitTiming(XCanFd *InstancePtr, u8 SyncJumpWidth,
u8 TimeSegment2, u8 TimeSegment1)
{
u32 Value;
Xil_AssertNonvoid(InstancePtr != NULL);
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
if (SyncJumpWidth > 16 || TimeSegment2 > 32 || TimeSegment1 > 64) {
return XST_INVALID_PARAM;
}
/* Return error code if the device is NOT in Configuration Mode */
if (XCanFd_GetMode(InstancePtr) != XCANFD_MODE_CONFIG) {
return XST_FAILURE;
}
Value = ((u32) TimeSegment1) & XCANFD_BTR_TS1_MASK;
Value |= (((u32) TimeSegment2) << XCANFD_BTR_TS2_SHIFT) &
XCANFD_BTR_TS2_MASK;
Value |= (((u32) SyncJumpWidth) << XCANFD_BTR_SJW_SHIFT) &
XCANFD_BTR_SJW_MASK;
XCanFd_WriteReg(InstancePtr->CanFdConfig.BaseAddress,
XCANFD_BTR_OFFSET, Value);
Value = XCanFd_ReadReg(InstancePtr->CanFdConfig.BaseAddress,
XCANFD_BTR_OFFSET);
return XST_SUCCESS;
}
/*****************************************************************************/
/**
*
* This routine gets Bit time. Time segment 1, Time segment 2 and
* Synchronization Jump Width values are read in this function. According to
* device specification, the actual value of each of these fields is one
* more than the value read. Read the device specification for details.
*
* @param InstancePtr is a pointer to the XCanFd instance to be worked on.
* @param SyncJumpWidth will store the Synchronization Jump Width value
* after this function returns. Its value ranges from 0 to 3.
* @param TimeSegment2 will store the Time Segment 2 value after this
* function returns. Its value ranges from 0 to 7.
* @param TimeSegment1 will store the Time Segment 1 value after this
* function returns. Its value ranges from 0 to 15.
*
* @return None.
*
* @note None.
*
******************************************************************************/
void XCanFd_GetBitTiming(XCanFd *InstancePtr, u8 *SyncJumpWidth,
u8 *TimeSegment2, u8 *TimeSegment1)
{
u32 Value;
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
Value = XCanFd_ReadReg(InstancePtr->CanFdConfig.BaseAddress,
XCANFD_BTR_OFFSET);
*TimeSegment1 = (u8) (Value & XCANFD_BTR_TS1_MASK);
*TimeSegment2 =
(u8) ((Value & XCANFD_BTR_TS2_MASK) >> XCANFD_BTR_TS2_SHIFT);
*SyncJumpWidth =
(u8) ((Value & XCANFD_BTR_SJW_MASK) >> XCANFD_BTR_SJW_SHIFT);
}
/*****************************************************************************/
/**
*
* This routine sets Baud Rate Prescaler value in Data Phase.
* The system clock for the CAN controller is divided by (Prescaler + 1)
* to generate the quantum clock needed for sampling and synchronization.
* Read the device specification for details.
*
* Baud Rate Prescaler could be set only after CAN device entered Configuration
* Mode. So please call XCanFd_EnterMode() to enter Configuration Mode before
* using this function.
*
* @param InstancePtr is a pointer to the XCanFd instance to be worked on.
* @param Prescaler is the value to set. Valid values are from 1 to 256.
*
* @return - XST_SUCCESS if the Baud Rate Prescaler value is set
* successfully.
* - XST_FAILURE if CAN device is not in Configuration Mode.
*
* @note None.
*
******************************************************************************/
int XCanFd_SetFBaudRatePrescaler(XCanFd *InstancePtr, u8 Prescaler)
{
u32 RegValue;
Xil_AssertNonvoid(InstancePtr != NULL);
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
/*
* Return error code if the device currently is NOT in Configuration
* Mode
*/
if (XCanFd_GetMode(InstancePtr) != XCANFD_MODE_CONFIG) {
return XST_FAILURE;
}
RegValue = XCanFd_ReadReg(InstancePtr->CanFdConfig.BaseAddress,
XCANFD_F_BRPR_OFFSET);
RegValue |= ((u32) Prescaler & XCANFD_BRPR_BRP_MASK);
XCanFd_WriteReg(InstancePtr->CanFdConfig.BaseAddress,
XCANFD_F_BRPR_OFFSET,RegValue);
return XST_SUCCESS;
}
/*****************************************************************************/
/**
*
* This routine gets Baud Rate Prescaler value in Data Phase. The system clock
* for the CAN controller is divided by (Prescaler + 1) to generate the quantum
* clock needed for sampling and synchronization. Read the device specification
* for details.
*
* @param InstancePtr is a pointer to the XCanFd instance to be worked on.
*
* @return Current used Baud Rate Prescaler value. The value's range is
* from 1 to 256.
*
* @note None.
*
******************************************************************************/
u8 XCanFd_GetFBaudRatePrescaler(XCanFd *InstancePtr)
{
u32 Result;
Xil_AssertNonvoid(InstancePtr != NULL);
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
Result = (u8) XCanFd_ReadReg(InstancePtr->CanFdConfig.BaseAddress,
XCANFD_F_BRPR_OFFSET);
return (Result&XCANFD_BRPR_BRP_MASK);
}
/*****************************************************************************/
/**
*
* This routine sets Bit time in Data Phase. Time segment 1, Time segment 2 and
* Synchronization Jump Width are set in this function. Device specification
* requires the values passed into this function be one less than the actual
* values of these fields. Read the device specification for details.
*
* Bit time could be set only after CAN device entered Configuration Mode.
* Please call XCanFd_EnterMode() to enter Configuration Mode before using this
* function.
*
* @param InstancePtr is a pointer to the XCanFd instance to be worked on.
* @param SyncJumpWidth is the Synchronization Jump Width value to set.
* Valid values are from 0 to 3.
* @param TimeSegment2 is the Time Segment 2 value to set. Valid values
* are from 0 to 7.
* @param TimeSegment1 is the Time Segment 1 value to set. Valid values
* are from 0 to 15.
*
* @return - XST_SUCCESS if the Bit time is set successfully.
* - XST_FAILURE if CAN device is not in Configuration Mode.
* - XST_INVALID_PARAM if any value of SyncJumpWidth, TimeSegment2
* and TimeSegment1 is invalid.
*
* @note None.
*
******************************************************************************/
int XCanFd_SetFBitTiming(XCanFd *InstancePtr, u8 SyncJumpWidth,
u8 TimeSegment2, u8 TimeSegment1)
{
u32 Value;
Xil_AssertNonvoid(InstancePtr != NULL);
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
if (SyncJumpWidth > 3 || TimeSegment2 > 7 || TimeSegment1 > 15) {
return XST_INVALID_PARAM;
}
/* Return error code if the device is NOT in Configuration Mode */
if (XCanFd_GetMode(InstancePtr) != XCANFD_MODE_CONFIG) {
return XST_FAILURE;
}
Value = ((u32) TimeSegment1) & XCANFD_F_BTR_TS1_MASK;
Value |= (((u32) TimeSegment2) << XCANFD_F_BTR_TS2_SHIFT) &
XCANFD_F_BTR_TS2_MASK;
Value |= (((u32) SyncJumpWidth) << XCANFD_F_BTR_SJW_SHIFT) &
XCANFD_F_BTR_SJW_MASK;
XCanFd_WriteReg(InstancePtr->CanFdConfig.BaseAddress,
XCANFD_F_BTR_OFFSET,Value);
return XST_SUCCESS;
}
/*****************************************************************************/
/**
*
* This routine gets Bit time in Data Phase. Time segment 1, Time segment 2 and
* Synchronization Jump Width values are read in this function. According to
* device specification, the actual value of each of these fields is one
* more than the value read. Read the device specification for details.
*
* @param InstancePtr is a pointer to the XCanFd instance to be worked on.
* @param SyncJumpWidth will store the Synchronization Jump Width value
* after this function returns. Its value ranges from 0 to 3.
* @param TimeSegment2 will store the Time Segment 2 value after this
* function returns. Its value ranges from 0 to 7.
* @param TimeSegment1 will store the Time Segment 1 value after this
* function returns. Its value ranges from 0 to 15.
*
* @return None.
*
* @note None.
*
******************************************************************************/
void XCanFd_GetFBitTiming(XCanFd *InstancePtr, u8 *SyncJumpWidth,
u8 *TimeSegment2, u8 *TimeSegment1)
{
u32 Value;
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
Value = XCanFd_ReadReg(InstancePtr->CanFdConfig.BaseAddress,
XCANFD_F_BTR_OFFSET);
*TimeSegment1 = (u8) (Value & XCANFD_F_BTR_TS1_MASK);
*TimeSegment2 =
(u8) ((Value & XCANFD_F_BTR_TS2_MASK) >>
XCANFD_F_BTR_TS2_SHIFT);
*SyncJumpWidth =
(u8) ((Value & XCANFD_F_BTR_SJW_MASK) >>
XCANFD_F_BTR_SJW_SHIFT);
}
/*****************************************************************************/
/**
*
* This routine sets the Bit Rate Switch with nominal bit rate.
* if we set BRSD bit in Mode Select Register then CAN Controller transmits
* CAN FD Frames with Nominal Bit Rate.
* Read the device specification for details.
*
* @param InstancePtr is a pointer to the XCanFd instance to be worked on.
*
* @return None.
*
* @note None.
*
* ****************************************************************************/
void XCanFd_SetBitRateSwitch_EnableNominal(XCanFd *InstancePtr)
{
u32 Result;
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
Result = XCanFd_ReadReg(InstancePtr->CanFdConfig.BaseAddress,
XCANFD_MSR_OFFSET);
if (!(Result & XCANFD_SRR_CEN_MASK)) {
Result = Result | XCANFD_MSR_BRSD_MASK;
XCanFd_WriteReg(InstancePtr->CanFdConfig.BaseAddress,
XCANFD_MSR_OFFSET,Result);
}
Result = XCanFd_ReadReg(InstancePtr->CanFdConfig.BaseAddress,
XCANFD_MSR_OFFSET);
}
/*****************************************************************************/
/**
*
* This routine Disables the BRSD bit, so that Bit Rate Switch can be happen
* with Nominal or configured rate.
* Read the device specification for details.
*
* @param InstancePtr is a pointer to the XCanFd instance to be worked on.
*
* @return None.
*
* @note if we set BRSD bit in Mode Select Register then CAN Controller
* transmits CAN FD Frames with Nominal Bit Rate. else with
* configured bit rate(As specified in Data phase BRPR and BTR
* Registers.
*
******************************************************************************/
void XCanFd_SetBitRateSwitch_DisableNominal(XCanFd *InstancePtr)
{
u32 Result;
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
Result = XCanFd_ReadReg(InstancePtr->CanFdConfig.BaseAddress,
XCANFD_MSR_OFFSET);
if (!(Result & XCANFD_SRR_CEN_MASK)) {
Result = Result & (~XCANFD_MSR_BRSD_MASK);
XCanFd_WriteReg(InstancePtr->CanFdConfig.BaseAddress,
XCANFD_MSR_OFFSET,Result);
}
Result = XCanFd_ReadReg(InstancePtr->CanFdConfig.BaseAddress,
XCANFD_MSR_OFFSET);
}

View file

@ -0,0 +1,55 @@
/*******************************************************************
*
* CAUTION: This file is automatically generated by HSM.
* Version:
* DO NOT EDIT.
*
* Copyright (C) 2010-2015 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.
*
*
* Description: Driver configuration
*
*******************************************************************/
#include "xparameters.h"
#include "xcanfd.h"
/*
* The configuration table for devices
*/
XCanFd_Config XCanFd_ConfigTable[] =
{
{
XPAR_CAN_0_DEVICE_ID,
XPAR_CAN_0_BASEADDR,
XPAR_CAN_0_RX_MODE,
XPAR_CAN_0_NUM_OF_RX_MB_BUF
}
};

View file

@ -0,0 +1,600 @@
/******************************************************************************
*
* Copyright (C) 2015 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 xcanfd_intr.c
*
* This file contains functions related to CAN interrupt handling.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- --------- -----------------------------------------------
* 1.00a nsk 06/04/15 First release
* </pre>
*
******************************************************************************/
/***************************** Include Files *********************************/
#include "xcanfd.h"
/************************** Constant Definitions *****************************/
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Variable Definitions *****************************/
/************************** Function Prototypes ******************************/
/****************************************************************************/
/**
*
* This routine enables interrupt(s). Use the XCANFD_IXR_* constants defined in
* xcanfd_l.h to create the bit-mask to enable interrupts.
*
*
* @param InstancePtr is a pointer to the XCanFd instance to be worked on.
* @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 XCANFD_IXR_* bits defined in xcanfd_l.h.
*
* @return None.
*
* @note None.
*
*****************************************************************************/
void XCanFd_InterruptEnable(XCanFd *InstancePtr, u32 Mask)
{
u32 IntrValue;
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
IntrValue = XCanFd_InterruptGetEnabled(InstancePtr);
IntrValue |= Mask & XCANFD_IXR_ALL;
XCanFd_WriteReg(InstancePtr->CanFdConfig.BaseAddress, XCANFD_IER_OFFSET,
IntrValue);
}
/****************************************************************************/
/**
*
* This routine sets the Rx Full threshold in the Watermark Interrupt Register.
*
* @param InstancePtr is a pointer to the XCanFd instance.
* @param Threshold is the threshold to be set. The valid values are
* from 1 to 63.
*
* @return - XST_FAILURE - If the CAN device is not in Configuration Mode.
* - XST_SUCCESS - If the Rx Full threshold is set in Watermark
* Interrupt Register.
*
* @note The threshold can only be set when the CAN device is in the
* configuration mode.
*
*****************************************************************************/
u32 XCanFd_SetRxIntrWatermark(XCanFd *InstancePtr, u8 Threshold)
{
u32 ThrReg;
s32 Status;
Xil_AssertNonvoid(InstancePtr != NULL);
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
Xil_AssertNonvoid((Threshold > 0) || (Threshold <= (u8)31));
if (XCanFd_GetMode(InstancePtr) != (u8)XCANFD_MODE_CONFIG) {
Status = XST_FAILURE;
}
else {
ThrReg = XCanFd_ReadReg(InstancePtr->CanFdConfig.BaseAddress,
XCANFD_WIR_OFFSET);
Threshold &= XCANFD_WIR_MASK;
XCanFd_WriteReg(InstancePtr->CanFdConfig.BaseAddress,
XCANFD_WIR_OFFSET,Threshold);
Status = XST_SUCCESS;
}
return Status;
}
/****************************************************************************/
/**
*
* This routine enables TxBuffer Ready Request interrupt(s).
*
* @param InstancePtr is a pointer to the XCanFd instance to be worked on.
* @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 XCANFD_IETRS_OFFSET* bits defined in xcanfd_l.h.
*
* @return None.
*
* @note None.
*
*****************************************************************************/
void XCanFd_InterruptEnable_ReadyRqt(XCanFd *InstancePtr, u32 Mask)
{
u32 IntrValue;
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
IntrValue = XCanFd_ReadReg(InstancePtr->CanFdConfig.BaseAddress, \
XCANFD_IETRS_OFFSET);
IntrValue |= Mask;
XCanFd_WriteReg(InstancePtr->CanFdConfig.BaseAddress, \
XCANFD_IETRS_OFFSET, IntrValue);
}
/****************************************************************************/
/**
*
* This routine enables TxBuffer Cancellation interrupt(s).
*
*
* @param InstancePtr is a pointer to the XCanFd instance to be worked on.
* @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 XCANFD_IETCS_OFFSET* bits defined in xcanfd_l.h.
*
* @return None.
*
* @note None.
*
*****************************************************************************/
void XCanFd_InterruptEnable_CancelRqt(XCanFd *InstancePtr, u32 Mask)
{
u32 IntrValue;
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
IntrValue = XCanFd_ReadReg(InstancePtr->CanFdConfig.BaseAddress, \
XCANFD_IETCS_OFFSET);
IntrValue |= Mask;
XCanFd_WriteReg(InstancePtr->CanFdConfig.BaseAddress, \
XCANFD_IETCS_OFFSET, IntrValue);
}
/****************************************************************************/
/**
*
* This routine disables TxBuffer Ready Request interrupt(s).
*
* @param InstancePtr is a pointer to the XCanFd instance to be worked on.
* @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 AND'ing XCANFD_IETRS_OFFSET* bits
* defined in xcanfd_l.h.
*
* @return None.
*
* @note None.
*
*****************************************************************************/
void XCanFd_InterruptDisable_ReadyRqt(XCanFd *InstancePtr, u32 Mask)
{
u32 IntrValue;
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
IntrValue = XCanFd_ReadReg(InstancePtr->CanFdConfig.BaseAddress, \
XCANFD_IETRS_OFFSET);
IntrValue &= ~Mask;
XCanFd_WriteReg(InstancePtr->CanFdConfig.BaseAddress, \
XCANFD_IETRS_OFFSET, IntrValue);
}
/****************************************************************************/
/**
*
* This routine disables the TxBuffer Cancel Request interrupt(s).
*
* @param InstancePtr is a pointer to the XCanFd instance to be worked on.
* @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 AND'ing XCANFD_IETCS_OFFSET* bits defined in
* xcanfd_l.h.
*
* @return None.
*
* @note None.
*
*****************************************************************************/
void XCanFd_InterruptDisable_CancelRqt(XCanFd *InstancePtr, u32 Mask)
{
u32 IntrValue;
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
IntrValue = XCanFd_ReadReg(InstancePtr->CanFdConfig.BaseAddress, \
XCANFD_IETCS_OFFSET);
IntrValue &= ~Mask;
XCanFd_WriteReg(InstancePtr->CanFdConfig.BaseAddress, \
XCANFD_IETCS_OFFSET, IntrValue);
}
/****************************************************************************/
/**
*
* This routine Enables the RxBuffer Full interrupt(s) in MailBox Mode.
*
* @param InstancePtr is a pointer to the XCanFd instance to be worked on.
* @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 AND'ing XCANFD_RXBFLL*_OFFSET bits defined
* in xcanfd_l.h.
* @param RxBuffNumber has two values
* if 0 -> Access RxBufferFull0 Reg
* else -> Access RxBufferFull1 Reg
*
* @return None.
*
* @note None.
*
****************************************************************************/
void XCanFd_InterruptEnable_RxBuffFull(XCanFd *InstancePtr,
u32 Mask,u32 RxBuffNumber)
{
u32 IntrValue;
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
if ((RxBuffNumber == 0)) {
IntrValue = XCanFd_ReadReg(
InstancePtr->CanFdConfig.BaseAddress,
XCANFD_RXBFLL1_OFFSET);
IntrValue |= Mask;
XCanFd_WriteReg(InstancePtr->CanFdConfig.BaseAddress,
XCANFD_RXBFLL1_OFFSET, IntrValue);
}
else {
IntrValue = XCanFd_ReadReg(
InstancePtr->CanFdConfig.BaseAddress,
XCANFD_RXBFLL2_OFFSET);
IntrValue |= Mask;
XCanFd_WriteReg(InstancePtr->CanFdConfig.BaseAddress,
XCANFD_RXBFLL2_OFFSET, IntrValue);
}
}
/****************************************************************************/
/**
*
* This routine disables the RxBuffer Full interrupt(s) in MailBox Mode.
*
* @param InstancePtr is a pointer to the XCanFd instance to be worked on.
* @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 AND'ing XCANFD_RXBFLL*_OFFSET bits
* defined in xcanfd_l.h.
*
*@param RxBuffNumber has two values
* if 0 -> Access RxBufferFull0 Reg.
* else -> Access RxBufferFull1 Reg.
*
* @return None.
*
* @note None.
*
*****************************************************************************/
void XCanFd_InterruptDisable_RxBuffFull(XCanFd *InstancePtr,
u32 Mask,u32 RxBuffNumber)
{
u32 IntrValue;
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
if ((RxBuffNumber == 0)) {
IntrValue =
XCanFd_ReadReg(InstancePtr->CanFdConfig.BaseAddress,
XCANFD_RXBFLL1_OFFSET);
IntrValue &= ~Mask;
XCanFd_WriteReg(InstancePtr->CanFdConfig.BaseAddress,
XCANFD_RXBFLL1_OFFSET, IntrValue);
}
else {
IntrValue =
XCanFd_ReadReg(InstancePtr->CanFdConfig.BaseAddress,
XCANFD_RXBFLL2_OFFSET);
IntrValue &= ~Mask;
XCanFd_WriteReg(InstancePtr->CanFdConfig.BaseAddress,
XCANFD_RXBFLL2_OFFSET, IntrValue);
}
}
/****************************************************************************/
/**
*
* This routine disables interrupt(s). Use the XCANFD_IXR_* constants defined in
* xcanfd_l.h to create the bit-mask to disable interrupt(s).
*
* @param InstancePtr is a pointer to the XCanFd instance to be worked on.
* @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 XCANFD_IXR_* bits defined in
* xcanfd_l.h.
*
* @return None.
*
* @note None.
*
*****************************************************************************/
void XCanFd_InterruptDisable(XCanFd *InstancePtr, u32 Mask)
{
u32 IntrValue;
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
IntrValue = XCanFd_InterruptGetEnabled(InstancePtr);
IntrValue &= ~Mask;
XCanFd_WriteReg(InstancePtr->CanFdConfig.BaseAddress,
XCANFD_IER_OFFSET, IntrValue);
}
/****************************************************************************/
/**
*
* 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 XCanFd instance to be worked on.
* @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 XCANFD_IXR_* bits defined
* in xcanfd_l.h.
*
* @note None.
*
*****************************************************************************/
void XCanFd_InterruptClear(XCanFd *InstancePtr, u32 Mask)
{
u32 IntrValue;
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
IntrValue = XCanFd_InterruptGetStatus(InstancePtr);
IntrValue &= Mask;
XCanFd_WriteReg(InstancePtr->CanFdConfig.BaseAddress,
XCANFD_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 XCanFd_SetHandler() during
* initialization phase. An example delivered with this driver demonstrates how
* this could be done.
*
* @param InstancePtr is a pointer to the XCanFd instance that just
* interrupted.
*
* @return None.
*
* @note None.
*
******************************************************************************/
void XCanFd_IntrHandler(void *InstancePtr)
{
u32 PendingIntr, EventIntr, ErrorStatus;
XCanFd *CanPtr = (XCanFd *) InstancePtr;
Xil_AssertVoid(CanPtr != NULL);
Xil_AssertVoid(CanPtr->IsReady == XIL_COMPONENT_IS_READY);
/* Get pending interrupts */
PendingIntr = XCanFd_InterruptGetStatus(CanPtr);
PendingIntr &= XCanFd_InterruptGetEnabled(CanPtr);
/* An error interrupt is occurring */
if ((PendingIntr & XCANFD_IXR_ERROR_MASK)) {
ErrorStatus = XCanFd_GetBusErrorStatus(CanPtr);
CanPtr->ErrorHandler(CanPtr->ErrorRef, ErrorStatus);
/* Clear Error Status Register */
XCanFd_ClearBusErrorStatus(CanPtr, ErrorStatus);
}
/*
* Check if any following event interrupt is pending:
* - RX FIFO Overflow
* - RX FIFO Underflow
* - Rx Match Not Finished
* - Rx Buffer Overflow for Buffer Index(Mail Box)
* - Transmit Cancelation Request served
* - Transmit Ready Request Served
* - Wake up from sleep mode
* - Rx Buffer Full(Mail Box)
* - TX FIFO Full
* - Enter sleep mode
* - Enter Bus off status
* - Arbitration is lost
*
* If so, call event callback provided by upper level.
*/
EventIntr = PendingIntr & (XCANFD_IXR_RXBOFLW_BI_MASK |
XCANFD_IXR_RXMNF_MASK |
XCANFD_IXR_RXBOFLW_MASK |
XCANFD_IXR_TXCRS_MASK | XCANFD_IXR_TXRRS_MASK |
XCANFD_IXR_WKUP_MASK |
XCANFD_IXR_SLP_MASK | XCANFD_IXR_BSOFF_MASK |
XCANFD_IXR_RXFOFLW_MASK | XCANFD_IXR_ARBLST_MASK |
XCANFD_IXR_RXRBF_MASK);
if (EventIntr) {
CanPtr->EventHandler(CanPtr->EventRef, EventIntr);
if ((EventIntr & XCANFD_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;
}
}
/*
* A frame was received and is sitting in RX FIFO.
*
* XCANFD_IXR_RXOK_MASK is used because the bit is set when a frame
* is sit in the buffer
*
* XCANFD_IXR_RXFWMFLL_MASK is used because the bit can be set
* when configured level of frames are set
*
* XCANFD_IXR_RXRBF_MASK is used because the bit is set in MAIL BOX Mode
* when a message is received and becomes FULL.
*/
if ((PendingIntr & (XCANFD_IXR_RXFWMFLL_MASK | XCANFD_IXR_RXOK_MASK \
| XCANFD_IXR_RXRBF_MASK ))) {
CanPtr->RecvHandler(CanPtr->RecvRef);
}
/* A frame was transmitted successfully */
if ((PendingIntr & XCANFD_IXR_TXOK_MASK)) {
CanPtr->SendHandler(CanPtr->SendRef);
}
/* Clear all pending interrupts */
XCanFd_InterruptClear(CanPtr, PendingIntr);
}
/*****************************************************************************/
/**
*
* This routine installs an asynchronous callback function for the given
* HandlerType:
*
* <pre>
* HandlerType Callback Function Type
* ----------------------- ---------------------------
* XCANFD_HANDLER_SEND XCanFd_SendRecvHandler
* XCANFD_HANDLER_RECV XCanFd_SendRecvHandler
* XCANFD_HANDLER_ERROR XCanFd_ErrorHandler
* XCANFD_HANDLER_EVENT XCanFd_EventHandler
*
* HandlerType Invoked by this driver when:
* ----------------------- --------------------------------------------------
* XCANFD_HANDLER_SEND A frame transmitted by a call to
* XCanFd_Send() has been sent successfully.
*
* XCANFD_HANDLER_RECV A frame has been received and is sitting in
* the RX FIFO.
*
* XCANFD_HANDLER_ERROR An error interrupt is occurring.
*
* XCANFD_HANDLER_EVENT Any other kind of interrupt is occurring.
* </pre>
*
* @param InstancePtr is a pointer to the XCanFd instance to be worked on.
* @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 XCanFd_SetHandler(XCanFd *InstancePtr, u32 HandlerType,
void *CallBackFunc, void *CallBackRef)
{
Xil_AssertNonvoid(InstancePtr != NULL);
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
switch (HandlerType) {
case XCANFD_HANDLER_SEND:
InstancePtr->SendHandler = (XCanFd_SendRecvHandler) CallBackFunc;
InstancePtr->SendRef = CallBackRef;
break;
case XCANFD_HANDLER_RECV:
InstancePtr->RecvHandler = (XCanFd_SendRecvHandler) CallBackFunc;
InstancePtr->RecvRef = CallBackRef;
break;
case XCANFD_HANDLER_ERROR:
InstancePtr->ErrorHandler = (XCanFd_ErrorHandler) CallBackFunc;
InstancePtr->ErrorRef = CallBackRef;
break;
case XCANFD_HANDLER_EVENT:
InstancePtr->EventHandler = (XCanFd_EventHandler) CallBackFunc;
InstancePtr->EventRef = CallBackRef;
break;
default:
return (XST_INVALID_PARAM);
}
return (XST_SUCCESS);
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,225 @@
/******************************************************************************
*
* Copyright (C) 2015 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 xcanfd_selftest.c
*
* This file contains a diagnostic self-test function for the XCanFd driver.
*
* Please see xcanfd.h for more information.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- ------------------------------------------------------
* 1.00a nsk 06/04/15 First release
*
* </pre>
*
*****************************************************************************/
/***************************** Include Files ********************************/
#include "xstatus.h"
#include "xcanfd.h"
/************************** Constant Definitions ****************************/
#define XCANFD_MAX_FRAME_SIZE_IN_BYTES 72
/**************************** Type Definitions ******************************/
/***************** Macros (Inline Functions) Definitions ********************/
/************************** Variable Definitions ****************************/
/* Buffers to hold frames to send and receive. */
static u32 TxFrame[XCANFD_MAX_FRAME_SIZE_IN_BYTES];
static u32 RxFrame[XCANFD_MAX_FRAME_SIZE_IN_BYTES];
/************************** Function Prototypes *****************************/
/* Message Id Constant. */
#define TEST_MESSAGE_ID 2650
/* CAN Dlc Value */
#define TEST_CANFD_DLC 8
/* CAN FD FilterIndex Value */
#define TEST_FILTER_INDEX 1
#define TEST_MAIL_BOX_MASK 0xFFFFFFFF
/*****************************************************************************/
/**
*
* 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 to the device specification for the device status
* after the reset operation.
*
*
* @param InstancePtr is a pointer to the XCanFd instance to be worked on.
*
* @return - XST_SUCCESS if the self-test passed. i.e., the frame
* received via the internal loop back has the same contents as the
* sent frame.
* - 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 XCanFd_SelfTest(XCanFd *InstancePtr)
{
u8 *FramePtr;
u32 Result;
u32 Index;
u32 RxErrorCount;
u32 TxErrorCount;
u32 TxBuffer;
u32 Dlc;
u32 TransmittedDlc;
u32 ReceivedDlc;
u32 Status;
u32 IdValue;
u32 BuffNr;
Xil_AssertNonvoid(InstancePtr != NULL);
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
XCanFd_Reset(InstancePtr);
/*
* The device should enter Configuration Mode immediately after the
* reset above is finished. Now check the mode and return error code if
* it is not Configuration Mode.
*/
if (XCanFd_GetMode(InstancePtr) != XCANFD_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.
*/
XCanFd_SetBaudRatePrescaler(InstancePtr, 29);
XCanFd_SetBitTiming(InstancePtr, 3,2,15);
XCanFd_SetFBaudRatePrescaler(InstancePtr, 29);
XCanFd_SetFBitTiming(InstancePtr,3,2,15);
XCanFd_EnterMode(InstancePtr, XCANFD_MODE_LOOPBACK);
while (XCanFd_GetMode(InstancePtr) != XCANFD_MODE_LOOPBACK);
/*
* Create a frame to send with known values so we can verify them
* on receive.
*/
TxFrame[0] = XCanFd_CreateIdValue(TEST_MESSAGE_ID, 0, 0, 0, 0);
TxFrame[1] = XCanFd_Create_CanFD_Dlc_BrsValue(TEST_CANFD_DLC);
Dlc = XCanFd_GetDlc2len(TxFrame[1] & XCANFD_DLCR_DLC_MASK);
FramePtr = (u8 *) (&TxFrame[2]);
for (Index = 0; Index < Dlc; Index++) {
*FramePtr++ = (u8) Index;
}
/*Check the design, if it is in MailBox Mode */
if (XCANFD_GET_RX_MODE(InstancePtr) == 1) {
IdValue = XCanFd_CreateIdValue(TEST_MESSAGE_ID, 0, 0, 0, 0);
for (BuffNr= 0;BuffNr < InstancePtr->CanFdConfig.NumofRxMbBuf;
BuffNr++)
{
XCanFd_RxBuff_MailBox_DeActive(InstancePtr,BuffNr);
XCanFd_Set_MailBox_IdMask(InstancePtr,BuffNr,
TEST_MAIL_BOX_MASK,IdValue);
XCanFd_RxBuff_MailBox_Active(InstancePtr,BuffNr);
}
}
else {
/*In Sequential Mode */
XCanFd_AcceptFilterDisable(InstancePtr,XCANFD_AFR_UAF_ALL_MASK);
XCanFd_AcceptFilterEnable(InstancePtr,XCANFD_AFR_UAF_ALL_MASK);
}
/* Send the frame. */
Status = XCanFd_Send(InstancePtr,TxFrame,&TxBuffer);
if (Status != XST_SUCCESS) {
return Status;
}
/* Wait untill buffer is transmitted. */
while (XCanFd_IsBufferTransmitted(InstancePtr,TxBuffer) == FALSE);
if (XCANFD_GET_RX_MODE(InstancePtr) == 1) {
Status = XCanFd_Recv_Mailbox(InstancePtr, RxFrame);
}
else{
Status = XCanFd_Recv_Sequential(InstancePtr, RxFrame);
}
if (Status != XST_SUCCESS) {
return Status;
}
Dlc = ReceivedDlc = XCanFd_GetDlc2len(RxFrame[1] & XCANFD_DLCR_DLC_MASK);
/* Verify Identifier and Data Length Code. */
if (RxFrame[0] != XCanFd_CreateIdValue(TEST_MESSAGE_ID, 0, 0, 0, 0)) {
return XST_FAILURE;
}
if (TEST_CANFD_DLC != XCanFd_GetLen2Dlc(Dlc)) {
return XST_FAILURE;
}
/* Verify Data field contents. */
FramePtr = (u8 *)(&RxFrame[2]);
for (Index = 0; Index < Dlc; Index++) {
if (*FramePtr++ != (u8)Index) {
return XST_FAILURE;
}
}
XCanFd_Reset(InstancePtr);
return XST_SUCCESS;
}

View file

@ -0,0 +1,108 @@
/******************************************************************************
*
* (c) Copyright 2015 Xilinx, Inc. All rights reserved.
*
* This file contains confidential and proprietary information of Xilinx, Inc.
* and is protected under U.S. and international copyright and other
* intellectual property laws.
*
* DISCLAIMER
* This disclaimer is not a license and does not grant any rights to the
* materials distributed herewith. Except as otherwise provided in a valid
* license issued to you by Xilinx, and to the maximum extent permitted by
* applicable law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL
* FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS,
* IMPLIED, OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF
* MERCHANTABILITY, NON-INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE;
* and (2) Xilinx shall not be liable (whether in contract or tort, including
* negligence, or under any other theory of liability) for any loss or damage
* of any kind or nature related to, arising under or in connection with these
* materials, including for any direct, or any indirect, special, incidental,
* or consequential loss or damage (including loss of data, profits, goodwill,
* or any type of loss or damage suffered as a result of any action brought by
* a third party) even if such damage or loss was reasonably foreseeable or
* Xilinx had been advised of the possibility of the same.
*
* CRITICAL APPLICATIONS
* Xilinx products are not designed or intended to be fail-safe, or for use in
* any application requiring fail-safe performance, such as life-support or
* safety devices or systems, Class III medical devices, nuclear facilities,
* applications related to the deployment of airbags, or any other applications
* that could lead to death, personal injury, or severe property or
* environmental damage (individually and collectively, "Critical
* Applications"). Customer assumes the sole risk and liability of any use of
* Xilinx products in Critical Applications, subject only to applicable laws
* and regulations governing limitations on product liability.
*
* THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE
* AT ALL TIMES.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xcanFd_sinit.c
*
* This file contains the implementation of the XCanFd driver's static
* initialization functionality.
*
* @note None.
*
* <pre>
*
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ----- -------- -----------------------------------------------
* 1.00a nsk 06/03/15 First release
*
*
* </pre>
*
******************************************************************************/
/***************************** Include Files *********************************/
#include "xparameters.h"
#include "xcanfd.h"
/************************** Constant Definitions *****************************/
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Function Prototypes ******************************/
/************************** Variable Definitions *****************************/
extern XCanFd_Config XCanFd_ConfigTable[];
/*****************************************************************************/
/**
*
* This function looks for the device configuration based on the unique device
* ID. The table XCanFd_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.
*
******************************************************************************/
XCanFd_Config *XCanFd_LookupConfig(u16 DeviceId)
{
XCanFd_Config *CfgPtr = NULL;
u32 Index;
for (Index = 0; Index < XPAR_XCANFD_NUM_INSTANCES; Index++) {
if (XCanFd_ConfigTable[Index].DeviceId == DeviceId) {
CfgPtr = &XCanFd_ConfigTable[Index];
break;
}
}
return (XCanFd_Config *)CfgPtr;
}