diff --git a/XilinxProcessorIPLib/drivers/canfd/data/canfd.mdd b/XilinxProcessorIPLib/drivers/canfd/data/canfd.mdd new file mode 100644 index 00000000..3432924d --- /dev/null +++ b/XilinxProcessorIPLib/drivers/canfd/data/canfd.mdd @@ -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 diff --git a/XilinxProcessorIPLib/drivers/canfd/data/canfd.tcl b/XilinxProcessorIPLib/drivers/canfd/data/canfd.tcl new file mode 100644 index 00000000..e9c82778 --- /dev/null +++ b/XilinxProcessorIPLib/drivers/canfd/data/canfd.tcl @@ -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" +} diff --git a/XilinxProcessorIPLib/drivers/canfd/examples/index.html b/XilinxProcessorIPLib/drivers/canfd/examples/index.html new file mode 100755 index 00000000..d3f937ea --- /dev/null +++ b/XilinxProcessorIPLib/drivers/canfd/examples/index.html @@ -0,0 +1,18 @@ + + + + + +Driver example applications + + + +

Example Applications for the driver canfd_v1_0

+
+ +

Copyright @1995-2015 Xilinx, Inc. All rights reserved.

+ + diff --git a/XilinxProcessorIPLib/drivers/canfd/examples/xcanfd_intr_example.c b/XilinxProcessorIPLib/drivers/canfd/examples/xcanfd_intr_example.c new file mode 100644 index 00000000..573da7d2 --- /dev/null +++ b/XilinxProcessorIPLib/drivers/canfd/examples/xcanfd_intr_example.c @@ -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. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who	Date	 Changes
+* ----- -----  -------- -----------------------------------------------
+* 1.00a nsk    06/04/15 First release
+*
+* 
+* +******************************************************************************/ + +/***************************** 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 +#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; +} diff --git a/XilinxProcessorIPLib/drivers/canfd/examples/xcanfd_polled_example.c b/XilinxProcessorIPLib/drivers/canfd/examples/xcanfd_polled_example.c new file mode 100644 index 00000000..3f8e5112 --- /dev/null +++ b/XilinxProcessorIPLib/drivers/canfd/examples/xcanfd_polled_example.c @@ -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. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who    Date	Changes
+* ----- -----  -------- -----------------------------------------------
+* 1.00a nsk    06/04/2015 First release
+*
+* 
+* +******************************************************************************/ + +/***************************** 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__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; +} diff --git a/XilinxProcessorIPLib/drivers/canfd/src/Makefile b/XilinxProcessorIPLib/drivers/canfd/src/Makefile new file mode 100644 index 00000000..8cc98630 --- /dev/null +++ b/XilinxProcessorIPLib/drivers/canfd/src/Makefile @@ -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} diff --git a/XilinxProcessorIPLib/drivers/canfd/src/xcanfd.c b/XilinxProcessorIPLib/drivers/canfd/src/xcanfd.c new file mode 100644 index 00000000..4b239e2c --- /dev/null +++ b/XilinxProcessorIPLib/drivers/canfd/src/xcanfd.c @@ -0,0 +1,1564 @@ +/****************************************************************************** +* +* 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.c +* +* The XCanFd driver. Functions in this file are the minimum required functions +* for this driver. See xcanfd.h for a detailed description of the driver. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date	Changes
+* ----- ---- -------- -------------------------------------------------------
+* 1.00a nsk  06/04/15 First release
+*
+* 
+******************************************************************************/ + +/***************************** Include Files *********************************/ + +#include "xil_types.h" +#include "xil_assert.h" +#include "xil_io.h" +#include "xenv.h" +#include "xcanfd.h" +#include "xparameters.h" + +/************************** Constant Definitions *****************************/ + +/**************************** Type Definitions *******************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ + +/************************** Variable Definitions *****************************/ + +extern XCanFd_Config XCanFd_ConfigTable[]; + +/************************** Function Prototypes ******************************/ + +static void Initialize(XCanFd *InstancePtr, XCanFd_Config * ConfigPtr); +static void StubHandler(void); + +/************************** Global Variables ******************************/ + +/*****************************************************************************/ +/** +* +* This routine initializes a specific XCanFd instance/driver. This function +* should only be used when no Virtual Memory support is needed. +* +* This initialization entails: +* - Search for device configuration given the device ID. +* - Initialize Base Address field of the XCanFd structure using the device +* - address in the found device configuration. +* - Populate all other data fields in the XCanFd structure +* - Reset the device. +* +* @param InstancePtr is a pointer to the XCanFd instance to be worked on. +* +* @param ConfigPtr is the pointer to XCanFd_Config instance +* +* @param EffectiveAddr is the base address of CANFD +* +* @return - XST_SUCCESS if initialization was successful +* - XST_DEVICE_NOT_FOUND if device configuration information was + not found for a device with the supplied device ID. +* +* @note None. +* +******************************************************************************/ +int XCanFd_CfgInitialize(XCanFd *InstancePtr, XCanFd_Config *ConfigPtr, + u32 EffectiveAddr) +{ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(ConfigPtr != NULL); + + /* + * Set some default values for instance data, don't indicate the device + * is ready to use until everything has been initialized successfully. + */ + InstancePtr->IsReady = 0; + InstancePtr->CanFdConfig.BaseAddress = EffectiveAddr; + InstancePtr->CanFdConfig.DeviceId = ConfigPtr->DeviceId; + InstancePtr->CanFdConfig.Rx_Mode = ConfigPtr->Rx_Mode; + InstancePtr->CanFdConfig.NumofRxMbBuf = ConfigPtr->NumofRxMbBuf; + + /* + * Set all handlers to stub values, let user configure this data later. + */ + InstancePtr->SendHandler = (XCanFd_SendRecvHandler) StubHandler; + InstancePtr->RecvHandler = (XCanFd_SendRecvHandler) StubHandler; + InstancePtr->ErrorHandler = (XCanFd_ErrorHandler) StubHandler; + InstancePtr->EventHandler = (XCanFd_EventHandler) StubHandler; + + InstancePtr->IsReady = XIL_COMPONENT_IS_READY; + + /* Reset the device to get it into its initial state. */ + XCanFd_Reset(InstancePtr); + + return XST_SUCCESS; +} + +/*****************************************************************************/ +/** +* +* This function returns enabled acceptance filters. Use XCANFD_AFR_UAF*_MASK +* defined in xcanfd_l.h to interpret the returned value. If no acceptance +* filters are enabled then all received frames are stored in the RX FIFO. +* +* @param InstancePtr is a pointer to the XCanFd instance to be worked on. +* +* @return The value stored in Acceptance Filter Register. +* +* @note Acceptance Filter Register is an optional register in Xilinx +* CAN device If it is NOT existing in the device, this function +* should NOT be used.Calling this function in this case will +* cause an assertion failure. +* +******************************************************************************/ +u32 XCanFd_AcceptFilterGetEnabled(XCanFd *InstancePtr) +{ + u32 Result; + + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + Result = XCanFd_ReadReg(InstancePtr->CanFdConfig.BaseAddress, + XCANFD_AFR_OFFSET); + return Result; +} + +/****************************************************************************/ +/** +* +* This routine returns current operation mode the CAN device is in. +* +* @param InstancePtr is a pointer to the XCanFd instance to be worked on. +* +* @return - XCANFD_MODE_CONFIG if the device is in Configuration Mode. +* - XCANFD_MODE_SLEEP if the device is in Sleep Mode. +* - XCANFD_MODE_NORMAL if the device is in Normal Mode. +* - XCANFD_MODE_LOOPBACK if the device is in Loop Back Mode. +* - XCANFD_MODE_SNOOP if the device is in Snoop Mode. +* +* @note None. +* +*****************************************************************************/ +u8 XCanFd_GetMode(XCanFd *InstancePtr) +{ + u32 Value; + u32 Mode; + + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + Value = XCanFd_GetStatus(InstancePtr); + + if ((Value & XCANFD_SR_CONFIG_MASK) != (u32)0) { + Mode = XCANFD_MODE_CONFIG; + } + else if ((Value & XCANFD_SR_SLEEP_MASK) != (u32)0) { + Mode = XCANFD_MODE_SLEEP; + } + + else if ((Value & XCANFD_SR_NORMAL_MASK) != (u32)0) { + if ((Value & XCANFD_SR_SNOOP_MASK) != (u32)0) { + Mode = XCANFD_MODE_SNOOP; + } + else { + Mode = XCANFD_MODE_NORMAL; + } + } + + else { + /* If this line is reached, the device is in Loop Back Mode. */ + Mode = XCANFD_MODE_LOOPBACK; + } + return (u8)Mode; +} + +/*****************************************************************************/ +/** +* +* This function allows the CAN device to enter one of the following operation +* modes: +* +* - Configuration Mode: Pass in parameter XCANFD_MODE_CONFIG +* - Sleep Mode: Pass in parameter XCANFD_MODE_SLEEP +* - Normal Mode: Pass in parameter XCANFD_MODE_NORMAL +* - Loop Back Mode: Pass in parameter XCANFD_MODE_LOOPBACK. +* - Snoop Mode: Pass in Parameter XCANFD_MODE_SNOOP +* +* Read xcanfd.h and device specification for detailed description of each +* operation mode. +* +* @param InstancePtr is a pointer to the XCanFd instance to be worked on. +* @param OperationMode specify which operation mode to enter.Valid value +* is any of XCANFD_MODE_* defined in xcanfd.h. Please note no +* multiple modes could be entered at the same time. +* +* @return None. +* +* @note This function does NOT ensure CAN device enters the specified +* operation mode before returns the control to the caller. +* The caller is responsible for checking current operation mode +* using XCanFd_GetMode(). +* +******************************************************************************/ +void XCanFd_EnterMode(XCanFd *InstancePtr, u8 OperationMode) +{ + u8 CurrentMode; + u32 MsrReg; + + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + Xil_AssertVoid((OperationMode == XCANFD_MODE_CONFIG) || + (OperationMode == XCANFD_MODE_SLEEP) || + (OperationMode == XCANFD_MODE_NORMAL) || + (OperationMode == XCANFD_MODE_LOOPBACK) || + (OperationMode == XCANFD_MODE_SNOOP)); + + CurrentMode = XCanFd_GetMode(InstancePtr); + MsrReg = XCanFd_ReadReg(InstancePtr->CanFdConfig.BaseAddress, + XCANFD_MSR_OFFSET) & XCANFD_DAR_MASK; + if ((CurrentMode == XCANFD_MODE_NORMAL) && + (OperationMode == XCANFD_MODE_SLEEP)) { + + XCanFd_WriteReg(InstancePtr->CanFdConfig.BaseAddress, + XCANFD_MSR_OFFSET, + (XCANFD_MSR_SLEEP_MASK | MsrReg)); + return; + } + + else if ((CurrentMode == XCANFD_MODE_SLEEP) && + (OperationMode == XCANFD_MODE_NORMAL)) { + XCanFd_WriteReg(InstancePtr->CanFdConfig.BaseAddress, + XCANFD_MSR_OFFSET, MsrReg); + return; + } + + /* + * If the mode transition is not any of the two cases above, CAN must + * enter Configuration Mode before switching into the target operation + * mode. + */ + XCanFd_WriteReg(InstancePtr->CanFdConfig.BaseAddress, + XCANFD_SRR_OFFSET,MsrReg); + + /* + * Check if the device has entered Configuration Mode, if not, return + * to the caller. + */ + if (XCanFd_GetMode(InstancePtr) != XCANFD_MODE_CONFIG) { + return; + } + + switch (OperationMode) { + case XCANFD_MODE_CONFIG: + break; + + case XCANFD_MODE_SLEEP: + + /* Switch the device into Sleep Mode */ + XCanFd_WriteReg(InstancePtr->CanFdConfig.BaseAddress, + XCANFD_MSR_OFFSET, + (XCANFD_MSR_SLEEP_MASK | MsrReg)); + XCanFd_WriteReg(InstancePtr->CanFdConfig.BaseAddress, + XCANFD_SRR_OFFSET, + XCANFD_SRR_CEN_MASK); + + break; + + case XCANFD_MODE_NORMAL: + + XCanFd_WriteReg(InstancePtr->CanFdConfig.BaseAddress, + XCANFD_MSR_OFFSET,MsrReg); + XCanFd_WriteReg(InstancePtr->CanFdConfig.BaseAddress, + XCANFD_SRR_OFFSET,XCANFD_SRR_CEN_MASK); + + break; + + case XCANFD_MODE_LOOPBACK: + + XCanFd_WriteReg(InstancePtr->CanFdConfig.BaseAddress, + XCANFD_MSR_OFFSET, + (XCANFD_MSR_LBACK_MASK | MsrReg)); + XCanFd_WriteReg(InstancePtr->CanFdConfig.BaseAddress, + XCANFD_SRR_OFFSET, + XCANFD_SRR_CEN_MASK); + + break; + + case XCANFD_MODE_SNOOP: + + XCanFd_WriteReg(InstancePtr->CanFdConfig.BaseAddress, + XCANFD_MSR_OFFSET, (XCANFD_MSR_SNOOP_MASK | MsrReg)); + XCanFd_WriteReg(InstancePtr->CanFdConfig.BaseAddress, + XCANFD_SRR_OFFSET, XCANFD_SRR_CEN_MASK); + break; + } +} + +/*****************************************************************************/ +/** +* +* This function reads Receive and Transmit error counters. +* +* @param InstancePtr is a pointer to the XCanFd instance to be worked on. +* @param RxErrorCount will contain Receive Error Counter value after + this function returns. +* @param TxErrorCount will contain Transmit Error Counter value after +* this function returns. +* +* @return None. +* +* @note None. +* +******************************************************************************/ +void XCanFd_GetBusErrorCounter(XCanFd *InstancePtr, u8 *RxErrorCount, + u8 *TxErrorCount) +{ + u32 Result; + + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + Result = XCanFd_ReadReg(InstancePtr->CanFdConfig.BaseAddress, + XCANFD_ECR_OFFSET); + + *RxErrorCount = (Result & XCANFD_ECR_REC_MASK) >> XCANFD_ECR_REC_SHIFT; + *TxErrorCount = Result & XCANFD_ECR_TEC_MASK; +} + +/*****************************************************************************/ +/** +* +* This function sends a CAN/CANFD Frame. This function first checks whether +* free buffer is there or not.if free buffer is there the user data will be +* written into the free buffer.otherwise it returns error code immediately. +* This function does not wait for the given frame being sent to CAN bus. +* +* @param InstancePtr is a pointer to the XCanFd instance to be worked on. +* @param FramePtr is a pointer to a 32-bit aligned buffer containing the +* CAN frame to be sent. +* +* @param TxBufferNumber is the buffer where the user data has been +* written and it is updated by driver. +* +* @return - XST_SUCCESS if TX FIFO was not full and the given frame was +* written into the FIFO; +* - XST_FIFO_NO_ROOM if there is no room in the TX FIFO for the +* given frame +* +* @note None. +* +*****************************************************************************/ +int XCanFd_Send(XCanFd *InstancePtr, u32 *FramePtr,u32 *TxBufferNumber) +{ + u32 Result; + u32 FreeTxBuffer; + u32 DwIndex=0; + u32 Value; + u32 Dlc; + u32 Len; + u32 CanEDL; + u32 OutValue; + + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* Poll TRR to check pending transmission requests */ + Result = XCanFd_ReadReg(InstancePtr->CanFdConfig.BaseAddress, + XCANFD_TRR_OFFSET); + + FreeTxBuffer = XCanFd_GetFreeBuffer(InstancePtr); + + if (FreeTxBuffer == XST_NOBUFFER){ + return XST_FIFO_NO_ROOM; + } + else { + + /* Write ID to ID Register */ + XCanFd_WriteReg(InstancePtr->CanFdConfig.BaseAddress, + XCANFD_TXID_OFFSET(FreeTxBuffer),FramePtr[0]); + + /* Write DLC to DLC Register */ + XCanFd_WriteReg(InstancePtr->CanFdConfig.BaseAddress, + XCANFD_TXDLC_OFFSET(FreeTxBuffer),FramePtr[1]); + CanEDL = XCanFd_ReadReg(InstancePtr->CanFdConfig.BaseAddress, + XCANFD_TXDLC_OFFSET(FreeTxBuffer)); + + if (CanEDL & XCANFD_DLCR_EDL_MASK) { + + /* CAN FD Frames. */ + Dlc = XCanFd_GetDlc2len(FramePtr[1] & + XCANFD_DLCR_DLC_MASK); + /* Write Data to Data Register */ + + for (Len = 0;Len < Dlc;Len += 4) { + OutValue = Xil_EndianSwap32( + FramePtr[2+DwIndex]); + XCanFd_WriteReg( + InstancePtr->CanFdConfig.BaseAddress, + (XCANFD_TXDW_OFFSET(FreeTxBuffer)+ + (DwIndex*XCANFD_DW_BYTES)),OutValue); + DwIndex++; + } + } + else { + + /* Legacy CAN Frames */ + Dlc = XCanFd_GetDlc2len(FramePtr[1] & + XCANFD_DLCR_DLC_MASK); + for (Len = 0;Len < Dlc;Len += 4) { + OutValue = Xil_EndianSwap32( + FramePtr[2+DwIndex]); + XCanFd_WriteReg( + InstancePtr->CanFdConfig.BaseAddress, + (XCANFD_TXDW_OFFSET(FreeTxBuffer)+ + (Len)),OutValue); + DwIndex++; + } + } + } + + Value = XCanFd_ReadReg(InstancePtr->CanFdConfig.BaseAddress, + XCANFD_TRR_OFFSET); + Value |= (1 << FreeTxBuffer); + XCanFd_WriteReg(InstancePtr->CanFdConfig.BaseAddress, + XCANFD_TRR_OFFSET,Value); + + /* Assign buffer number to user */ + *TxBufferNumber = FreeTxBuffer; + + /* Make That buffer as transmitted */ + InstancePtr->FreeBuffStatus[FreeTxBuffer] = 0; + + return XST_SUCCESS; +} + +/*****************************************************************************/ +/** +* +* This function writes the Data into specific Buffer.we have 32 TxBuffers +* we can Add data to each Buffer using this routine.This routine won't +* transmit the data. it only adds data to Buffers. +* +* @param InstancePtr is a pointer to the XCanFd instance to be worked on. +* @param FramePtr is a pointer to a 32-bit aligned buffer containing the +* CAN frame to be sent. +* @param TxBufferNumber is Buffer Number where the data has written +* and is given back to user. +* +* @return - XST_SUCCESS if TX FIFO was not full and the given frame was +* written into the FIFO; +* - XST_FIFO_NO_ROOM if there is no room in the TX FIFO for the +* given frame +* +* @note None. +* +******************************************************************************/ +int XCanFd_Addto_Queue(XCanFd *InstancePtr, u32 *FramePtr,u32 *TxBufferNumber) +{ + u32 Result; + u32 FreeTxBuffer; + u32 DwIndex=0; + u32 Len; + u32 Dlc; + u32 CanEDL; + u32 OutValue; + + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* Poll TRR to check pending transmission requests */ + Result = XCanFd_ReadReg(InstancePtr->CanFdConfig.BaseAddress, + XCANFD_TRR_OFFSET); + + FreeTxBuffer = XCanFd_GetFreeBuffer(InstancePtr); + + if (FreeTxBuffer == XST_NOBUFFER){ + return XST_FIFO_NO_ROOM; + } + else { + if (InstancePtr->FreeBuffStatus[FreeTxBuffer] == 1) + return XST_BUFFER_ALREADY_FILLED; + InstancePtr->MultiBuffTrr |= 1 << FreeTxBuffer; + + /* Write ID to ID Register*/ + XCanFd_WriteReg(InstancePtr->CanFdConfig.BaseAddress, + XCANFD_TXID_OFFSET(FreeTxBuffer),FramePtr[0]); + + /* Write DLC to DLC Register*/ + XCanFd_WriteReg(InstancePtr->CanFdConfig.BaseAddress, + XCANFD_TXDLC_OFFSET(FreeTxBuffer),FramePtr[1]); + + CanEDL = XCanFd_ReadReg(InstancePtr->CanFdConfig.BaseAddress, + XCANFD_TXDLC_OFFSET(FreeTxBuffer)); + + Dlc = XCanFd_GetDlc2len(FramePtr[1] & XCANFD_DLCR_DLC_MASK); + + if (CanEDL & XCANFD_DLCR_EDL_MASK) { + + /* CAN FD Frames */ + for (Len = 0;Len < Dlc;Len += 4) { + OutValue = Xil_EndianSwap32( + FramePtr[2+DwIndex]); + XCanFd_WriteReg( + InstancePtr->CanFdConfig.BaseAddress, + (XCANFD_TXDW_OFFSET( + FreeTxBuffer)+(DwIndex* + XCANFD_DW_BYTES)),OutValue); + DwIndex++; + } + } + + else { + + /* Legacy CAN Frames */ + for (Len = 0;Len < Dlc;Len += 4) { + XCanFd_WriteReg( + InstancePtr->CanFdConfig.BaseAddress, + (XCANFD_TXDW_OFFSET( + FreeTxBuffer)+(Len)), + FramePtr[2+DwIndex]); + DwIndex++; + } + } + /* Assign Buffer to user */ + *TxBufferNumber = FreeTxBuffer; + + /* Mark Current Buffer as Filled */ + InstancePtr->FreeBuffStatus[FreeTxBuffer] = 1; + + return XST_SUCCESS; + } +} + +/*****************************************************************************/ +/** +* +* This function receives a CAN/CAN FD Frame. This function first checks FSR +* Register.The FL bits tells the Number of Packets received. if FL is non Zero +* then Read the Packet and store it to user Buffer. +* +* @param InstancePtr is a pointer to the XCanFd instance to be worked on. +* @param FramePtr is a pointer to a 32-bit aligned buffer where the +* CAN/CAN FD frame to be written. +* +* @return - XST_SUCCESS if RX FIFO was not empty and a frame was read from +* RX FIFO successfully and written into the given buffer; +* - XST_NO_DATA if there is no frame to be received from the FIFO +* +* @note This CANFD has two design modes. +* ->Sequential Mode - Core writes data sequentially to RxBuffers. +* ->MailBox Mode - Core writes data to RxBuffers when a ID +* Match happened. +* This routine is useful for Sequential Mode. +* +******************************************************************************/ +u32 XCanFd_Recv_Sequential(XCanFd *InstancePtr, u32 *FramePtr) +{ + u32 ReadIndex; + u32 DwIndex=0; + u32 Result; + u32 CanEDL; + u32 Dlc=0; + u32 Len; + + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + Result = XCanFd_ReadReg(InstancePtr->CanFdConfig.BaseAddress, + XCANFD_FSR_OFFSET); + + /* Check for the Packet Availability by reading FSR Register */ + if (Result & XCANFD_FSR_FL_MASK) { + ReadIndex = Result & XCANFD_FSR_RI_MASK; + + /* Read ID from ID Register*/ + FramePtr[0] = XCanFd_ReadReg( + InstancePtr->CanFdConfig.BaseAddress, + XCANFD_RXID_OFFSET(ReadIndex)); + + /* Read DLC from DLC Register*/ + FramePtr[1] = CanEDL = XCanFd_ReadReg( + InstancePtr->CanFdConfig.BaseAddress, + XCANFD_RXDLC_OFFSET(ReadIndex)); + + Dlc = XCanFd_GetDlc2len(FramePtr[1] & XCANFD_DLCR_DLC_MASK); + + if (CanEDL & XCANFD_DLCR_EDL_MASK) { + + /* Can Fd frames */ + for (Len = 0;Len < Dlc;Len += 4) { + FramePtr[2+DwIndex] = Xil_EndianSwap32( + XCanFd_ReadReg( + InstancePtr->CanFdConfig.BaseAddress, + (XCANFD_RXDW_OFFSET(ReadIndex)+ + (DwIndex*XCANFD_DW_BYTES)))); + DwIndex++; + } + } + else { + + /* Legacy CAN Frame */ + for (Len = 0;Len < Dlc;Len += 4) { + FramePtr[2+DwIndex] = Xil_EndianSwap32( + XCanFd_ReadReg( + InstancePtr->CanFdConfig.BaseAddress, + (XCANFD_RXDW_OFFSET(ReadIndex)+(Len)))); + DwIndex++; + } + } + + /* Set the IRI bit causes core to increment RI in FSR Register */ + Result = XCanFd_ReadReg(InstancePtr->CanFdConfig.BaseAddress, + XCANFD_FSR_OFFSET); + Result |= XCANFD_FSR_IRI_MASK; + XCanFd_WriteReg(InstancePtr->CanFdConfig.BaseAddress, + XCANFD_FSR_OFFSET,Result); + Result = XCanFd_ReadReg(InstancePtr->CanFdConfig.BaseAddress, + XCANFD_FSR_OFFSET); + + return XST_SUCCESS; + } + else { + return XST_NO_DATA; + } +} + +/*****************************************************************************/ +/** +* +* This function receives a CAN Frame in MAIL BOX Mode. Read Receive +* Control Status Registers.if CoreStatus bit is set then read that +* corresponding buffer and update the data to user buffer. +* +* @param InstancePtr is a pointer to the XCanFd instance to be worked on. +* @param FramePtr is a pointer to a 32-bit aligned buffer where the CAN +* frame to be receive. +* +* @return - XST_SUCCESS if RX FIFO was not empty and a frame was read from +* RX FIFO successfully and written into the given buffer; +* - XST_NO_DATA if there is no frame to be received from the FIFO +* +* @note This CANFD has two design modes. +* ->Sequential Mode - Core writes data sequentially to RxBuffers. +* ->MailBox Mode - Core writes data to RxBuffers when a ID +* match happened. +* This routine is useful for MailBox Mode. +* +******************************************************************************/ +u32 XCanFd_Recv_Mailbox(XCanFd *InstancePtr, u32 *FramePtr) +{ + u32 DwIndex=0; + u32 Result; + u32 CanEDL; + u32 ReadIndex=0; + u32 NoCtrlStatus; + u32 Dlc; + u32 Len; + u32 NofRcsReg=0; + /* + * Core status bit in Receive Control Status Register starts from 16 + * th bit Location. + */ + u32 CoreStatusBit=16; + + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + NofRcsReg = XCanFd_Get_NofRxBuffers(InstancePtr); + + for (NoCtrlStatus = 0;NoCtrlStatus < NofRcsReg;NoCtrlStatus++) { + Result = XCanFd_ReadReg(InstancePtr->CanFdConfig.BaseAddress, + XCANFD_RCS_OFFSET(NoCtrlStatus)); + + while (CoreStatusBit <32) { + if (Result & (1<< CoreStatusBit)) { + + /* Read ID from ID Register of that FIFO */ + FramePtr[0] = XCanFd_ReadReg( + InstancePtr->CanFdConfig. + BaseAddress, + XCANFD_RXID_OFFSET(ReadIndex)); + + /* Read DLC from DLC Register of that FIFO */ + FramePtr[1] = CanEDL = XCanFd_ReadReg( + InstancePtr->CanFdConfig. + BaseAddress, + XCANFD_RXDLC_OFFSET(ReadIndex)); + + Dlc = XCanFd_GetDlc2len(FramePtr[1] & + XCANFD_DLCR_DLC_MASK); + + /* CanFD Frame is received */ + if (CanEDL & XCANFD_DLCR_EDL_MASK) { + /* + * Read all Bytes from DW Register of + * that FIFO + */ + for (Len = 0;Len < Dlc;Len += 4) { + FramePtr[2+DwIndex] = + Xil_EndianSwap32( + XCanFd_ReadReg( + InstancePtr->CanFdConfig. + BaseAddress, + (XCANFD_RXDW_OFFSET( + ReadIndex) + +(DwIndex*XCANFD_DW_BYTES)))); + DwIndex++; + } + DwIndex=0; + } + else { + /* Legacy CAN Frame */ + for (Len = 0;Len < Dlc;Len += 4) { + FramePtr[2+DwIndex] = + Xil_EndianSwap32( + XCanFd_ReadReg( + InstancePtr->CanFdConfig. + BaseAddress, + (XCANFD_RXDW_OFFSET(ReadIndex)+ + (Len)))); + DwIndex++; + } + } + Result ^= (1 << CoreStatusBit); + XCanFd_WriteReg(InstancePtr->CanFdConfig. + BaseAddress, + XCANFD_RCS_OFFSET(NoCtrlStatus),Result); + return XST_SUCCESS; + } + ReadIndex++; + CoreStatusBit++; + } + CoreStatusBit = 16; + } + return XST_NO_DATA; +} + +/*****************************************************************************/ +/** +* +* This function sets an RxBuffer to Active State.In Mailbox Mode configuration +* we can set each buffer to receive with specific Id and Mask.inorder compare +* we need to first Activate the Buffer.Maximum number of RxBuffers depends on +* Design.Range 48,32,16. +* +* @param InstancePtr is a pointer to the XCanFd instance to be worked on. +* @param RxBuffer Receive Buffer Number defines which Buffer to configure +* Value ranges from 0 - 48 +* +* @return - XST_SUCCESS if the values were set successfully. +* +* @note none +* +******************************************************************************/ +u32 XCanFd_RxBuff_MailBox_Active(XCanFd *InstancePtr, u32 RxBuffer) +{ + u32 Status = 0; + u32 NoCtrlStatus; + + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + Xil_AssertNonvoid(RxBuffer < InstancePtr->CanFdConfig.NumofRxMbBuf); + + if (RxBuffer <=15) { + NoCtrlStatus = 0; + } + else if (RxBuffer <=31) { + RxBuffer -= 16; + NoCtrlStatus = 1; + } + else { + RxBuffer -= 32; + NoCtrlStatus = 2; + } + Status = XCanFd_ReadReg(InstancePtr->CanFdConfig.BaseAddress, + XCANFD_RCS_OFFSET(NoCtrlStatus)); + if (Status & 1 << RxBuffer) { + return; + } + Status |= (1<< RxBuffer); + XCanFd_WriteReg(InstancePtr->CanFdConfig.BaseAddress, + XCANFD_RCS_OFFSET(NoCtrlStatus),Status); + return XST_SUCCESS; +} + +/*****************************************************************************/ +/** +* +* This function sets the Id and Mask for an RxBuffer to participate in +* Id match.if a packet is received with an id which is equal to id we +* configured, then it is stored in RxBuffer. otherwise it won't. +* +* @param InstancePtr is a pointer to the XCanFd instance to be worked on. +* @param RxBuffer Receive Buffer Number defines which Buffer to configure +* Value ranges from 0 - 48(can get from NumofRxMbBuf) +* @param MaskValue is the value to write into the RxBuffer Mask Register +* @param IdValue is the value to write into the RxBuffer Id register +* +* @return - XST_SUCCESS if the values were set successfully. +** +* @note none +* +******************************************************************************/ +u32 XCanFd_Set_MailBox_IdMask(XCanFd *InstancePtr, u32 RxBuffer, + u32 MaskValue, u32 IdValue) +{ + u32 Status = 0; + u32 NoCtrlStatus; + u32 BufferNr = RxBuffer; + + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + Xil_AssertNonvoid(RxBuffer < InstancePtr->CanFdConfig.NumofRxMbBuf); + + if (RxBuffer <=15) { + NoCtrlStatus = 0; + } + else if (RxBuffer <=31) { + RxBuffer -= 16; + NoCtrlStatus = 1; + } + else { + RxBuffer -= 32; + NoCtrlStatus = 2; + } + + Status = XCanFd_ReadReg(InstancePtr->CanFdConfig.BaseAddress, + XCANFD_RCS_OFFSET(NoCtrlStatus)); + + if (Status & 1 << RxBuffer) { + Status &= ~(1<< RxBuffer); + XCanFd_WriteReg(InstancePtr->CanFdConfig.BaseAddress, + XCANFD_RCS_OFFSET(NoCtrlStatus),Status); + } + + XCanFd_WriteReg(InstancePtr->CanFdConfig.BaseAddress, + XCANFD_MAILBOX_MASK_OFFSET(BufferNr),MaskValue); + XCanFd_WriteReg(InstancePtr->CanFdConfig.BaseAddress, + XCANFD_MAILBOX_ID_OFFSET(BufferNr),IdValue); + + return XST_SUCCESS; +} + +/*****************************************************************************/ +/** +* +* This function sets an RxBuffer to InActive State.if we change a buffer to +* InActive state, then Rx Packet won't store into that buffer, even the Id +* is matched. +* +* @param InstancePtr is a pointer to the XCanFd instance to be worked on. +* @param RxBuffer Receive Buffer Number defines which Buffer to configure +* Value ranges from 0 - 48 +* +* @return - XST_SUCCESS if the values were set successfully. +* - XST_FAILURE if the given filter was not disabled, or the CAN +* device was not ready to accept writes to AFMR and AFIR. +* +* @note none +* +******************************************************************************/ +u32 XCanFd_RxBuff_MailBox_DeActive(XCanFd *InstancePtr, u32 RxBuffer) +{ + u32 Status; + u8 NoCtrlStatus; + + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + Xil_AssertNonvoid(RxBuffer < InstancePtr->CanFdConfig.NumofRxMbBuf); + + if (RxBuffer <=15) { + NoCtrlStatus = 0; + } + else if (RxBuffer <=31) { + RxBuffer -= 16; + NoCtrlStatus = 1; + } + else { + RxBuffer -= 32; + NoCtrlStatus = 2; + } + + Status = XCanFd_ReadReg(InstancePtr->CanFdConfig.BaseAddress, + XCANFD_RCS_OFFSET(NoCtrlStatus)); + if (Status & 1 << RxBuffer) { + Status &= ~(1<< RxBuffer); + XCanFd_WriteReg(InstancePtr->CanFdConfig.BaseAddress, + XCANFD_RCS_OFFSET(NoCtrlStatus),Status); + } + return XST_SUCCESS; +} + +/*****************************************************************************/ +/** +* +* This function Cancels a CAN/CAN FD Frame which was already initiated for +* transmission.This function first checks TRR Bit based on BufferNumber. +* if TRR Bit is set, then it cancels the Buffers. +* +* @param InstancePtr is a pointer to the XCanFd instance to be worked on. +* @param BufferNumber is which Buffer to cancel out of 32 Buffers. +* +* @return - XST_SUCCESS if RX FIFO was not empty and a frame was read from +* RX FIFO successfully and written into the given buffer; +* - XST_NO_DATA if there is no frame to be received from the FIFO +* +* @note This function first checks whether TRR bit is set or not +* if Set, it then checks the corresponding TCR bit +* ->if Set, then wait until cancellation is performed. +* ->if Not set, then set the corresponding TCR bit and +* wait until core clears it. +* if Not set, Nothing to do. +* +******************************************************************************/ +int XCanFd_TxBuffer_Cancel_Request(XCanFd *InstancePtr,u32 BufferNumber) +{ + + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + if ((BufferNumber >= 0) || (BufferNumber <32)) { + if (XCanFd_ReadReg(InstancePtr->CanFdConfig.BaseAddress, + XCANFD_TRR_OFFSET) & (1<CanFdConfig.BaseAddress, + XCANFD_TCR_OFFSET)& (1<CanFdConfig.BaseAddress, + XCANFD_TCR_OFFSET)& (1<FreeBuffStatus[BufferNumber]= 0; + + return XST_SUCCESS; + } + else { + + /* + * buffer has pending transmission request but no pending + * cancellation request + */ + XCanFd_WriteReg(InstancePtr->CanFdConfig. + BaseAddress,XCANFD_TCR_OFFSET,1<CanFdConfig.BaseAddress, + XCANFD_TCR_OFFSET)& (1<FreeBuffStatus[BufferNumber]= 0; + + return XST_SUCCESS; + } + } + } + else + return XST_FAILURE; + +} + +/*****************************************************************************/ +/** +* This routine enables the acceptance filters. Up to 32 filters can +* be enabled. +* +* @param InstancePtr is a pointer to the XCanFd instance to be worked on. +* @param FilterIndexMask specifies which filter(s) to enable. Use +* any XCANFD_AFR_UAF*_MASK to enable one filter, and "Or" multiple +* XCANFD_AFR_UAF*_MASK values if multiple filters need to be +* enabled. Any filter not specified in this parameter will keep +* its previous enable/disable setting. +* +* @return None. +* +* @note In Sequential Mode, in order to receive data, we need to enable +* these filters. if we want to make filtration i.e Id match +* then we need to set the Id value in AFR Id register. +* +******************************************************************************/ +void XCanFd_AcceptFilterEnable(XCanFd *InstancePtr, u32 FilterIndexMask) +{ + u32 EnabledFilters; + + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + EnabledFilters = + XCanFd_ReadReg(InstancePtr->CanFdConfig.BaseAddress, + XCANFD_AFR_OFFSET); + + EnabledFilters |= FilterIndexMask; + + XCanFd_WriteReg(InstancePtr->CanFdConfig.BaseAddress, XCANFD_AFR_OFFSET, + EnabledFilters); + +} + +/*****************************************************************************/ +/** +* +* This routine disables the acceptance filters. 32 filters can be disabled. +* +* @param InstancePtr is a pointer to the XCanFd instance to be worked on. +* @param FilterIndexMask specifies which filter(s) to disable. Use +* any XCANFD_AFR_UAF*_MASK to disable one filter, and "Or" multiple +* XCANFD_AFR_UAF*_MASK values if multiple filters need to be +* disabled. Any filter not specified in this parameter will keep +* its previous enable/disable setting. If all acceptance filters +* are disabled then all received frames are stored in the RX FIFO. +* +* @return None. +* +* @note None +* +******************************************************************************/ +void XCanFd_AcceptFilterDisable(XCanFd *InstancePtr, u32 FilterIndexMask) +{ + u32 EnabledFilters; + + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + EnabledFilters = + XCanFd_ReadReg(InstancePtr->CanFdConfig.BaseAddress, + XCANFD_AFR_OFFSET); + + EnabledFilters &= (~FilterIndexMask); + + XCanFd_WriteReg(InstancePtr->CanFdConfig.BaseAddress, XCANFD_AFR_OFFSET, + EnabledFilters); + +} + +/*****************************************************************************/ +/** +* +* This function sets values to the Acceptance Filter Mask Register (AFMR) and +* Acceptance Filter ID Register (AFIR) for the specified Acceptance Filter. +* Use XCANFD_IDR_* defined in xcanfd_l.h to create the values to set the filter. +* Read xcanfd.h and device specification for details. +* +* This function should be called only after: +* - The given filter is disabled by calling XCanFd_AcceptFilterDisable(); +* - And the CAN device is ready to accept writes to AFMR and AFIR, i.e., +* XCanFd_IsAcceptFilterBusy() returns FALSE. +* +* @param InstancePtr is a pointer to the XCanFd instance to be worked on. +* @param FilterIndex defines which Acceptance Filter Mask and ID Register +* to set. Use any single XCANFD_AFR_UAF*_MASK value.ranges from 0 +* - 31 +* @param MaskValue is the value to write to the chosen Acceptance Filter +* Mask Register. +* @param IdValue is the value to write to the chosen Acceptance Filter +* ID Register. +* +* @return - XST_SUCCESS if the values were set successfully. +* - XST_FAILURE if the given filter was not disabled, or the CAN +* device was not ready to accept writes to AFMR and AFIR. +* +* @note Acceptance Filter Mask and ID Registers are optional registers in +* Xilinx XCanFd device.if they are not configured then device will +* receive data with any ID. +* +******************************************************************************/ +int XCanFd_AcceptFilterSet(XCanFd *InstancePtr, u32 FilterIndex, + u32 MaskValue, u32 IdValue) +{ + u32 EnabledFilters; + + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + Xil_AssertNonvoid((FilterIndex > 0) ||(FilterIndex <= 32)); + + /* + * Check if the given filter is currently enabled. If yes, return error + * code. + */ + EnabledFilters = XCanFd_AcceptFilterGetEnabled(InstancePtr); + + if ((EnabledFilters & FilterIndex) == FilterIndex) { + return XST_FAILURE; + } + + XCanFd_WriteReg(InstancePtr->CanFdConfig.BaseAddress, + XCANFD_AFMR_OFFSET(FilterIndex-1),MaskValue); + + XCanFd_WriteReg(InstancePtr->CanFdConfig.BaseAddress, + XCANFD_AFIDR_OFFSET(FilterIndex-1),IdValue); + + + return XST_SUCCESS; +} + +/*****************************************************************************/ +/** +* +* This function reads the values of the Acceptance Filter Mask and ID Register +* for the specified Acceptance Filter. Use XCANFD_IDR_* defined in xcanfd_l.h to +* interpret the values. Read xcanfd.h and device specification for details. +* +* @param InstancePtr is a pointer to the XCanFd instance to be worked on. +* @param FilterIndex defines which Acceptance Filter Mask Register to get +* Mask and ID from. Use any single XCANFD_FILTER_* value. +* @param MaskValue will store the Mask value read from the chosen +* Acceptance Filter Mask Register after this function returns. +* @param IdValue will store the ID value read from the chosen Acceptance +* Filter ID Register after this function returns. +* +* @return None. +* +* @note Acceptance Filter Mask and ID Registers are optional registers +* in Xilinx CAN device. If they are NOT existing in the device, +* this function should NOT be used. Calling this function in this +* case will cause an assertion failure. +* +******************************************************************************/ +void XCanFd_AcceptFilterGet(XCanFd *InstancePtr, u32 FilterIndex, + u32 *MaskValue, u32 *IdValue) +{ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + Xil_Assertvoid(FilterIndex < XCANFD_NOOF_AFR); + + *MaskValue = XCanFd_ReadReg(InstancePtr->CanFdConfig.BaseAddress, + XCANFD_AFMR_OFFSET(FilterIndex)); + + *IdValue = XCanFd_ReadReg(InstancePtr->CanFdConfig.BaseAddress, + XCANFD_AFIDR_OFFSET(FilterIndex)); + +} + +/*****************************************************************************/ +/** +* +* This function looks for the device configuration based on the device index. +* The table XCanFd_ConfigTable[] contains the configuration information for each +* device in the system. +* +* @param InstanceIndex is a 0-based integer indexing all CAN devices in +* the system. +* +* @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_GetConfig(unsigned int InstanceIndex) +{ + XCanFd_Config *CfgPtr; + + /* Check parameter */ + if (InstanceIndex >= XPAR_XCANFD_NUM_INSTANCES) + return NULL; + + CfgPtr = &XCanFd_ConfigTable[InstanceIndex]; + + return CfgPtr; +} + +/******************************************************************************/ +/** +* +* This routine is a stub for the asynchronous callbacks. The stub is here in +* case the upper layer forgot to set the handler(s). On initialization, all +* handlers are set to this callback. It is considered an error for this handler +* to be invoked. +* +* @param None. +* +* @return None. +* +* @note None. +* +******************************************************************************/ +static void StubHandler(void) +{ + Xil_AssertVoidAlways(); +} + +/*****************************************************************************/ +/** +* +* This function returns Data Length Code(in Bytes),we need to pass +* DLC Field value in DLC Register. +* +* @param Dlc Field in Data Length Code Register. +* +* +* @return Total Number of Bytes stored in each Buffer. +* +* @note Refer CAN FD Spec about DLC. +* +******************************************************************************/ +int XCanFd_GetDlc2len(u32 Dlc) +{ + + u32 NofBytes=0; + + switch(Dlc) { + + case XCANFD_DLC1: + NofBytes = 1; + break; + + case XCANFD_DLC2: + NofBytes = 2; + break; + + case XCANFD_DLC3: + NofBytes = 3; + break; + + case XCANFD_DLC4: + NofBytes = 4; + break; + + case XCANFD_DLC5: + NofBytes = 5; + break; + + case XCANFD_DLC6: + NofBytes = 6; + break; + + case XCANFD_DLC7: + NofBytes = 7; + break; + + case XCANFD_DLC8: + NofBytes = 8; + break; + + case XCANFD_DLC9: + NofBytes = 12; + break; + + case XCANFD_DLC10: + NofBytes = 16; + break; + + case XCANFD_DLC11: + NofBytes = 20; + break; + + case XCANFD_DLC12: + NofBytes = 24; + break; + + case XCANFD_DLC13: + NofBytes = 32; + break; + + case XCANFD_DLC14: + NofBytes = 48; + break; + + case XCANFD_DLC15: + NofBytes = 64; + break; + default : + break; + } + return NofBytes; +} + +/*****************************************************************************/ +/** +* +* This function returns Data Length Code of 4bits,we need to pass +* length in bytes. +* +* @param len is the length in bytes. +* +* @return Total Number of Bytes stored in each Buffer. +* +* @note Refer CAN FD Spec about DLC. +* +******************************************************************************/ +u8 XCanFd_GetLen2Dlc(int len) +{ + if(len <= 8) + return len; + else if(len <= 12) + return 9; + else if(len <= 16) + return 10; + else if(len <= 20) + return 11; + else if(len <= 24) + return 12; + else if(len <= 32) + return 13; + else if(len <= 48) + return 14; + else if(len <= 64) + return 15; + else + return XST_INVALID_DLC; +} + +/*****************************************************************************/ +/** +* This Routine returns the Free Buffer out of 32 Transmit Buffers. +* +* @param InstancePtr is a pointer to the XCanFd instance to be worked on. +* +* +* @return Returns Free buffer if any free buffer +* other wise returns XST_NOBUFFER. +* +* @note None. +* +******************************************************************************/ +int XCanFd_GetFreeBuffer(XCanFd *InstancePtr) +{ + + u32 AvailBuffer=0; + + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + for (AvailBuffer = 0;AvailBuffer <= 31;AvailBuffer++) { + + if (InstancePtr->FreeBuffStatus[AvailBuffer]!= 1) { + return AvailBuffer; + } + } + return XST_NOBUFFER; + +} + +/*****************************************************************************/ +/** +* +* This routine sends queue of buffers,when added to queue using Addto_Queue() +* Basically this will trigger the TRR Bit(s).This routine can be used +* when user want to send multiple packets at a time. +* +* @param InstancePtr is a pointer to the XCanFd instance to be worked on. +* +* @return - XST_SUCCESS. +* +* @note None. +* +******************************************************************************/ +int XCanFd_Send_Queue(XCanFd *InstancePtr) +{ + + u32 BufferNr; + u32 TrrVal; + + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Set the bits of Transmit Ready Request Register + * InstancePtr->MultiBuffTrr is updated by calling + * XCanFd_Addto_Queue() + */ + TrrVal = InstancePtr->MultiBuffTrr; + XCanFd_WriteReg(InstancePtr->CanFdConfig.BaseAddress, XCANFD_TRR_OFFSET, + TrrVal); + MAKE_CURRENTBUFFER_ZERO(InstancePtr); + + return XST_SUCCESS; + +} + +/*****************************************************************************/ +/** +* +* This function Polls the TxBuffer(s) whether it is transmitted or not. +* 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. +* +******************************************************************************/ +void XCanFd_PollQueue_Buffer(XCanFd *InstancePtr) +{ + u32 BufferNumber; + + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + if (InstancePtr->MultiBuffTrr!=0) { + for (BufferNumber = 0;BufferNumber < 32;BufferNumber++) { + if (InstancePtr->MultiBuffTrr & (1 << BufferNumber)) + while (XCanFd_IsBufferTransmitted(InstancePtr, + BufferNumber) == FALSE); + } + InstancePtr->MultiBuffTrr = 0; + } + +} + +/*****************************************************************************/ +/** +* +* This function returns Number of messages Stored. +* The FSR Register has Field called FL. this gives number of packets +* received. +* +* @param InstancePtr is a pointer to the XCanFd instance to be worked on. +* +* @return Value is the number of messages stored in FSR Register. +* +* @note None +* +******************************************************************************/ + +int XCanFd_GetNofMessages_Stored(XCanFd *InstancePtr) +{ + + u32 FillLevel; + u32 Result; + + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + Result = XCanFd_ReadReg(InstancePtr->CanFdConfig.BaseAddress, + XCANFD_FSR_OFFSET); + + FillLevel = Result & XCANFD_FSR_FL_MASK; + FillLevel >>= 8; + + return FillLevel; + +} + +/*****************************************************************************/ +/** +* +* This function Enables the Transceiver delay compensation. +* +* @param InstancePtr is a pointer to the XCanFd instance to be worked on. +* +* @return None. +* +* +* @note None. +* +******************************************************************************/ +void XCanFd_Enable_Tranceiver_Delay_Compensation(XCanFd *InstancePtr) +{ + u32 RegValue = 0; + + Xil_Assertvoid(InstancePtr != NULL); + Xil_Assertvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + RegValue = XCanFd_ReadReg(InstancePtr->CanFdConfig.BaseAddress, + XCANFD_F_BRPR_OFFSET); + RegValue |= XCANFD_F_BRPR_TDC_ENABLE_MASK; + + XCanFd_WriteReg(InstancePtr->CanFdConfig.BaseAddress, + XCANFD_F_BRPR_OFFSET,RegValue); +} + +/*****************************************************************************/ +/** +* +* This function Sets the Transceiver delay compensation offset. +* +* @param InstancePtr is a pointer to the XCanFd instance to be worked on. +* +* @param TdcOffset is the Delay Compensation Offset. +* +* @return None. +* +* +* @note None. +* +******************************************************************************/ +void XCanFd_Set_Tranceiver_Delay_Compensation(XCanFd *InstancePtr, + u32 TdcOffset) +{ + + u32 RegValue=0; + + Xil_Assertvoid(InstancePtr != NULL); + Xil_Assertvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + if (TdcOffset <= 32) { + + RegValue = XCanFd_ReadReg(InstancePtr->CanFdConfig.BaseAddress, + XCANFD_F_BRPR_OFFSET); + + TdcOffset <<= 8; + RegValue |= (TdcOffset & XCANFD_F_BRPR_TDCMASK); + + XCanFd_WriteReg(InstancePtr->CanFdConfig.BaseAddress, + XCANFD_F_BRPR_OFFSET,RegValue); + } + +} + +/*****************************************************************************/ +/** +* +* This function Disables the Transceiver delay compensation. +* +* @param InstancePtr is a pointer to the XCanFd instance to be worked on. +* +* @return None. +* +* @note None. +* +******************************************************************************/ +void XCanFd_Disable_Tranceiver_Delay_Compensation(XCanFd *InstancePtr) +{ + u32 RegValue=0; + + Xil_Assertvoid(InstancePtr != NULL); + Xil_Assertvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + RegValue = XCanFd_ReadReg(InstancePtr->CanFdConfig.BaseAddress, + XCANFD_F_BRPR_OFFSET); + RegValue &= ~XCANFD_F_BRPR_TDC_ENABLE_MASK; + XCanFd_WriteReg(InstancePtr->CanFdConfig.BaseAddress, + XCANFD_F_BRPR_OFFSET,RegValue); +} diff --git a/XilinxProcessorIPLib/drivers/canfd/src/xcanfd.h b/XilinxProcessorIPLib/drivers/canfd/src/xcanfd.h new file mode 100644 index 00000000..7b3e1cdc --- /dev/null +++ b/XilinxProcessorIPLib/drivers/canfd/src/xcanfd.h @@ -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. +* +* Driver Description +* +* 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 +* +* Operation Modes +* +* The CANFD controller supports the following modes of operation: +* - Configuration Mode: In this mode the CAN timing parameters and +* Baud Rate Pre-scalar parameters can be changed. In this mode the CAN +* controller loses synchronization with the CAN bus and drives a +* constant recessive bit on the bus line. The Error Counter Register are +* reset. The CAN controller does not receive or transmit any messages even +* if there are pending transmit requests from the TX FIFO or the TX High +* Priority Buffer. the Storage FIFOs and the CAN configuration registers +* are still accessible. +* - Normal Mode:In Normal Mode the CAN controller participates in bus +* communication, by transmitting and receiving messages. +* - Sleep Mode: In Sleep Mode the CAN Controller does not transmit any +* messages. However, if any other node transmits a message, then the CAN +* Controller receives the transmitted message and exits from Sleep Mode. +* If there are new transmission requests from either the TX FIFO or the +* TX High Priority Buffer when the CAN Controller is in Sleep Mode, these +* requests are not serviced, and the CAN Controller continues to remain in +* Sleep Mode. Interrupts are generated when the CAN controller enters Sleep +* mode or Wakes up from Sleep mode. +* - Loop Back Mode: In Loop Back mode, the CAN controller transmits a +* recessive bit stream on to the CAN Bus. Any message that is transmitted +* is 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. +* - Snoop mode: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. +* +* Buffer Alignment +* +* It is important to note that frame buffers passed to the driver must be +* 32-bit aligned. +* +* Receive Address Filtering +* +* The device can be set to accept frames whose Identifiers match any of 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. +* +* PHY Communication +* +* This driver does not provide any mechanism for directly programming PHY. +* +* Interrupts +* +* The driver has no dependencies on the interrupt controller. The driver +* provides an interrupt handler. User of this driver needs to provide +* callback functions. An interrupt handler example is available with +* the driver. +* +* Virtual Memory +* +* 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. +* +* Threads +* +* This driver is not thread safe. Any needs for threads or thread mutual +exclusion +* must be satisfied by the layer above this driver. +* +* Device Reset +* +* Bus Off interrupt that can occur in the device requires a device reset. The +* user is responsible for resetting the device and re-configuring it +* based on its needs (the driver does not save the current configuration). When +* integrating into an RTOS, these reset and re-configure obligations are +* taken care of by the OS adapter software if it exists for that RTOS. +* +* Device Configuration +* +* The device can be configured in various ways during the FPGA implementation +* process. Configuration parameters are stored in the 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. +* +* Asserts +* +* Asserts are used within all Xilinx drivers to enforce constraints on argument +* values. Asserts can be turned off on a system-wide basis by defining, at +* compile time, the NDEBUG identifier. By default, asserts are turned on and it +* is recommended that users leave asserts on during development. +* +* Building the driver +* +* The 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. +*

