1 /******************************************************************************
3 * (c) Copyright 2010-11 Xilinx, Inc. All rights reserved.
5 * This file contains confidential and proprietary information of Xilinx, Inc.
6 * and is protected under U.S. and international copyright and other
7 * intellectual property laws.
10 * This disclaimer is not a license and does not grant any rights to the
11 * materials distributed herewith. Except as otherwise provided in a valid
12 * license issued to you by Xilinx, and to the maximum extent permitted by
13 * applicable law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL
14 * FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS,
15 * IMPLIED, OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF
16 * MERCHANTABILITY, NON-INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE;
17 * and (2) Xilinx shall not be liable (whether in contract or tort, including
18 * negligence, or under any other theory of liability) for any loss or damage
19 * of any kind or nature related to, arising under or in connection with these
20 * materials, including for any direct, or any indirect, special, incidental,
21 * or consequential loss or damage (including loss of data, profits, goodwill,
22 * or any type of loss or damage suffered as a result of any action brought by
23 * a third party) even if such damage or loss was reasonably foreseeable or
24 * Xilinx had been advised of the possibility of the same.
26 * CRITICAL APPLICATIONS
27 * Xilinx products are not designed or intended to be fail-safe, or for use in
28 * any application requiring fail-safe performance, such as life-support or
29 * safety devices or systems, Class III medical devices, nuclear facilities,
30 * applications related to the deployment of airbags, or any other applications
31 * that could lead to death, personal injury, or severe property or
32 * environmental damage (individually and collectively, "Critical
33 * Applications"). Customer assumes the sole risk and liability of any use of
34 * Xilinx products in Critical Applications, subject only to applicable laws
35 * and regulations governing limitations on product liability.
37 * THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE
40 ******************************************************************************/
41 /*****************************************************************************/
46 * Functions in this file are the minimum required functions for the XCanPs
47 * driver. See xcanps.h for a detailed description of the driver.
53 * MODIFICATION HISTORY:
55 * Ver Who Date Changes
56 * ----- ----- -------- -----------------------------------------------
57 * 1.00a xd/sv 01/12/10 First release
58 * 1.01a bss 12/27/11 Added the APIs XCanPs_SetTxIntrWatermark and
59 * XCanPs_GetTxIntrWatermark.
62 ******************************************************************************/
64 /***************************** Include Files *********************************/
68 /************************** Constant Definitions *****************************/
70 /**************************** Type Definitions *******************************/
72 /***************** Macros (Inline Functions) Definitions *********************/
74 /************************** Variable Definitions *****************************/
76 /************************** Function Prototypes ******************************/
78 static void StubHandler(void);
80 /*****************************************************************************/
83 * This function initializes a XCanPs instance/driver.
85 * The initialization entails:
86 * - Initialize all members of the XCanPs structure.
87 * - Reset the CAN device. The CAN device will enter Configuration Mode
88 * immediately after the reset is finished.
90 * @param InstancePtr is a pointer to the XCanPs instance.
91 * @param ConfigPtr points to the XCanPs device configuration structure.
92 * @param EffectiveAddr is the device base address in the virtual memory
93 * address space. If the address translation is not used then the
94 * physical address is passed.
95 * Unexpected errors may occur if the address mapping is changed
96 * after this function is invoked.
98 * @return XST_SUCCESS always.
102 ******************************************************************************/
103 int XCanPs_CfgInitialize(XCanPs *InstancePtr, XCanPs_Config *ConfigPtr,
107 Xil_AssertNonvoid(InstancePtr != NULL);
108 Xil_AssertNonvoid(ConfigPtr != NULL);
111 * Set some default values for instance data, don't indicate the device
112 * is ready to use until everything has been initialized successfully.
114 InstancePtr->IsReady = 0;
115 InstancePtr->CanConfig.BaseAddr = EffectiveAddr;
116 InstancePtr->CanConfig.DeviceId = ConfigPtr->DeviceId;
119 * Set all handlers to stub values, let user configure this data later.
121 InstancePtr->SendHandler = (XCanPs_SendRecvHandler) StubHandler;
122 InstancePtr->RecvHandler = (XCanPs_SendRecvHandler) StubHandler;
123 InstancePtr->ErrorHandler = (XCanPs_ErrorHandler) StubHandler;
124 InstancePtr->EventHandler = (XCanPs_EventHandler) StubHandler;
127 * Indicate the component is now ready to use.
129 InstancePtr->IsReady = XIL_COMPONENT_IS_READY;
132 * Reset the device to get it into its initial state.
134 XCanPs_Reset(InstancePtr);
139 /*****************************************************************************/
142 * This function resets the CAN device. Calling this function resets the device
143 * immediately, and any pending transmission or reception is terminated at once.
144 * Both Object Layer and Transfer Layer are reset. This function does not reset
145 * the Physical Layer. All registers are reset to the default values, and no
146 * previous status will be restored. TX FIFO, RX FIFO and TX High Priority
147 * Buffer are also reset.
149 * When a reset is required due to an internal error, the driver notifies the
150 * upper layer software of this need through the error status code or interrupts.
151 * The upper layer software is responsible for calling this Reset function and
152 * then re-configuring the device.
154 * The CAN device will be in Configuration Mode immediately after this function
157 * @param InstancePtr is a pointer to the XCanPs instance.
163 ******************************************************************************/
164 void XCanPs_Reset(XCanPs *InstancePtr)
166 Xil_AssertVoid(InstancePtr != NULL);
167 Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
169 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr, XCANPS_SRR_OFFSET, \
170 XCANPS_SRR_SRST_MASK);
173 /****************************************************************************/
176 * This routine returns the current operation mode of the CAN device.
178 * @param InstancePtr is a pointer to the XCanPs instance.
181 * - XCANPS_MODE_CONFIG if the device is in Configuration Mode.
182 * - XCANPS_MODE_SLEEP if the device is in Sleep Mode.
183 * - XCANPS_MODE_NORMAL if the device is in Normal Mode.
184 * - XCANPS_MODE_LOOPBACK if the device is in Loop Back Mode.
185 * - XCANPS_MODE_SNOOP if the device is in Snoop Mode.
189 *****************************************************************************/
190 u8 XCanPs_GetMode(XCanPs *InstancePtr)
194 Xil_AssertNonvoid(InstancePtr != NULL);
195 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
197 StatusReg = XCanPs_GetStatus(InstancePtr);
199 if (StatusReg & XCANPS_SR_CONFIG_MASK) {
200 return XCANPS_MODE_CONFIG;
202 } else if (StatusReg & XCANPS_SR_SLEEP_MASK) {
203 return XCANPS_MODE_SLEEP;
205 } else if (StatusReg & XCANPS_SR_NORMAL_MASK) {
206 if (StatusReg & XCANPS_SR_SNOOP_MASK) {
207 return XCANPS_MODE_SNOOP;
209 return XCANPS_MODE_NORMAL;
213 * If this line is reached, the device is in Loop Back Mode.
215 return XCANPS_MODE_LOOPBACK;
219 /*****************************************************************************/
222 * This function allows the CAN device to enter one of the following operation
224 * - Configuration Mode: Pass in parameter XCANPS_MODE_CONFIG
225 * - Sleep Mode: Pass in parameter XCANPS_MODE_SLEEP
226 * - Normal Mode: Pass in parameter XCANPS_MODE_NORMAL
227 * - Loop Back Mode: Pass in parameter XCANPS_MODE_LOOPBACK.
228 * - Snoop Mode: Pass in parameter XCANPS_MODE_SNOOP.
230 * Read the xcanps.h file and device specification for detailed description of
231 * each operation mode.
233 * @param InstancePtr is a pointer to the XCanPs instance.
234 * @param OperationMode specify which operation mode to enter. Valid value
235 * is any of XCANPS_MODE_* defined in xcanps.h. Multiple modes
236 * can not be entered at the same time.
242 * This function does NOT ensure CAN device enters the specified operation mode
243 * before it returns the control to the caller. The caller is responsible for
244 * checking current operation mode using XCanPs_GetMode().
246 ******************************************************************************/
247 void XCanPs_EnterMode(XCanPs *InstancePtr, u8 OperationMode)
251 Xil_AssertVoid(InstancePtr != NULL);
252 Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
253 Xil_AssertVoid((OperationMode == XCANPS_MODE_CONFIG) ||
254 (OperationMode == XCANPS_MODE_SLEEP) ||
255 (OperationMode == XCANPS_MODE_NORMAL) ||
256 (OperationMode == XCANPS_MODE_LOOPBACK) ||
257 (OperationMode == XCANPS_MODE_SNOOP));
259 CurrentMode = XCanPs_GetMode(InstancePtr);
262 * If current mode is Normal Mode and the mode to enter is Sleep Mode,
263 * or if current mode is Sleep Mode and the mode to enter is Normal
264 * Mode, no transition through Configuration Mode is needed.
266 if ((CurrentMode == XCANPS_MODE_NORMAL) &&
267 (OperationMode == XCANPS_MODE_SLEEP)) {
269 * Normal Mode ---> Sleep Mode
271 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
272 XCANPS_MSR_OFFSET, XCANPS_MSR_SLEEP_MASK);
275 } else if ((CurrentMode == XCANPS_MODE_SLEEP) &&
276 (OperationMode == XCANPS_MODE_NORMAL)) {
278 * Sleep Mode ---> Normal Mode
280 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
281 XCANPS_MSR_OFFSET, 0);
287 * If the mode transition is not any of the two cases above, CAN must
288 * enter Configuration Mode before switching into the target operation
291 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
292 XCANPS_SRR_OFFSET, 0);
295 * Check if the device has entered Configuration Mode, if not, return to
298 if (XCanPs_GetMode(InstancePtr) != XCANPS_MODE_CONFIG) {
302 switch (OperationMode) {
303 case XCANPS_MODE_CONFIG:
305 * As CAN is in Configuration Mode already.
306 * Nothing is needed to be done here.
310 case XCANPS_MODE_SLEEP:
311 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
312 XCANPS_MSR_OFFSET, XCANPS_MSR_SLEEP_MASK);
313 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
314 XCANPS_SRR_OFFSET, XCANPS_SRR_CEN_MASK);
317 case XCANPS_MODE_NORMAL:
318 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
319 XCANPS_MSR_OFFSET, 0);
320 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
321 XCANPS_SRR_OFFSET, XCANPS_SRR_CEN_MASK);
324 case XCANPS_MODE_LOOPBACK:
325 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
326 XCANPS_MSR_OFFSET, XCANPS_MSR_LBACK_MASK);
327 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
328 XCANPS_SRR_OFFSET, XCANPS_SRR_CEN_MASK);
331 case XCANPS_MODE_SNOOP:
332 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
333 XCANPS_MSR_OFFSET, XCANPS_MSR_SNOOP_MASK);
334 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
335 XCANPS_SRR_OFFSET, XCANPS_SRR_CEN_MASK);
341 /*****************************************************************************/
344 * This function returns Status value from Status Register (SR). Use the
345 * XCANPS_SR_* constants defined in xcanps_hw.h to interpret the returned
348 * @param InstancePtr is a pointer to the XCanPs instance.
350 * @return The 32-bit value read from Status Register.
354 ******************************************************************************/
355 u32 XCanPs_GetStatus(XCanPs *InstancePtr)
358 Xil_AssertNonvoid(InstancePtr != NULL);
359 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
361 return XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr,
365 /*****************************************************************************/
368 * This function reads Receive and Transmit error counters.
370 * @param InstancePtr is a pointer to the XCanPs instance.
371 * @param RxErrorCount is a pointer to data in which the Receive Error
372 * counter value is returned.
373 * @param TxErrorCount is a pointer to data in which the Transmit Error
374 * counter value is returned.
380 ******************************************************************************/
381 void XCanPs_GetBusErrorCounter(XCanPs *InstancePtr, u8 *RxErrorCount,
386 Xil_AssertVoid(InstancePtr != NULL);
387 Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
388 Xil_AssertVoid(RxErrorCount != NULL);
389 Xil_AssertVoid(TxErrorCount != NULL);
391 * Read Error Counter Register and parse it.
393 ErrorCount = XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr,
395 *RxErrorCount = (ErrorCount & XCANPS_ECR_REC_MASK) >>
396 XCANPS_ECR_REC_SHIFT;
397 *TxErrorCount = ErrorCount & XCANPS_ECR_TEC_MASK;
400 /*****************************************************************************/
403 * This function reads Error Status value from Error Status Register (ESR). Use
404 * the XCANPS_ESR_* constants defined in xcanps_hw.h to interpret the
407 * @param InstancePtr is a pointer to the XCanPs instance.
409 * @return The 32-bit value read from Error Status Register.
413 ******************************************************************************/
414 u32 XCanPs_GetBusErrorStatus(XCanPs *InstancePtr)
417 Xil_AssertNonvoid(InstancePtr != NULL);
418 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
420 return XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr,
424 /*****************************************************************************/
427 * This function clears Error Status bit(s) previously set in Error
428 * Status Register (ESR). Use the XCANPS_ESR_* constants defined in xcanps_hw.h
429 * to create the value to pass in. If a bit was cleared in Error Status Register
430 * before this function is called, it will not be modified.
432 * @param InstancePtr is a pointer to the XCanPs instance.
434 * @param Mask is he 32-bit mask used to clear bits in Error Status
435 * Register. Multiple XCANPS_ESR_* values can be 'OR'ed to clear
440 ******************************************************************************/
441 void XCanPs_ClearBusErrorStatus(XCanPs *InstancePtr, u32 Mask)
443 Xil_AssertVoid(InstancePtr != NULL);
444 Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
446 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
447 XCANPS_ESR_OFFSET, Mask);
450 /*****************************************************************************/
453 * This function sends a CAN Frame. If the TX FIFO is not full then the given
454 * frame is written into the the TX FIFO otherwise, it returns an error code
456 * This function does not wait for the given frame being sent to CAN bus.
458 * @param InstancePtr is a pointer to the XCanPs instance.
459 * @param FramePtr is a pointer to a 32-bit aligned buffer containing the
460 * CAN frame to be sent.
463 * - XST_SUCCESS if TX FIFO was not full and the given frame was
464 * written into the FIFO.
465 * - XST_FIFO_NO_ROOM if there is no room in the TX FIFO for the
470 ******************************************************************************/
471 int XCanPs_Send(XCanPs *InstancePtr, u32 *FramePtr)
473 Xil_AssertNonvoid(InstancePtr != NULL);
474 Xil_AssertNonvoid(FramePtr != NULL);
475 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
477 if (XCanPs_IsTxFifoFull(InstancePtr) == TRUE) {
478 return XST_FIFO_NO_ROOM;
482 * Write IDR, DLC, Data Word 1 and Data Word 2 to the CAN device.
484 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
485 XCANPS_TXFIFO_ID_OFFSET, FramePtr[0]);
486 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
487 XCANPS_TXFIFO_DLC_OFFSET, FramePtr[1]);
488 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
489 XCANPS_TXFIFO_DW1_OFFSET, FramePtr[2]);
490 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
491 XCANPS_TXFIFO_DW2_OFFSET, FramePtr[3]);
496 /*****************************************************************************/
499 * This function receives a CAN Frame. This function first checks if RX FIFO is
500 * empty, if not, it then reads a frame from the RX FIFO into the given buffer.
501 * This function returns error code immediately if there is no frame in the RX
504 * @param InstancePtr is a pointer to the XCanPs instance.
505 * @param FramePtr is a pointer to a 32-bit aligned buffer where the CAN
506 * frame to be written.
509 * - XST_SUCCESS if RX FIFO was not empty and a frame was read from
510 * RX FIFO successfully and written into the given buffer.
511 * - XST_NO_DATA if there is no frame to be received from the FIFO.
515 ******************************************************************************/
516 int XCanPs_Recv(XCanPs *InstancePtr, u32 *FramePtr)
518 Xil_AssertNonvoid(InstancePtr != NULL);
519 Xil_AssertNonvoid(FramePtr != NULL);
520 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
522 if (XCanPs_IsRxEmpty(InstancePtr) == TRUE) {
527 * Read IDR, DLC, Data Word 1 and Data Word 2 from the CAN device.
529 FramePtr[0] = XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr,
530 XCANPS_RXFIFO_ID_OFFSET);
531 FramePtr[1] = XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr,
532 XCANPS_RXFIFO_DLC_OFFSET);
533 FramePtr[2] = XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr,
534 XCANPS_RXFIFO_DW1_OFFSET);
535 FramePtr[3] = XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr,
536 XCANPS_RXFIFO_DW2_OFFSET);
539 * Clear RXNEMP bit in ISR. This allows future XCanPs_IsRxEmpty() call
540 * returns correct RX FIFO occupancy/empty condition.
542 XCanPs_IntrClear(InstancePtr, XCANPS_IXR_RXNEMP_MASK);
547 /*****************************************************************************/
550 * This routine sends a CAN High Priority frame. This function first checks if
551 * TX High Priority Buffer is empty. If yes, it then writes the given frame into
552 * the Buffer. If not, this function returns immediately. This function does not
553 * wait for the given frame being sent to CAN bus.
555 * @param InstancePtr is a pointer to the XCanPs instance.
556 * @param FramePtr is a pointer to a 32-bit aligned buffer containing the
557 * CAN High Priority frame to be sent.
560 * - XST_SUCCESS if TX High Priority Buffer was not full and the
561 * given frame was written into the buffer;
562 * - XST_FIFO_NO_ROOM if there is no room in the TX High Priority
563 * Buffer for this frame.
567 * If the frame needs to be sent immediately and not delayed by processor's
568 * interrupt handling, the caller should disable interrupt at processor
569 * level before invoking this function.
571 ******************************************************************************/
572 int XCanPs_SendHighPriority(XCanPs *InstancePtr, u32 *FramePtr)
574 Xil_AssertNonvoid(InstancePtr != NULL);
575 Xil_AssertNonvoid(FramePtr != NULL);
576 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
578 if (XCanPs_IsHighPriorityBufFull(InstancePtr) == TRUE) {
579 return XST_FIFO_NO_ROOM;
583 * Write IDR, DLC, Data Word 1 and Data Word 2 to the CAN device.
585 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
586 XCANPS_TXHPB_ID_OFFSET, FramePtr[0]);
587 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
588 XCANPS_TXHPB_DLC_OFFSET, FramePtr[1]);
589 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
590 XCANPS_TXHPB_DW1_OFFSET, FramePtr[2]);
591 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
592 XCANPS_TXHPB_DW2_OFFSET, FramePtr[3]);
597 /*****************************************************************************/
600 * This routine enables individual acceptance filters. Up to 4 filters could
603 * @param InstancePtr is a pointer to the XCanPs instance.
604 * @param FilterIndexes specifies which filter(s) to enable. Use
605 * any XCANPS_AFR_UAF*_MASK to enable one filter, and "Or"
606 * multiple XCANPS_AFR_UAF*_MASK values if multiple filters need
607 * to be enabled. Any filter not specified in this parameter will
608 * keep its previous enable/disable setting.
615 ******************************************************************************/
616 void XCanPs_AcceptFilterEnable(XCanPs *InstancePtr, u32 FilterIndexes)
620 Xil_AssertVoid(InstancePtr != NULL);
621 Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
624 * Calculate the new value and write to AFR.
626 EnabledFilters = XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr,
628 EnabledFilters |= FilterIndexes;
629 EnabledFilters &= XCANPS_AFR_UAF_ALL_MASK;
630 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr, XCANPS_AFR_OFFSET,
634 /*****************************************************************************/
637 * This routine disables individual acceptance filters. Up to 4 filters could
638 * be disabled. If all acceptance filters are disabled then all the received
639 * frames are stored in the RX FIFO.
641 * @param InstancePtr is a pointer to the XCanPs instance.
642 * @param FilterIndexes specifies which filter(s) to disable. Use
643 * any XCANPS_AFR_UAF*_MASK to disable one filter, and "Or"
644 * multiple XCANPS_AFR_UAF*_MASK values if multiple filters need
645 * to be disabled. Any filter not specified in this parameter will
646 * keep its previous enable/disable setting. If all acceptance
647 * filters are disabled then all received frames are stored in the
654 ******************************************************************************/
655 void XCanPs_AcceptFilterDisable(XCanPs *InstancePtr, u32 FilterIndexes)
659 Xil_AssertVoid(InstancePtr != NULL);
660 Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
663 * Calculate the new value and write to AFR.
665 EnabledFilters = XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr,
667 EnabledFilters &= XCANPS_AFR_UAF_ALL_MASK & (~FilterIndexes);
668 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr, XCANPS_AFR_OFFSET,
672 /*****************************************************************************/
675 * This function returns enabled acceptance filters. Use XCANPS_AFR_UAF*_MASK
676 * defined in xcanps_hw.h to interpret the returned value. If no acceptance
677 * filters are enabled then all received frames are stored in the RX FIFO.
679 * @param InstancePtr is a pointer to the XCanPs instance.
681 * @return The value stored in Acceptance Filter Register.
686 ******************************************************************************/
687 u32 XCanPs_AcceptFilterGetEnabled(XCanPs *InstancePtr)
690 Xil_AssertNonvoid(InstancePtr != NULL);
691 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
693 return XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr,
698 /*****************************************************************************/
701 * This function sets values to the Acceptance Filter Mask Register (AFMR) and
702 * Acceptance Filter ID Register (AFIR) for the specified Acceptance Filter.
703 * Use XCANPS_IDR_* defined in xcanps_hw.h to create the values to set the
704 * filter. Read the xcanps.h file and device specification for details.
706 * This function should be called only after:
707 * - The given filter is disabled by calling XCanPs_AcceptFilterDisable();
708 * - And the CAN device is ready to accept writes to AFMR and AFIR, i.e.,
709 * XCanPs_IsAcceptFilterBusy() returns FALSE.
711 * @param InstancePtr is a pointer to the XCanPs instance.
712 * @param FilterIndex defines which Acceptance Filter Mask and ID Register
713 * to set. Use any single XCANPS_AFR_UAF*_MASK value.
714 * @param MaskValue is the value to write to the chosen Acceptance Filter
716 * @param IdValue is the value to write to the chosen Acceptance Filter
720 * - XST_SUCCESS if the values were set successfully.
721 * - XST_FAILURE if the given filter was not disabled, or the CAN
722 * device was not ready to accept writes to AFMR and AFIR.
726 ******************************************************************************/
727 int XCanPs_AcceptFilterSet(XCanPs *InstancePtr, u32 FilterIndex,
728 u32 MaskValue, u32 IdValue)
732 Xil_AssertNonvoid(InstancePtr != NULL);
733 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
734 Xil_AssertNonvoid((FilterIndex == XCANPS_AFR_UAF4_MASK) ||
735 (FilterIndex == XCANPS_AFR_UAF3_MASK) ||
736 (FilterIndex == XCANPS_AFR_UAF2_MASK) ||
737 (FilterIndex == XCANPS_AFR_UAF1_MASK));
740 * Return an error if the given filter is currently enabled.
742 EnabledFilters = XCanPs_AcceptFilterGetEnabled(InstancePtr);
743 if ((EnabledFilters & FilterIndex) == FilterIndex) {
748 * If the CAN device is not ready to accept writes to AFMR and AFIR,
751 if (XCanPs_IsAcceptFilterBusy(InstancePtr) == TRUE) {
756 * Write to the AFMR and AFIR of the specified filter.
758 switch (FilterIndex) {
759 case XCANPS_AFR_UAF1_MASK: /* Acceptance Filter No. 1 */
761 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
762 XCANPS_AFMR1_OFFSET, MaskValue);
763 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
764 XCANPS_AFIR1_OFFSET, IdValue);
767 case XCANPS_AFR_UAF2_MASK: /* Acceptance Filter No. 2 */
768 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
769 XCANPS_AFMR2_OFFSET, MaskValue);
770 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
771 XCANPS_AFIR2_OFFSET, IdValue);
774 case XCANPS_AFR_UAF3_MASK: /* Acceptance Filter No. 3 */
775 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
776 XCANPS_AFMR3_OFFSET, MaskValue);
777 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
778 XCANPS_AFIR3_OFFSET, IdValue);
781 case XCANPS_AFR_UAF4_MASK: /* Acceptance Filter No. 4 */
782 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
783 XCANPS_AFMR4_OFFSET, MaskValue);
784 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
785 XCANPS_AFIR4_OFFSET, IdValue);
792 /*****************************************************************************/
795 * This function reads the values of the Acceptance Filter Mask and ID Register
796 * for the specified Acceptance Filter. Use XCANPS_IDR_* defined in xcanps_hw.h
797 * to interpret the values. Read the xcanps.h file and device specification for
800 * @param InstancePtr is a pointer to the XCanPs instance.
801 * @param FilterIndex defines which Acceptance Filter Mask Register to get
802 * Mask and ID from. Use any single XCANPS_FILTER_* value.
803 * @param MaskValue is a pointer to the data in which the Mask value read
804 * from the chosen Acceptance Filter Mask Register is returned.
805 * @param IdValue is a pointer to the data in which the ID value read
806 * from the chosen Acceptance Filter ID Register is returned.
812 ******************************************************************************/
813 void XCanPs_AcceptFilterGet(XCanPs *InstancePtr, u32 FilterIndex,
814 u32 *MaskValue, u32 *IdValue)
816 Xil_AssertVoid(InstancePtr != NULL);
817 Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
818 Xil_AssertVoid((FilterIndex == XCANPS_AFR_UAF4_MASK) ||
819 (FilterIndex == XCANPS_AFR_UAF3_MASK) ||
820 (FilterIndex == XCANPS_AFR_UAF2_MASK) ||
821 (FilterIndex == XCANPS_AFR_UAF1_MASK));
822 Xil_AssertVoid(MaskValue != NULL);
823 Xil_AssertVoid(IdValue != NULL);
826 * Read from the AFMR and AFIR of the specified filter.
828 switch (FilterIndex) {
829 case XCANPS_AFR_UAF1_MASK: /* Acceptance Filter No. 1 */
830 *MaskValue = XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr,
831 XCANPS_AFMR1_OFFSET);
832 *IdValue = XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr,
833 XCANPS_AFIR1_OFFSET);
836 case XCANPS_AFR_UAF2_MASK: /* Acceptance Filter No. 2 */
837 *MaskValue = XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr,
838 XCANPS_AFMR2_OFFSET);
839 *IdValue = XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr,
840 XCANPS_AFIR2_OFFSET);
843 case XCANPS_AFR_UAF3_MASK: /* Acceptance Filter No. 3 */
844 *MaskValue = XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr,
845 XCANPS_AFMR3_OFFSET);
846 *IdValue = XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr,
847 XCANPS_AFIR3_OFFSET);
850 case XCANPS_AFR_UAF4_MASK: /* Acceptance Filter No. 4 */
851 *MaskValue = XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr,
852 XCANPS_AFMR4_OFFSET);
853 *IdValue = XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr,
854 XCANPS_AFIR4_OFFSET);
859 /*****************************************************************************/
862 * This routine sets Baud Rate Prescaler value. The system clock for the CAN
863 * controller is divided by (Prescaler + 1) to generate the quantum clock
864 * needed for sampling and synchronization. Read the device specification
867 * Baud Rate Prescaler can be set only if the CAN device is in Configuration
868 * Mode. Call XCanPs_EnterMode() to enter Configuration Mode before using this
871 * @param InstancePtr is a pointer to the XCanPs instance.
872 * @param Prescaler is the value to set. Valid values are from 0 to 255.
875 * - XST_SUCCESS if the Baud Rate Prescaler value is set
877 * - XST_FAILURE if CAN device is not in Configuration Mode.
881 ******************************************************************************/
882 int XCanPs_SetBaudRatePrescaler(XCanPs *InstancePtr, u8 Prescaler)
884 Xil_AssertNonvoid(InstancePtr != NULL);
885 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
887 if (XCanPs_GetMode(InstancePtr) != XCANPS_MODE_CONFIG) {
891 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr, XCANPS_BRPR_OFFSET,
897 /*****************************************************************************/
900 * This routine gets Baud Rate Prescaler value. The system clock for the CAN
901 * controller is divided by (Prescaler + 1) to generate the quantum clock
902 * needed for sampling and synchronization. Read the device specification for
905 * @param InstancePtr is a pointer to the XCanPs instance.
907 * @return Current used Baud Rate Prescaler value. The value's range is
912 ******************************************************************************/
913 u8 XCanPs_GetBaudRatePrescaler(XCanPs *InstancePtr)
915 Xil_AssertNonvoid(InstancePtr != NULL);
916 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
918 return (u8) XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr,
923 /*****************************************************************************/
926 * This routine sets Bit time. Time segment 1, Time segment 2 and
927 * Synchronization Jump Width are set in this function. Device specification
928 * requires the values passed into this function be one less than the actual
929 * values of these fields. Read the device specification for details.
931 * Bit time can be set only if the CAN device is in Configuration Mode.
932 * Call XCanPs_EnterMode() to enter Configuration Mode before using this
935 * @param InstancePtr is a pointer to the XCanPs instance.
936 * @param SyncJumpWidth is the Synchronization Jump Width value to set.
937 * Valid values are from 0 to 3.
938 * @param TimeSegment2 is the Time Segment 2 value to set. Valid values
940 * @param TimeSegment1 is the Time Segment 1 value to set. Valid values
944 * - XST_SUCCESS if the Bit time is set successfully.
945 * - XST_FAILURE if CAN device is not in Configuration Mode.
949 ******************************************************************************/
950 int XCanPs_SetBitTiming(XCanPs *InstancePtr, u8 SyncJumpWidth,
951 u8 TimeSegment2, u8 TimeSegment1)
955 Xil_AssertNonvoid(InstancePtr != NULL);
956 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
957 Xil_AssertNonvoid(SyncJumpWidth <= 3);
958 Xil_AssertNonvoid(TimeSegment2 <= 7);
959 Xil_AssertNonvoid(TimeSegment1 <= 15 );
961 if (XCanPs_GetMode(InstancePtr) != XCANPS_MODE_CONFIG) {
965 Value = ((u32) TimeSegment1) & XCANPS_BTR_TS1_MASK;
966 Value |= (((u32) TimeSegment2) << XCANPS_BTR_TS2_SHIFT) &
968 Value |= (((u32) SyncJumpWidth) << XCANPS_BTR_SJW_SHIFT) &
971 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
972 XCANPS_BTR_OFFSET, Value);
977 /*****************************************************************************/
980 * This routine gets Bit time. Time segment 1, Time segment 2 and
981 * Synchronization Jump Width values are read in this function. According to
982 * device specification, the actual value of each of these fields is one
983 * more than the value read. Read the device specification for details.
985 * @param InstancePtr is a pointer to the XCanPs instance.
986 * @param SyncJumpWidth will store the Synchronization Jump Width value
987 * after this function returns. Its value ranges from 0 to 3.
988 * @param TimeSegment2 will store the Time Segment 2 value after this
989 * function returns. Its value ranges from 0 to 7.
990 * @param TimeSegment1 will store the Time Segment 1 value after this
991 * function returns. Its value ranges from 0 to 15.
997 ******************************************************************************/
998 void XCanPs_GetBitTiming(XCanPs *InstancePtr, u8 *SyncJumpWidth,
999 u8 *TimeSegment2, u8 *TimeSegment1)
1003 Xil_AssertVoid(InstancePtr != NULL);
1004 Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
1005 Xil_AssertVoid(SyncJumpWidth != NULL);
1006 Xil_AssertVoid(TimeSegment2 != NULL);
1007 Xil_AssertVoid(TimeSegment1 != NULL);
1009 Value = XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr,
1012 *TimeSegment1 = (u8) (Value & XCANPS_BTR_TS1_MASK);
1014 (u8) ((Value & XCANPS_BTR_TS2_MASK) >> XCANPS_BTR_TS2_SHIFT);
1016 (u8) ((Value & XCANPS_BTR_SJW_MASK) >> XCANPS_BTR_SJW_SHIFT);
1020 /****************************************************************************/
1023 * This routine sets the Rx Full threshold in the Watermark Interrupt Register.
1025 * @param InstancePtr is a pointer to the XCanPs instance.
1026 * @param Threshold is the threshold to be set. The valid values are
1030 * - XST_FAILURE - If the CAN device is not in Configuration Mode.
1031 * - XST_SUCCESS - If the Rx Full threshold is set in Watermark
1032 * Interrupt Register.
1034 * @note The threshold can only be set when the CAN device is in the
1035 * configuration mode.
1037 *****************************************************************************/
1038 int XCanPs_SetRxIntrWatermark(XCanPs *InstancePtr, u8 Threshold)
1042 Xil_AssertNonvoid(InstancePtr != NULL);
1043 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
1044 Xil_AssertNonvoid(Threshold <= 63);
1046 if (XCanPs_GetMode(InstancePtr) != XCANPS_MODE_CONFIG)
1049 ThrReg = XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr,
1052 ThrReg &= XCANPS_WIR_EW_MASK;
1053 ThrReg |= ((u32)Threshold & XCANPS_WIR_FW_MASK);
1054 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
1055 XCANPS_WIR_OFFSET, ThrReg);
1060 /****************************************************************************/
1063 * This routine gets the Rx Full threshold from the Watermark Interrupt Register.
1065 * @param InstancePtr is a pointer to the XCanPs instance.
1067 * @return The Rx FIFO full watermark threshold value. The valid values
1072 *****************************************************************************/
1073 u8 XCanPs_GetRxIntrWatermark(XCanPs *InstancePtr)
1076 Xil_AssertNonvoid(InstancePtr != NULL);
1077 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
1080 return (u8) (XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr,
1081 XCANPS_WIR_OFFSET) &
1082 XCANPS_WIR_FW_MASK);
1086 /****************************************************************************/
1089 * This routine sets the Tx Empty Threshold in the Watermark Interrupt Register.
1091 * @param InstancePtr is a pointer to the XCanPs instance.
1092 * @param Threshold is the threshold to be set. The valid values are
1096 * - XST_FAILURE - If the CAN device is not in Configuration Mode.
1097 * - XST_SUCCESS - If the threshold is set in Watermark
1098 * Interrupt Register.
1100 * @note The threshold can only be set when the CAN device is in the
1101 * configuration mode.
1103 *****************************************************************************/
1104 int XCanPs_SetTxIntrWatermark(XCanPs *InstancePtr, u8 Threshold)
1107 Xil_AssertNonvoid(InstancePtr != NULL);
1108 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
1109 Xil_AssertNonvoid(Threshold <= 63);
1111 if (XCanPs_GetMode(InstancePtr) != XCANPS_MODE_CONFIG)
1114 ThrReg = XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr,
1117 ThrReg &= XCANPS_WIR_FW_MASK;
1118 ThrReg |= ((u32)(Threshold << XCANPS_WIR_EW_SHIFT)
1119 & XCANPS_WIR_EW_MASK);
1120 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
1121 XCANPS_WIR_OFFSET, ThrReg);
1126 /****************************************************************************/
1129 * This routine gets the Tx Empty threshold from Watermark Interrupt Register.
1131 * @param InstancePtr is a pointer to the XCanPs instance.
1133 * @return The Tx Empty FIFO threshold value. The valid values are 1 to 63.
1137 *****************************************************************************/
1138 u8 XCanPs_GetTxIntrWatermark(XCanPs *InstancePtr)
1141 Xil_AssertNonvoid(InstancePtr != NULL);
1142 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
1145 return (u8) ((XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr,
1146 XCANPS_WIR_OFFSET) & XCANPS_WIR_EW_MASK) >>
1147 XCANPS_WIR_EW_SHIFT);
1152 /******************************************************************************/
1154 * This routine is a stub for the asynchronous callbacks. The stub is here in
1155 * case the upper layer forgot to set the handler(s). On initialization, all
1156 * handlers are set to this callback. It is considered an error for this handler
1159 ******************************************************************************/
1160 static void StubHandler(void)
1162 Xil_AssertVoidAlways();