+* +*
+* Temp Change
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -------------------------------------------------------
+* 1.00a nsk  06/04/15 First release
+*
+* 
+* +******************************************************************************/ + +#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 */ diff --git a/XilinxProcessorIPLib/drivers/canfd/src/xcanfd_config.c b/XilinxProcessorIPLib/drivers/canfd/src/xcanfd_config.c new file mode 100644 index 00000000..1719cbb6 --- /dev/null +++ b/XilinxProcessorIPLib/drivers/canfd/src/xcanfd_config.c @@ -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. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -------------------------------------------------------
+* 1.00a nsk  06/04/15 First release
+*
+* 
+******************************************************************************/ + +/***************************** 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); +} diff --git a/XilinxProcessorIPLib/drivers/canfd/src/xcanfd_g.c b/XilinxProcessorIPLib/drivers/canfd/src/xcanfd_g.c new file mode 100644 index 00000000..935e8b5f --- /dev/null +++ b/XilinxProcessorIPLib/drivers/canfd/src/xcanfd_g.c @@ -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 + } +}; diff --git a/XilinxProcessorIPLib/drivers/canfd/src/xcanfd_intr.c b/XilinxProcessorIPLib/drivers/canfd/src/xcanfd_intr.c new file mode 100644 index 00000000..97b2b1cf --- /dev/null +++ b/XilinxProcessorIPLib/drivers/canfd/src/xcanfd_intr.c @@ -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. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date      Changes
+* ----- ---- --------- -----------------------------------------------
+* 1.00a nsk  06/04/15  First release
+
+* 
+* +******************************************************************************/ + +/***************************** 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: +* +*
+* 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.
+* 
+* +* @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); +} diff --git a/XilinxProcessorIPLib/drivers/canfd/src/xcanfd_l.h b/XilinxProcessorIPLib/drivers/canfd/src/xcanfd_l.h new file mode 100644 index 00000000..13cd0b49 --- /dev/null +++ b/XilinxProcessorIPLib/drivers/canfd/src/xcanfd_l.h @@ -0,0 +1,1181 @@ +/****************************************************************************** +* +* 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_l.h +* +* This header file contains the identifiers and basic driver functions (or +* macros) that can be used to access the device. Other driver functions +* are defined in xcanfd.h. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date       Changes
+* ----- ---- ---------- -----------------------------------------------
+* 1.00a nsk  06/04/2015 First release
+*
+*
+* 
+* +******************************************************************************/ + +#ifndef XCANFD_L_H /* prevent circular inclusions */ +#define XCANFD_L_H /* by using protection macros */ + +#ifdef __cplusplus +extern "C" { +#endif + + +/***************************** Include Files *********************************/ + +#include "xil_types.h" +#include "xil_assert.h" +#include "xil_io.h" +#include "xparameters.h" +/************************** Constant Definitions *****************************/ + +/** @name Register offsets for the CAN. Each register is 32 bits. + * @{ + */ +#define XCANFD_SRR_OFFSET 0x000 /**< Software Reset Register */ +#define XCANFD_MSR_OFFSET 0x004 /**< Mode Select Register */ +#define XCANFD_BRPR_OFFSET 0x008 /**< Baud Rate Prescaler Register */ +#define XCANFD_BTR_OFFSET 0x00C /**< Bit Timing Register */ +#define XCANFD_ECR_OFFSET 0x010 /**< Error Counter Register */ +#define XCANFD_ESR_OFFSET 0x014 /**< Error Status Register */ +#define XCANFD_SR_OFFSET 0x018 /**< Status Register */ + +#define XCANFD_ISR_OFFSET 0x01C /**< Interrupt Status Register */ +#define XCANFD_IER_OFFSET 0x020 /**< Interrupt Enable Register */ +#define XCANFD_ICR_OFFSET 0x024 /**< Interrupt Clear Register */ + +#define XCANFD_F_BRPR_OFFSET 0x088 /**< Data Phase Buad Rate Prescalar + Register */ +#define XCANFD_F_BTR_OFFSET 0x08C /**< Data Phase Bit Timing Register */ +#define XCANFD_TRR_OFFSET 0x090 /**< Tx Buffer Ready Request Register */ +#define XCANFD_IETRS_OFFSET 0x094 /**< Tx Buffer Ready Request Served + Interrupt Enable Register */ +#define XCANFD_TCR_OFFSET 0x098 /**< Tx Buffer Cancel Request Register + */ +#define XCANFD_IETCS_OFFSET 0x09C /**< Tx Buffer Cancel Request Served + Interrupt Enable Register */ +#define XCANFD_RSD0_OFFSET 0x0A0 /**< Reserved */ +#define XCANFD_RSD1_OFFSET 0x0A4 /**< Reserved */ +#define XCANFD_RSD2_OFFSET 0x0A8 /**< Reserved */ +#define XCANFD_RSD3_OFFSET 0x0AC /**< Reserved */ +/* @} */ + +/** @name Mail box mode registers + * @{ + */ +#define XCANFD_RCS0_OFFSET 0x0B0 /**< Rx Buffer Control Status 0 Register + */ +#define XCANFD_RCS1_OFFSET 0x0B4 /**< Rx Buffer Control Status 1 Register + */ +#define XCANFD_RCS2_OFFSET 0x0B8 /**< Rx Buffer Control Status 2 Register + */ +#define XCANFD_RXBFLL1_OFFSET 0x0C0 /**< Rx Buffer Full Interrupt Enable + Register */ +#define XCANFD_RXBFLL2_OFFSET 0x0C4 /**< Rx Buffer Full Interrupt Enable + Register */ +#define XCANFD_MAILBOX_RB_MASK_BASE_OFFSET 0x1000 /**< Mailbox RxBuffer + Mask Register */ +#define XCANFD_MAILBOX_NXT_RB 4 +/* @} */ + +/** @name TxBuffer Element ID Registers + * Tx Message Buffer Element Start Address - 0x0100 (2304 Bytes) + End Address - 0x09FF +* @{ +*/ +#define XCANFD_DLCR_TIMESTAMP_MASK 0x0000FFFF /**< Dlc Register TimeStamp + Mask */ +#define XCANFD_TXFIFO_0_BASE_ID_OFFSET 0x0100 /**< Tx Message Buffer Element + 0 ID Register */ +#define XCANFD_TXFIFO_1_BASE_ID_OFFSET 0x0148 /**< Tx Message Buffer Element + 1 ID Register */ +#define XCANFD_TXFIFO_2_BASE_ID_OFFSET 0x0190 /**< Tx Message Buffer Element + 2 ID Register */ +#define XCANFD_TXFIFO_3_BASE_ID_OFFSET 0x01d8 /**< Tx Message Buffer Element + 3 ID Register */ +#define XCANFD_TXFIFO_4_BASE_ID_OFFSET 0x0220 /**< Tx Message Buffer Element + 4 ID Register */ +#define XCANFD_TXFIFO_5_BASE_ID_OFFSET 0x0268 /**< Tx Message Buffer Element + 5 ID Register */ +#define XCANFD_TXFIFO_6_BASE_ID_OFFSET 0x02b0 /**< Tx Message Buffer Element + 6 ID Register */ +#define XCANFD_TXFIFO_7_BASE_ID_OFFSET 0x02f8 /**< Tx Message Buffer Element + 7 ID Register */ +#define XCANFD_TXFIFO_8_BASE_ID_OFFSET 0x0340 /**< Tx Message Buffer Element + 8 ID Register */ +#define XCANFD_TXFIFO_9_BASE_ID_OFFSET 0x0388 /**< Tx Message Buffer Element + 9 ID Register */ +#define XCANFD_TXFIFO_10_BASE_ID_OFFSET 0x03d0 /**< Tx Message Buffer Element + 10 ID Register */ +#define XCANFD_TXFIFO_11_BASE_ID_OFFSET 0x0418 /**< Tx Message Buffer Element + 11 ID Register */ +#define XCANFD_TXFIFO_12_BASE_ID_OFFSET 0x0460 /**< Tx Message Buffer Element + 12 ID Register */ +#define XCANFD_TXFIFO_13_BASE_ID_OFFSET 0x04a8 /**< Tx Message Buffer Element + 13 ID Register */ +#define XCANFD_TXFIFO_14_BASE_ID_OFFSET 0x04f0 /**< Tx Message Buffer Element + 14 ID Register */ +#define XCANFD_TXFIFO_15_BASE_ID_OFFSET 0x0538 /**< Tx Message Buffer Element + 15 ID Register */ +#define XCANFD_TXFIFO_16_BASE_ID_OFFSET 0x0580 /**< Tx Message Buffer Element + 16 ID Register */ +#define XCANFD_TXFIFO_17_BASE_ID_OFFSET 0x05c8 /**< Tx Message Buffer Element + 17 ID Register */ +#define XCANFD_TXFIFO_18_BASE_ID_OFFSET 0x0610 /**< Tx Message Buffer Element + 18 ID Register */ +#define XCANFD_TXFIFO_19_BASE_ID_OFFSET 0x0658 /**< Tx Message Buffer Element + 19 ID Register */ +#define XCANFD_TXFIFO_20_BASE_ID_OFFSET 0x06a0 /**< Tx Message Buffer Element + 20 ID Register */ +#define XCANFD_TXFIFO_21_BASE_ID_OFFSET 0x06e8 /**< Tx Message Buffer Element + 21 ID Register */ +#define XCANFD_TXFIFO_22_BASE_ID_OFFSET 0x0730 /**< Tx Message Buffer Element + 22 ID Register */ +#define XCANFD_TXFIFO_23_BASE_ID_OFFSET 0x0778 /**< Tx Message Buffer Element + 23 ID Register */ +#define XCANFD_TXFIFO_24_BASE_ID_OFFSET 0x07c0 /**< Tx Message Buffer Element + 24 ID Register */ +#define XCANFD_TXFIFO_25_BASE_ID_OFFSET 0x0808 /**< Tx Message Buffer Element + 25 ID Register */ +#define XCANFD_TXFIFO_26_BASE_ID_OFFSET 0x0850 /**< Tx Message Buffer Element + 26 ID Register */ +#define XCANFD_TXFIFO_27_BASE_ID_OFFSET 0x0898 /**< Tx Message Buffer Element + 27 ID Register */ +#define XCANFD_TXFIFO_28_BASE_ID_OFFSET 0x08e0 /**< Tx Message Buffer Element + 28 ID Register */ +#define XCANFD_TXFIFO_29_BASE_ID_OFFSET 0x0928 /**< Tx Message Buffer Element + 29 ID Register */ +#define XCANFD_TXFIFO_30_BASE_ID_OFFSET 0x0970 /**< Tx Message Buffer Element + 30 ID Register */ +#define XCANFD_TXFIFO_31_BASE_ID_OFFSET 0x09b8 /**< Tx Message Buffer Element + 31 ID Register */ +/* @} */ + +/** @name TxBuffer Element DLC Registers +* @{ +*/ +#define XCANFD_TXFIFO_0_BASE_DLC_OFFSET 0x0104 /**< Tx Message Buffer Element + 0 DLC Register */ +#define XCANFD_TXFIFO_1_BASE_DLC_OFFSET 0x014c /**< Tx Message Buffer Element + 1 DLC Register */ +#define XCANFD_TXFIFO_2_BASE_DLC_OFFSET 0x0194 /**< Tx Message Buffer Element + 2 DLC Register */ +#define XCANFD_TXFIFO_3_BASE_DLC_OFFSET 0x01dc /**< Tx Message Buffer Element + 3 DLC Register */ +#define XCANFD_TXFIFO_4_BASE_DLC_OFFSET 0x0224 /**< Tx Message Buffer Element + 4 DLC Register */ +#define XCANFD_TXFIFO_5_BASE_DLC_OFFSET 0x026c /**< Tx Message Buffer Element + 5 DLC Register */ +#define XCANFD_TXFIFO_6_BASE_DLC_OFFSET 0x02b4 /**< Tx Message Buffer Element + 6 DLC Register */ +#define XCANFD_TXFIFO_7_BASE_DLC_OFFSET 0x02fc /**< Tx Message Buffer Element + 7 DLC Register */ +#define XCANFD_TXFIFO_8_BASE_DLC_OFFSET 0x0344 /**< Tx Message Buffer Element + 8 DLC Register */ +#define XCANFD_TXFIFO_9_BASE_DLC_OFFSET 0x038c /**< Tx Message Buffer Element + 9 DLC Register */ +#define XCANFD_TXFIFO_10_BASE_DLC_OFFSET 0x03d4 /**< Tx Message Buffer + Element10 DLC + Register */ +#define XCANFD_TXFIFO_11_BASE_DLC_OFFSET 0x041c /**< Tx Message Buffer + Element11 DLC + Register */ +#define XCANFD_TXFIFO_12_BASE_DLC_OFFSET 0x0464 /**< Tx Message Buffer + Element12 DLC + Register */ +#define XCANFD_TXFIFO_13_BASE_DLC_OFFSET 0x04ac /**< Tx Message Buffer + Element13 DLC + Register */ +#define XCANFD_TXFIFO_14_BASE_DLC_OFFSET 0x04f4 /**< Tx Message Buffer + Element14 DLC + Register */ +#define XCANFD_TXFIFO_15_BASE_DLC_OFFSET 0x053c /**< Tx Message Buffer + Element15 DLC + Register */ +#define XCANFD_TXFIFO_16_BASE_DLC_OFFSET 0x0584 /**< Tx Message Buffer + Element16 DLC + Register */ +#define XCANFD_TXFIFO_17_BASE_DLC_OFFSET 0x05cc /**< Tx Message Buffer + Element17 DLC + Register */ +#define XCANFD_TXFIFO_18_BASE_DLC_OFFSET 0x0614 /**< Tx Message Buffer + Element18 DLC + Register */ +#define XCANFD_TXFIFO_19_BASE_DLC_OFFSET 0x065c /**< Tx Message Buffer + Element19 DLC + Register */ +#define XCANFD_TXFIFO_20_BASE_DLC_OFFSET 0x06a4 /**< Tx Message Buffer + Element20 DLC + Register */ +#define XCANFD_TXFIFO_21_BASE_DLC_OFFSET 0x06ec /**< Tx Message Buffer + Element21 DLC + Register */ +#define XCANFD_TXFIFO_22_BASE_DLC_OFFSET 0x0734 /**< Tx Message Buffer + Element22 DLC + Register */ +#define XCANFD_TXFIFO_23_BASE_DLC_OFFSET 0x077c /**< Tx Message Buffer + Element23 DLC + Register */ +#define XCANFD_TXFIFO_24_BASE_DLC_OFFSET 0x07c4 /**< Tx Message Buffer + Element24 DLC + Register */ +#define XCANFD_TXFIFO_25_BASE_DLC_OFFSET 0x080c /**< Tx Message Buffer + Element25 DLC + Register */ +#define XCANFD_TXFIFO_26_BASE_DLC_OFFSET 0x0854 /**< Tx Message Buffer + Element26 DLC + Register */ +#define XCANFD_TXFIFO_27_BASE_DLC_OFFSET 0x089c /**< Tx Message Buffer + Element27 DLC + Register */ +#define XCANFD_TXFIFO_28_BASE_DLC_OFFSET 0x08e4 /**< Tx Message Buffer + Element28 DLC + Register */ +#define XCANFD_TXFIFO_29_BASE_DLC_OFFSET 0x092c /**< Tx Message Buffer + Element29 DLC + Register */ +#define XCANFD_TXFIFO_30_BASE_DLC_OFFSET 0x0974 /**< Tx Message Buffer + Element30 DLC + Register */ +#define XCANFD_TXFIFO_31_BASE_DLC_OFFSET 0x09bc /**< Tx Message Buffer + Element31 DLC + Register */ +/* @} */ + +/** @name TxBuffer Element DW Registers +* @{ +*/ +#define XCANFD_TXFIFO_0_BASE_DW0_OFFSET 0x0108 /**< Tx Message Buffer Element + 0 DW Register */ +#define XCANFD_TXFIFO_1_BASE_DW0_OFFSET 0x0150 /**< Tx Message Buffer Element + 1 DW Register */ +#define XCANFD_TXFIFO_2_BASE_DW0_OFFSET 0x0198 /**< Tx Message Buffer Element + 2 DW Register */ +#define XCANFD_TXFIFO_3_BASE_DW0_OFFSET 0x01e0 /**< Tx Message Buffer Element + 3 DW Register */ +#define XCANFD_TXFIFO_4_BASE_DW0_OFFSET 0x0228 /**< Tx Message Buffer Element + 4 DW Register */ +#define XCANFD_TXFIFO_5_BASE_DW0_OFFSET 0x0270 /**< Tx Message Buffer Element + 5 DW Register */ +#define XCANFD_TXFIFO_6_BASE_DW0_OFFSET 0x02b8 /**< Tx Message Buffer Element + 6 DW Register */ +#define XCANFD_TXFIFO_7_BASE_DW0_OFFSET 0x0300 /**< Tx Message Buffer Element + 7 DW Register */ +#define XCANFD_TXFIFO_8_BASE_DW0_OFFSET 0x0348 /**< Tx Message Buffer Element + 8 DW Register */ +#define XCANFD_TXFIFO_9_BASE_DW0_OFFSET 0x0390 /**< Tx Message Buffer Element + 9 DW Register */ +#define XCANFD_TXFIFO_10_BASE_DW0_OFFSET 0x03d8 /**< Tx Message Buffer + Element 10 DW Register + */ +#define XCANFD_TXFIFO_11_BASE_DW0_OFFSET 0x0420 /**< Tx Message Buffer + Element 11 DW Register + */ +#define XCANFD_TXFIFO_12_BASE_DW0_OFFSET 0x0468 /**< Tx Message Buffer + Element 12 DW Register + */ +#define XCANFD_TXFIFO_13_BASE_DW0_OFFSET 0x04b0 /**< Tx Message Buffer + Element 13 DW Register + */ +#define XCANFD_TXFIFO_14_BASE_DW0_OFFSET 0x04f8 /**< Tx Message Buffer + Element 14 DW Register + */ +#define XCANFD_TXFIFO_15_BASE_DW0_OFFSET 0x0540 /**< Tx Message Buffer + Element 15 DW Register + */ +#define XCANFD_TXFIFO_16_BASE_DW0_OFFSET 0x0588 /**< Tx Message Buffer + Element 16 DW Register + */ +#define XCANFD_TXFIFO_17_BASE_DW0_OFFSET 0x05d0 /**< Tx Message Buffer + Element 17 DW Register + */ +#define XCANFD_TXFIFO_18_BASE_DW0_OFFSET 0x0618 /**< Tx Message Buffer + Element 18 DW Register + */ +#define XCANFD_TXFIFO_19_BASE_DW0_OFFSET 0x0660 /**< Tx Message Buffer + Element 19 DW Register + */ +#define XCANFD_TXFIFO_20_BASE_DW0_OFFSET 0x06a8 /**< Tx Message Buffer + Element 20 DW Register + */ +#define XCANFD_TXFIFO_21_BASE_DW0_OFFSET 0x06f0 /**< Tx Message Buffer + Element 21 DW Register + */ +#define XCANFD_TXFIFO_22_BASE_DW0_OFFSET 0x0738 /**< Tx Message Buffer + Element 22 DW Register + */ +#define XCANFD_TXFIFO_23_BASE_DW0_OFFSET 0x0780 /**< Tx Message Buffer + Element 23 DW Register + */ +#define XCANFD_TXFIFO_24_BASE_DW0_OFFSET 0x07c8 /**< Tx Message Buffer + Element 24 DW Register + */ +#define XCANFD_TXFIFO_25_BASE_DW0_OFFSET 0x0810 /**< Tx Message Buffer + Element 25 DW Register + */ +#define XCANFD_TXFIFO_26_BASE_DW0_OFFSET 0x0858 /**< Tx Message Buffer + Element 26 DW Register + */ +#define XCANFD_TXFIFO_27_BASE_DW0_OFFSET 0x08a0 /**< Tx Message Buffer + Element 27 DW Register + */ +#define XCANFD_TXFIFO_28_BASE_DW0_OFFSET 0x08e8 /**< Tx Message Buffer + Element 28 DW Register + */ +#define XCANFD_TXFIFO_29_BASE_DW0_OFFSET 0x0930 /**< Tx Message Buffer + Element 29 DW Register + */ +#define XCANFD_TXFIFO_30_BASE_DW0_OFFSET 0x0978 /**< Tx Message Buffer + Element 30 DW Register + */ +#define XCANFD_TXFIFO_31_BASE_DW0_OFFSET 0x09c0 /**< Tx Message Buffer + Element 31 DW Register + */ +/* @} */ + +/** @name Rx Message Buffer Element ID Registers. + * Start Address - 0x1100 (2304 Bytes) + End Address - 0x19FF +* @{ +*/ +#define XCANFD_RXFIFO_0_BASE_ID_OFFSET 0x1100 /**< Rx Message Buffer Element + 0 ID Register */ +#define XCANFD_RXFIFO_1_BASE_ID_OFFSET 0x1148 /**< Rx Message Buffer Element + 1 ID Register */ +#define XCANFD_RXFIFO_2_BASE_ID_OFFSET 0x1190 /**< Rx Message Buffer Element + 2 ID Register */ +#define XCANFD_RXFIFO_3_BASE_ID_OFFSET 0x11d8 /**< Rx Message Buffer Element + 3 ID Register */ +#define XCANFD_RXFIFO_4_BASE_ID_OFFSET 0x1220 /**< Rx Message Buffer Element + 4 ID Register */ +#define XCANFD_RXFIFO_5_BASE_ID_OFFSET 0x1268 /**< Rx Message Buffer Element + 5 ID Register */ +#define XCANFD_RXFIFO_6_BASE_ID_OFFSET 0x12b0 /**< Rx Message Buffer Element + 6 ID Register */ +#define XCANFD_RXFIFO_7_BASE_ID_OFFSET 0x12f8 /**< Rx Message Buffer Element + 7 ID Register */ +#define XCANFD_RXFIFO_8_BASE_ID_OFFSET 0x1340 /**< Rx Message Buffer Element + 8 ID Register */ +#define XCANFD_RXFIFO_9_BASE_ID_OFFSET 0x1388 /**< Rx Message Buffer Element + 9 ID Register */ +#define XCANFD_RXFIFO_10_BASE_ID_OFFSET 0x13d0 /**< Rx Message Buffer Element + 10 ID Register */ +#define XCANFD_RXFIFO_11_BASE_ID_OFFSET 0x1418 /**< Rx Message Buffer Element + 11 ID Register */ +#define XCANFD_RXFIFO_12_BASE_ID_OFFSET 0x1460 /**< Rx Message Buffer Element + 12 ID Register */ +#define XCANFD_RXFIFO_13_BASE_ID_OFFSET 0x14a8 /**< Rx Message Buffer Element + 13 ID Register */ +#define XCANFD_RXFIFO_14_BASE_ID_OFFSET 0x14f0 /**< Rx Message Buffer Element + 14 ID Register */ +#define XCANFD_RXFIFO_15_BASE_ID_OFFSET 0x1538 /**< Rx Message Buffer Element + 15 ID Register */ +#define XCANFD_RXFIFO_16_BASE_ID_OFFSET 0x1580 /**< Rx Message Buffer Element + 16 ID Register */ +#define XCANFD_RXFIFO_17_BASE_ID_OFFSET 0x15c8 /**< Rx Message Buffer Element + 17 ID Register */ +#define XCANFD_RXFIFO_18_BASE_ID_OFFSET 0x1610 /**< Rx Message Buffer Element + 18 ID Register */ +#define XCANFD_RXFIFO_19_BASE_ID_OFFSET 0x1658 /**< Rx Message Buffer Element + 19 ID Register */ +#define XCANFD_RXFIFO_20_BASE_ID_OFFSET 0x16a0 /**< Rx Message Buffer Element + 20 ID Register */ +#define XCANFD_RXFIFO_21_BASE_ID_OFFSET 0x16e8 /**< Rx Message Buffer Element + 21 ID Register */ +#define XCANFD_RXFIFO_22_BASE_ID_OFFSET 0x1730 /**< Rx Message Buffer Element + 22 ID Register */ +#define XCANFD_RXFIFO_23_BASE_ID_OFFSET 0x1778 /**< Rx Message Buffer Element + 23 ID Register */ +#define XCANFD_RXFIFO_24_BASE_ID_OFFSET 0x17c0 /**< Rx Message Buffer Element + 24 ID Register */ +#define XCANFD_RXFIFO_25_BASE_ID_OFFSET 0x1808 /**< Rx Message Buffer Element + 25 ID Register */ +#define XCANFD_RXFIFO_26_BASE_ID_OFFSET 0x1850 /**< Rx Message Buffer Element + 26 ID Register */ +#define XCANFD_RXFIFO_27_BASE_ID_OFFSET 0x1898 /**< Rx Message Buffer Element + 27 ID Register */ +#define XCANFD_RXFIFO_28_BASE_ID_OFFSET 0x18e0 /**< Rx Message Buffer Element + 28 ID Register */ +#define XCANFD_RXFIFO_29_BASE_ID_OFFSET 0x1928 /**< Rx Message Buffer Element + 29 ID Register */ +#define XCANFD_RXFIFO_30_BASE_ID_OFFSET 0x1970 /**< Rx Message Buffer Element + 30 ID Register */ +#define XCANFD_RXFIFO_31_BASE_ID_OFFSET 0x19b8 /**< Rx Message Buffer Element + 31 ID Register */ +/* @} */ + +/** @name Rx Message Buffer Element DLC Registers. +* @{ +*/ +#define XCANFD_RXFIFO_0_BASE_DLC_OFFSET 0x1104 /**< Rx Message Buffer Element + 0 DLC Register */ +#define XCANFD_RXFIFO_1_BASE_DLC_OFFSET 0x114c /**< Rx Message Buffer Element + 1 DLC Register */ +#define XCANFD_RXFIFO_2_BASE_DLC_OFFSET 0x1194 /**< Rx Message Buffer Element + 2 DLC Register */ +#define XCANFD_RXFIFO_3_BASE_DLC_OFFSET 0x11dc /**< Rx Message Buffer Element + 3 DLC Register */ +#define XCANFD_RXFIFO_4_BASE_DLC_OFFSET 0x1224 /**< Rx Message Buffer Element + 4 DLC Register */ +#define XCANFD_RXFIFO_5_BASE_DLC_OFFSET 0x126c /**< Rx Message Buffer Element + 5 DLC Register */ +#define XCANFD_RXFIFO_6_BASE_DLC_OFFSET 0x12b4 /**< Rx Message Buffer Element + 6 DLC Register */ +#define XCANFD_RXFIFO_7_BASE_DLC_OFFSET 0x12fc /**< Rx Message Buffer Element + 7 DLC Register */ +#define XCANFD_RXFIFO_8_BASE_DLC_OFFSET 0x1344 /**< Rx Message Buffer Element + 8 DLC Register */ +#define XCANFD_RXFIFO_9_BASE_DLC_OFFSET 0x138c /**< Rx Message Buffer Element + 9 DLC Register */ +#define XCANFD_RXFIFO_10_BASE_DLC_OFFSET 0x13d4 /**< Rx Message Buffer + Element 10 DLC Register + */ +#define XCANFD_RXFIFO_11_BASE_DLC_OFFSET 0x141c /**< Rx Message Buffer + Element 11 DLC Register + */ +#define XCANFD_RXFIFO_12_BASE_DLC_OFFSET 0x1464 /**< Rx Message Buffer + Element 12 DLC Register + */ +#define XCANFD_RXFIFO_13_BASE_DLC_OFFSET 0x14ac /**< Rx Message Buffer + Element 13 DLC Register + */ +#define XCANFD_RXFIFO_14_BASE_DLC_OFFSET 0x14f4 /**< Rx Message Buffer + Element 14 DLC Register + */ +#define XCANFD_RXFIFO_15_BASE_DLC_OFFSET 0x153c /**< Rx Message Buffer + Element 15 DLC Register + */ +#define XCANFD_RXFIFO_16_BASE_DLC_OFFSET 0x1584 /**< Rx Message Buffer + Element 16 DLC Register + */ +#define XCANFD_RXFIFO_17_BASE_DLC_OFFSET 0x15cc /**< Rx Message Buffer + Element 17 DLC Register + */ +#define XCANFD_RXFIFO_18_BASE_DLC_OFFSET 0x1614 /**< Rx Message Buffer + Element 18 DLC Register + */ +#define XCANFD_RXFIFO_19_BASE_DLC_OFFSET 0x165c /**< Rx Message Buffer + Element 19 DLC Register + */ +#define XCANFD_RXFIFO_20_BASE_DLC_OFFSET 0x16a4 /**< Rx Message Buffer + Element 20 DLC Register + */ +#define XCANFD_RXFIFO_21_BASE_DLC_OFFSET 0x16ec /**< Rx Message Buffer + Element 21 DLC Register + */ +#define XCANFD_RXFIFO_22_BASE_DLC_OFFSET 0x1734 /**< Rx Message Buffer + Element 22 DLC Register + */ +#define XCANFD_RXFIFO_23_BASE_DLC_OFFSET 0x177c /**< Rx Message Buffer + Element 23 DLC Register + */ +#define XCANFD_RXFIFO_24_BASE_DLC_OFFSET 0x17c4 /**< Rx Message Buffer + Element 24 DLC Register + */ +#define XCANFD_RXFIFO_25_BASE_DLC_OFFSET 0x180c /**< Rx Message Buffer + Element 25 DLC Register + */ +#define XCANFD_RXFIFO_26_BASE_DLC_OFFSET 0x1854 /**< Rx Message Buffer + Element 26 DLC Register + */ +#define XCANFD_RXFIFO_27_BASE_DLC_OFFSET 0x189c /**< Rx Message Buffer + Element 27 DLC Register + */ +#define XCANFD_RXFIFO_28_BASE_DLC_OFFSET 0x18e4 /**< Rx Message Buffer + Element 28 DLC Register + */ +#define XCANFD_RXFIFO_29_BASE_DLC_OFFSET 0x192c /**< Rx Message Buffer + Element 29 DLC Register + */ +#define XCANFD_RXFIFO_30_BASE_DLC_OFFSET 0x1974 /**< Rx Message Buffer + Element 30 DLC Register + */ +#define XCANFD_RXFIFO_31_BASE_DLC_OFFSET 0x19bc /**< Rx Message Buffer + Element 31 DLC Register + */ +/* @} */ + +/** @name Rx Message Buffer Element DW Registers. +* @{ +*/ +#define XCANFD_RXFIFO_0_BASE_DW0_OFFSET 0x1108 /**< Rx Message Buffer Element + 0 DW Register */ +#define XCANFD_RXFIFO_1_BASE_DW0_OFFSET 0x1150 /**< Rx Message Buffer Element + 1 DW Register */ +#define XCANFD_RXFIFO_2_BASE_DW0_OFFSET 0x1198 /**< Rx Message Buffer Element + 2 DW Register */ +#define XCANFD_RXFIFO_3_BASE_DW0_OFFSET 0x11e0 /**< Rx Message Buffer Element + 3 DW Register */ +#define XCANFD_RXFIFO_4_BASE_DW0_OFFSET 0x1228 /**< Rx Message Buffer Element + 4 DW Register */ +#define XCANFD_RXFIFO_5_BASE_DW0_OFFSET 0x1270 /**< Rx Message Buffer Element + 5 DW Register */ +#define XCANFD_RXFIFO_6_BASE_DW0_OFFSET 0x12b8 /**< Rx Message Buffer Element + 6 DW Register */ +#define XCANFD_RXFIFO_7_BASE_DW0_OFFSET 0x1300 /**< Rx Message Buffer Element + 7 DW Register */ +#define XCANFD_RXFIFO_8_BASE_DW0_OFFSET 0x1348 /**< Rx Message Buffer Element + 8 DW Register */ +#define XCANFD_RXFIFO_9_BASE_DW0_OFFSET 0x1390 /**< Rx Message Buffer Element + 9 DW Register */ +#define XCANFD_RXFIFO_10_BASE_DW0_OFFSET 0x13d8 /**< Rx Message Buffer + Element 10 DW Register + */ +#define XCANFD_RXFIFO_11_BASE_DW0_OFFSET 0x1420 /**< Rx Message Buffer + Element 11 DW Register + */ +#define XCANFD_RXFIFO_12_BASE_DW0_OFFSET 0x1468 /**< Rx Message Buffer + Element 12 DW Register + */ +#define XCANFD_RXFIFO_13_BASE_DW0_OFFSET 0x14b0 /**< Rx Message Buffer + Element 13 DW Register + */ +#define XCANFD_RXFIFO_14_BASE_DW0_OFFSET 0x14f8 /**< Rx Message Buffer + Element 14 DW Register + */ +#define XCANFD_RXFIFO_15_BASE_DW0_OFFSET 0x1540 /**< Rx Message Buffer + Element 15 DW Register + */ +#define XCANFD_RXFIFO_16_BASE_DW0_OFFSET 0x1588 /**< Rx Message Buffer + Element 16 DW Register + */ +#define XCANFD_RXFIFO_17_BASE_DW0_OFFSET 0x15d0 /**< Rx Message Buffer + Element 17 DW Register + */ +#define XCANFD_RXFIFO_18_BASE_DW0_OFFSET 0x1618 /**< Rx Message Buffer + Element 18 DW Register + */ +#define XCANFD_RXFIFO_19_BASE_DW0_OFFSET 0x1660 /**< Rx Message Buffer + Element 19 DW Register + */ +#define XCANFD_RXFIFO_20_BASE_DW0_OFFSET 0x16a8 /**< Rx Message Buffer + Element 20 DW Register + */ +#define XCANFD_RXFIFO_21_BASE_DW0_OFFSET 0x16f0 /**< Rx Message Buffer + Element 21 DW Register + */ +#define XCANFD_RXFIFO_22_BASE_DW0_OFFSET 0x1738 /**< Rx Message Buffer + Element 22 DW Register + */ +#define XCANFD_RXFIFO_23_BASE_DW0_OFFSET 0x1780 /**< Rx Message Buffer + Element 23 DW Register + */ +#define XCANFD_RXFIFO_24_BASE_DW0_OFFSET 0x17c8 /**< Rx Message Buffer + Element 24 DW Register + */ +#define XCANFD_RXFIFO_25_BASE_DW0_OFFSET 0x1810 /**< Rx Message Buffer + Element 25 DW Register + */ +#define XCANFD_RXFIFO_26_BASE_DW0_OFFSET 0x1858 /**< Rx Message Buffer + Element 26 DW Register + */ +#define XCANFD_RXFIFO_27_BASE_DW0_OFFSET 0x18a0 /**< Rx Message Buffer + Element 27 DW Register + */ +#define XCANFD_RXFIFO_28_BASE_DW0_OFFSET 0x18e8 /**< Rx Message Buffer + Element 28 DW Register + */ +#define XCANFD_RXFIFO_29_BASE_DW0_OFFSET 0x1930 /**< Rx Message Buffer + Element 29 DW Register + */ +#define XCANFD_RXFIFO_30_BASE_DW0_OFFSET 0x1978 /**< Rx Message Buffer + Element 30 DW Register + */ +#define XCANFD_RXFIFO_31_BASE_DW0_OFFSET 0x19c0 /**< Rx Message Buffer + Element 31 DW Register + */ +/* @} */ + +/** @name Rx Message Buffer Element ID,DLC,DW Sizes. +* @{ +*/ +#define XCANFD_RXFIFO_NEXTID_OFFSET 72 /**< Rx Message Buffer Element + Next ID AT Offset */ +#define XCANFD_RXFIFO_NEXTDLC_OFFSET 72 /**< Rx Message Buffer Element + Next DLC AT Offset */ +#define XCANFD_RXFIFO_NEXTDW_OFFSET 72 /**< Rx Message Buffer Element + Next DW AT Offset */ +/* @} */ + +/** @name EDL and BRS Masks. +* @{ +*/ +#define XCANFD_DLCR_EDL_MASK 0x08000000 /**< EDL Mask in DLC Register */ +#define XCANFD_DLCR_BRS_MASK 0x04000000 /**< BRS Mask in DLC Register */ +/* @} */ + +/** @name Acceptance Filter Mask Registers + * @{ + */ +#define XCANFD_AFMR_BASE_OFFSET 0x1A00 /** +* MODIFICATION HISTORY: +* +* Ver Who Date Changes +* ----- ---- -------- ------------------------------------------------------ +* 1.00a nsk 06/04/15 First release +* +* +* +*****************************************************************************/ + +/***************************** 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. +*

+* 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; +} diff --git a/XilinxProcessorIPLib/drivers/canfd/src/xcanfd_sinit.c b/XilinxProcessorIPLib/drivers/canfd/src/xcanfd_sinit.c new file mode 100644 index 00000000..8ddb997c --- /dev/null +++ b/XilinxProcessorIPLib/drivers/canfd/src/xcanfd_sinit.c @@ -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. +* +*
+*
+* MODIFICATION HISTORY:
+*
+* Ver   Who    Date	Changes
+* ----- -----  -------- -----------------------------------------------
+* 1.00a nsk    06/03/15 First release
+*
+*
+* 
+* +******************************************************************************/ + +/***************************** 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; +}