1 /******************************************************************************
3 * Copyright (C) 2010 - 2014 Xilinx, Inc. All rights reserved.
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to deal
7 * in the Software without restriction, including without limitation the rights
8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
15 * Use of the Software is limited solely to applications:
16 * (a) running on a Xilinx device, or
17 * (b) that interact with a Xilinx device through a bus or interconnect.
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
24 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27 * Except as contained in this notice, the name of the Xilinx shall not be used
28 * in advertising or otherwise to promote the sale, use or other dealings in
29 * this Software without prior written authorization from Xilinx.
31 ******************************************************************************/
32 /*****************************************************************************/
36 * @addtogroup canps_v2_0
39 * Functions in this file are the minimum required functions for the XCanPs
40 * driver. See xcanps.h for a detailed description of the driver.
46 * MODIFICATION HISTORY:
48 * Ver Who Date Changes
49 * ----- ----- -------- -----------------------------------------------
50 * 1.00a xd/sv 01/12/10 First release
51 * 1.01a bss 12/27/11 Added the APIs XCanPs_SetTxIntrWatermark and
52 * XCanPs_GetTxIntrWatermark.
55 ******************************************************************************/
57 /***************************** Include Files *********************************/
61 /************************** Constant Definitions *****************************/
63 /**************************** Type Definitions *******************************/
65 /***************** Macros (Inline Functions) Definitions *********************/
67 /************************** Variable Definitions *****************************/
69 /************************** Function Prototypes ******************************/
71 static void StubHandler(void);
73 /*****************************************************************************/
76 * This function initializes a XCanPs instance/driver.
78 * The initialization entails:
79 * - Initialize all members of the XCanPs structure.
80 * - Reset the CAN device. The CAN device will enter Configuration Mode
81 * immediately after the reset is finished.
83 * @param InstancePtr is a pointer to the XCanPs instance.
84 * @param ConfigPtr points to the XCanPs device configuration structure.
85 * @param EffectiveAddr is the device base address in the virtual memory
86 * address space. If the address translation is not used then the
87 * physical address is passed.
88 * Unexpected errors may occur if the address mapping is changed
89 * after this function is invoked.
91 * @return XST_SUCCESS always.
95 ******************************************************************************/
96 int XCanPs_CfgInitialize(XCanPs *InstancePtr, XCanPs_Config *ConfigPtr,
100 Xil_AssertNonvoid(InstancePtr != NULL);
101 Xil_AssertNonvoid(ConfigPtr != NULL);
104 * Set some default values for instance data, don't indicate the device
105 * is ready to use until everything has been initialized successfully.
107 InstancePtr->IsReady = 0;
108 InstancePtr->CanConfig.BaseAddr = EffectiveAddr;
109 InstancePtr->CanConfig.DeviceId = ConfigPtr->DeviceId;
112 * Set all handlers to stub values, let user configure this data later.
114 InstancePtr->SendHandler = (XCanPs_SendRecvHandler) StubHandler;
115 InstancePtr->RecvHandler = (XCanPs_SendRecvHandler) StubHandler;
116 InstancePtr->ErrorHandler = (XCanPs_ErrorHandler) StubHandler;
117 InstancePtr->EventHandler = (XCanPs_EventHandler) StubHandler;
120 * Indicate the component is now ready to use.
122 InstancePtr->IsReady = XIL_COMPONENT_IS_READY;
125 * Reset the device to get it into its initial state.
127 XCanPs_Reset(InstancePtr);
132 /*****************************************************************************/
135 * This function resets the CAN device. Calling this function resets the device
136 * immediately, and any pending transmission or reception is terminated at once.
137 * Both Object Layer and Transfer Layer are reset. This function does not reset
138 * the Physical Layer. All registers are reset to the default values, and no
139 * previous status will be restored. TX FIFO, RX FIFO and TX High Priority
140 * Buffer are also reset.
142 * When a reset is required due to an internal error, the driver notifies the
143 * upper layer software of this need through the error status code or interrupts.
144 * The upper layer software is responsible for calling this Reset function and
145 * then re-configuring the device.
147 * The CAN device will be in Configuration Mode immediately after this function
150 * @param InstancePtr is a pointer to the XCanPs instance.
156 ******************************************************************************/
157 void XCanPs_Reset(XCanPs *InstancePtr)
159 Xil_AssertVoid(InstancePtr != NULL);
160 Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
162 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr, XCANPS_SRR_OFFSET, \
163 XCANPS_SRR_SRST_MASK);
166 /****************************************************************************/
169 * This routine returns the current operation mode of the CAN device.
171 * @param InstancePtr is a pointer to the XCanPs instance.
174 * - XCANPS_MODE_CONFIG if the device is in Configuration Mode.
175 * - XCANPS_MODE_SLEEP if the device is in Sleep Mode.
176 * - XCANPS_MODE_NORMAL if the device is in Normal Mode.
177 * - XCANPS_MODE_LOOPBACK if the device is in Loop Back Mode.
178 * - XCANPS_MODE_SNOOP if the device is in Snoop Mode.
182 *****************************************************************************/
183 u8 XCanPs_GetMode(XCanPs *InstancePtr)
187 Xil_AssertNonvoid(InstancePtr != NULL);
188 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
190 StatusReg = XCanPs_GetStatus(InstancePtr);
192 if (StatusReg & XCANPS_SR_CONFIG_MASK) {
193 return XCANPS_MODE_CONFIG;
195 } else if (StatusReg & XCANPS_SR_SLEEP_MASK) {
196 return XCANPS_MODE_SLEEP;
198 } else if (StatusReg & XCANPS_SR_NORMAL_MASK) {
199 if (StatusReg & XCANPS_SR_SNOOP_MASK) {
200 return XCANPS_MODE_SNOOP;
202 return XCANPS_MODE_NORMAL;
206 * If this line is reached, the device is in Loop Back Mode.
208 return XCANPS_MODE_LOOPBACK;
212 /*****************************************************************************/
215 * This function allows the CAN device to enter one of the following operation
217 * - Configuration Mode: Pass in parameter XCANPS_MODE_CONFIG
218 * - Sleep Mode: Pass in parameter XCANPS_MODE_SLEEP
219 * - Normal Mode: Pass in parameter XCANPS_MODE_NORMAL
220 * - Loop Back Mode: Pass in parameter XCANPS_MODE_LOOPBACK.
221 * - Snoop Mode: Pass in parameter XCANPS_MODE_SNOOP.
223 * Read the xcanps.h file and device specification for detailed description of
224 * each operation mode.
226 * @param InstancePtr is a pointer to the XCanPs instance.
227 * @param OperationMode specify which operation mode to enter. Valid value
228 * is any of XCANPS_MODE_* defined in xcanps.h. Multiple modes
229 * can not be entered at the same time.
235 * This function does NOT ensure CAN device enters the specified operation mode
236 * before it returns the control to the caller. The caller is responsible for
237 * checking current operation mode using XCanPs_GetMode().
239 ******************************************************************************/
240 void XCanPs_EnterMode(XCanPs *InstancePtr, u8 OperationMode)
244 Xil_AssertVoid(InstancePtr != NULL);
245 Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
246 Xil_AssertVoid((OperationMode == XCANPS_MODE_CONFIG) ||
247 (OperationMode == XCANPS_MODE_SLEEP) ||
248 (OperationMode == XCANPS_MODE_NORMAL) ||
249 (OperationMode == XCANPS_MODE_LOOPBACK) ||
250 (OperationMode == XCANPS_MODE_SNOOP));
252 CurrentMode = XCanPs_GetMode(InstancePtr);
255 * If current mode is Normal Mode and the mode to enter is Sleep Mode,
256 * or if current mode is Sleep Mode and the mode to enter is Normal
257 * Mode, no transition through Configuration Mode is needed.
259 if ((CurrentMode == XCANPS_MODE_NORMAL) &&
260 (OperationMode == XCANPS_MODE_SLEEP)) {
262 * Normal Mode ---> Sleep Mode
264 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
265 XCANPS_MSR_OFFSET, XCANPS_MSR_SLEEP_MASK);
268 } else if ((CurrentMode == XCANPS_MODE_SLEEP) &&
269 (OperationMode == XCANPS_MODE_NORMAL)) {
271 * Sleep Mode ---> Normal Mode
273 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
274 XCANPS_MSR_OFFSET, 0);
280 * If the mode transition is not any of the two cases above, CAN must
281 * enter Configuration Mode before switching into the target operation
284 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
285 XCANPS_SRR_OFFSET, 0);
288 * Check if the device has entered Configuration Mode, if not, return to
291 if (XCanPs_GetMode(InstancePtr) != XCANPS_MODE_CONFIG) {
295 switch (OperationMode) {
296 case XCANPS_MODE_CONFIG:
298 * As CAN is in Configuration Mode already.
299 * Nothing is needed to be done here.
303 case XCANPS_MODE_SLEEP:
304 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
305 XCANPS_MSR_OFFSET, XCANPS_MSR_SLEEP_MASK);
306 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
307 XCANPS_SRR_OFFSET, XCANPS_SRR_CEN_MASK);
310 case XCANPS_MODE_NORMAL:
311 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
312 XCANPS_MSR_OFFSET, 0);
313 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
314 XCANPS_SRR_OFFSET, XCANPS_SRR_CEN_MASK);
317 case XCANPS_MODE_LOOPBACK:
318 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
319 XCANPS_MSR_OFFSET, XCANPS_MSR_LBACK_MASK);
320 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
321 XCANPS_SRR_OFFSET, XCANPS_SRR_CEN_MASK);
324 case XCANPS_MODE_SNOOP:
325 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
326 XCANPS_MSR_OFFSET, XCANPS_MSR_SNOOP_MASK);
327 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
328 XCANPS_SRR_OFFSET, XCANPS_SRR_CEN_MASK);
334 /*****************************************************************************/
337 * This function returns Status value from Status Register (SR). Use the
338 * XCANPS_SR_* constants defined in xcanps_hw.h to interpret the returned
341 * @param InstancePtr is a pointer to the XCanPs instance.
343 * @return The 32-bit value read from Status Register.
347 ******************************************************************************/
348 u32 XCanPs_GetStatus(XCanPs *InstancePtr)
351 Xil_AssertNonvoid(InstancePtr != NULL);
352 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
354 return XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr,
358 /*****************************************************************************/
361 * This function reads Receive and Transmit error counters.
363 * @param InstancePtr is a pointer to the XCanPs instance.
364 * @param RxErrorCount is a pointer to data in which the Receive Error
365 * counter value is returned.
366 * @param TxErrorCount is a pointer to data in which the Transmit Error
367 * counter value is returned.
373 ******************************************************************************/
374 void XCanPs_GetBusErrorCounter(XCanPs *InstancePtr, u8 *RxErrorCount,
379 Xil_AssertVoid(InstancePtr != NULL);
380 Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
381 Xil_AssertVoid(RxErrorCount != NULL);
382 Xil_AssertVoid(TxErrorCount != NULL);
384 * Read Error Counter Register and parse it.
386 ErrorCount = XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr,
388 *RxErrorCount = (ErrorCount & XCANPS_ECR_REC_MASK) >>
389 XCANPS_ECR_REC_SHIFT;
390 *TxErrorCount = ErrorCount & XCANPS_ECR_TEC_MASK;
393 /*****************************************************************************/
396 * This function reads Error Status value from Error Status Register (ESR). Use
397 * the XCANPS_ESR_* constants defined in xcanps_hw.h to interpret the
400 * @param InstancePtr is a pointer to the XCanPs instance.
402 * @return The 32-bit value read from Error Status Register.
406 ******************************************************************************/
407 u32 XCanPs_GetBusErrorStatus(XCanPs *InstancePtr)
410 Xil_AssertNonvoid(InstancePtr != NULL);
411 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
413 return XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr,
417 /*****************************************************************************/
420 * This function clears Error Status bit(s) previously set in Error
421 * Status Register (ESR). Use the XCANPS_ESR_* constants defined in xcanps_hw.h
422 * to create the value to pass in. If a bit was cleared in Error Status Register
423 * before this function is called, it will not be modified.
425 * @param InstancePtr is a pointer to the XCanPs instance.
427 * @param Mask is he 32-bit mask used to clear bits in Error Status
428 * Register. Multiple XCANPS_ESR_* values can be 'OR'ed to clear
433 ******************************************************************************/
434 void XCanPs_ClearBusErrorStatus(XCanPs *InstancePtr, u32 Mask)
436 Xil_AssertVoid(InstancePtr != NULL);
437 Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
439 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
440 XCANPS_ESR_OFFSET, Mask);
443 /*****************************************************************************/
446 * This function sends a CAN Frame. If the TX FIFO is not full then the given
447 * frame is written into the the TX FIFO otherwise, it returns an error code
449 * This function does not wait for the given frame being sent to CAN bus.
451 * @param InstancePtr is a pointer to the XCanPs instance.
452 * @param FramePtr is a pointer to a 32-bit aligned buffer containing the
453 * CAN frame to be sent.
456 * - XST_SUCCESS if TX FIFO was not full and the given frame was
457 * written into the FIFO.
458 * - XST_FIFO_NO_ROOM if there is no room in the TX FIFO for the
463 ******************************************************************************/
464 int XCanPs_Send(XCanPs *InstancePtr, u32 *FramePtr)
466 Xil_AssertNonvoid(InstancePtr != NULL);
467 Xil_AssertNonvoid(FramePtr != NULL);
468 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
470 if (XCanPs_IsTxFifoFull(InstancePtr) == TRUE) {
471 return XST_FIFO_NO_ROOM;
475 * Write IDR, DLC, Data Word 1 and Data Word 2 to the CAN device.
477 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
478 XCANPS_TXFIFO_ID_OFFSET, FramePtr[0]);
479 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
480 XCANPS_TXFIFO_DLC_OFFSET, FramePtr[1]);
481 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
482 XCANPS_TXFIFO_DW1_OFFSET, FramePtr[2]);
483 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
484 XCANPS_TXFIFO_DW2_OFFSET, FramePtr[3]);
489 /*****************************************************************************/
492 * This function receives a CAN Frame. This function first checks if RX FIFO is
493 * empty, if not, it then reads a frame from the RX FIFO into the given buffer.
494 * This function returns error code immediately if there is no frame in the RX
497 * @param InstancePtr is a pointer to the XCanPs instance.
498 * @param FramePtr is a pointer to a 32-bit aligned buffer where the CAN
499 * frame to be written.
502 * - XST_SUCCESS if RX FIFO was not empty and a frame was read from
503 * RX FIFO successfully and written into the given buffer.
504 * - XST_NO_DATA if there is no frame to be received from the FIFO.
508 ******************************************************************************/
509 int XCanPs_Recv(XCanPs *InstancePtr, u32 *FramePtr)
511 Xil_AssertNonvoid(InstancePtr != NULL);
512 Xil_AssertNonvoid(FramePtr != NULL);
513 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
515 if (XCanPs_IsRxEmpty(InstancePtr) == TRUE) {
520 * Read IDR, DLC, Data Word 1 and Data Word 2 from the CAN device.
522 FramePtr[0] = XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr,
523 XCANPS_RXFIFO_ID_OFFSET);
524 FramePtr[1] = XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr,
525 XCANPS_RXFIFO_DLC_OFFSET);
526 FramePtr[2] = XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr,
527 XCANPS_RXFIFO_DW1_OFFSET);
528 FramePtr[3] = XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr,
529 XCANPS_RXFIFO_DW2_OFFSET);
532 * Clear RXNEMP bit in ISR. This allows future XCanPs_IsRxEmpty() call
533 * returns correct RX FIFO occupancy/empty condition.
535 XCanPs_IntrClear(InstancePtr, XCANPS_IXR_RXNEMP_MASK);
540 /*****************************************************************************/
543 * This routine sends a CAN High Priority frame. This function first checks if
544 * TX High Priority Buffer is empty. If yes, it then writes the given frame into
545 * the Buffer. If not, this function returns immediately. This function does not
546 * wait for the given frame being sent to CAN bus.
548 * @param InstancePtr is a pointer to the XCanPs instance.
549 * @param FramePtr is a pointer to a 32-bit aligned buffer containing the
550 * CAN High Priority frame to be sent.
553 * - XST_SUCCESS if TX High Priority Buffer was not full and the
554 * given frame was written into the buffer;
555 * - XST_FIFO_NO_ROOM if there is no room in the TX High Priority
556 * Buffer for this frame.
560 * If the frame needs to be sent immediately and not delayed by processor's
561 * interrupt handling, the caller should disable interrupt at processor
562 * level before invoking this function.
564 ******************************************************************************/
565 int XCanPs_SendHighPriority(XCanPs *InstancePtr, u32 *FramePtr)
567 Xil_AssertNonvoid(InstancePtr != NULL);
568 Xil_AssertNonvoid(FramePtr != NULL);
569 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
571 if (XCanPs_IsHighPriorityBufFull(InstancePtr) == TRUE) {
572 return XST_FIFO_NO_ROOM;
576 * Write IDR, DLC, Data Word 1 and Data Word 2 to the CAN device.
578 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
579 XCANPS_TXHPB_ID_OFFSET, FramePtr[0]);
580 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
581 XCANPS_TXHPB_DLC_OFFSET, FramePtr[1]);
582 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
583 XCANPS_TXHPB_DW1_OFFSET, FramePtr[2]);
584 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
585 XCANPS_TXHPB_DW2_OFFSET, FramePtr[3]);
590 /*****************************************************************************/
593 * This routine enables individual acceptance filters. Up to 4 filters could
596 * @param InstancePtr is a pointer to the XCanPs instance.
597 * @param FilterIndexes specifies which filter(s) to enable. Use
598 * any XCANPS_AFR_UAF*_MASK to enable one filter, and "Or"
599 * multiple XCANPS_AFR_UAF*_MASK values if multiple filters need
600 * to be enabled. Any filter not specified in this parameter will
601 * keep its previous enable/disable setting.
608 ******************************************************************************/
609 void XCanPs_AcceptFilterEnable(XCanPs *InstancePtr, u32 FilterIndexes)
613 Xil_AssertVoid(InstancePtr != NULL);
614 Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
617 * Calculate the new value and write to AFR.
619 EnabledFilters = XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr,
621 EnabledFilters |= FilterIndexes;
622 EnabledFilters &= XCANPS_AFR_UAF_ALL_MASK;
623 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr, XCANPS_AFR_OFFSET,
627 /*****************************************************************************/
630 * This routine disables individual acceptance filters. Up to 4 filters could
631 * be disabled. If all acceptance filters are disabled then all the received
632 * frames are stored in the RX FIFO.
634 * @param InstancePtr is a pointer to the XCanPs instance.
635 * @param FilterIndexes specifies which filter(s) to disable. Use
636 * any XCANPS_AFR_UAF*_MASK to disable one filter, and "Or"
637 * multiple XCANPS_AFR_UAF*_MASK values if multiple filters need
638 * to be disabled. Any filter not specified in this parameter will
639 * keep its previous enable/disable setting. If all acceptance
640 * filters are disabled then all received frames are stored in the
647 ******************************************************************************/
648 void XCanPs_AcceptFilterDisable(XCanPs *InstancePtr, u32 FilterIndexes)
652 Xil_AssertVoid(InstancePtr != NULL);
653 Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
656 * Calculate the new value and write to AFR.
658 EnabledFilters = XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr,
660 EnabledFilters &= XCANPS_AFR_UAF_ALL_MASK & (~FilterIndexes);
661 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr, XCANPS_AFR_OFFSET,
665 /*****************************************************************************/
668 * This function returns enabled acceptance filters. Use XCANPS_AFR_UAF*_MASK
669 * defined in xcanps_hw.h to interpret the returned value. If no acceptance
670 * filters are enabled then all received frames are stored in the RX FIFO.
672 * @param InstancePtr is a pointer to the XCanPs instance.
674 * @return The value stored in Acceptance Filter Register.
679 ******************************************************************************/
680 u32 XCanPs_AcceptFilterGetEnabled(XCanPs *InstancePtr)
683 Xil_AssertNonvoid(InstancePtr != NULL);
684 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
686 return XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr,
691 /*****************************************************************************/
694 * This function sets values to the Acceptance Filter Mask Register (AFMR) and
695 * Acceptance Filter ID Register (AFIR) for the specified Acceptance Filter.
696 * Use XCANPS_IDR_* defined in xcanps_hw.h to create the values to set the
697 * filter. Read the xcanps.h file and device specification for details.
699 * This function should be called only after:
700 * - The given filter is disabled by calling XCanPs_AcceptFilterDisable();
701 * - And the CAN device is ready to accept writes to AFMR and AFIR, i.e.,
702 * XCanPs_IsAcceptFilterBusy() returns FALSE.
704 * @param InstancePtr is a pointer to the XCanPs instance.
705 * @param FilterIndex defines which Acceptance Filter Mask and ID Register
706 * to set. Use any single XCANPS_AFR_UAF*_MASK value.
707 * @param MaskValue is the value to write to the chosen Acceptance Filter
709 * @param IdValue is the value to write to the chosen Acceptance Filter
713 * - XST_SUCCESS if the values were set successfully.
714 * - XST_FAILURE if the given filter was not disabled, or the CAN
715 * device was not ready to accept writes to AFMR and AFIR.
719 ******************************************************************************/
720 int XCanPs_AcceptFilterSet(XCanPs *InstancePtr, u32 FilterIndex,
721 u32 MaskValue, u32 IdValue)
725 Xil_AssertNonvoid(InstancePtr != NULL);
726 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
727 Xil_AssertNonvoid((FilterIndex == XCANPS_AFR_UAF4_MASK) ||
728 (FilterIndex == XCANPS_AFR_UAF3_MASK) ||
729 (FilterIndex == XCANPS_AFR_UAF2_MASK) ||
730 (FilterIndex == XCANPS_AFR_UAF1_MASK));
733 * Return an error if the given filter is currently enabled.
735 EnabledFilters = XCanPs_AcceptFilterGetEnabled(InstancePtr);
736 if ((EnabledFilters & FilterIndex) == FilterIndex) {
741 * If the CAN device is not ready to accept writes to AFMR and AFIR,
744 if (XCanPs_IsAcceptFilterBusy(InstancePtr) == TRUE) {
749 * Write to the AFMR and AFIR of the specified filter.
751 switch (FilterIndex) {
752 case XCANPS_AFR_UAF1_MASK: /* Acceptance Filter No. 1 */
754 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
755 XCANPS_AFMR1_OFFSET, MaskValue);
756 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
757 XCANPS_AFIR1_OFFSET, IdValue);
760 case XCANPS_AFR_UAF2_MASK: /* Acceptance Filter No. 2 */
761 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
762 XCANPS_AFMR2_OFFSET, MaskValue);
763 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
764 XCANPS_AFIR2_OFFSET, IdValue);
767 case XCANPS_AFR_UAF3_MASK: /* Acceptance Filter No. 3 */
768 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
769 XCANPS_AFMR3_OFFSET, MaskValue);
770 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
771 XCANPS_AFIR3_OFFSET, IdValue);
774 case XCANPS_AFR_UAF4_MASK: /* Acceptance Filter No. 4 */
775 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
776 XCANPS_AFMR4_OFFSET, MaskValue);
777 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
778 XCANPS_AFIR4_OFFSET, IdValue);
785 /*****************************************************************************/
788 * This function reads the values of the Acceptance Filter Mask and ID Register
789 * for the specified Acceptance Filter. Use XCANPS_IDR_* defined in xcanps_hw.h
790 * to interpret the values. Read the xcanps.h file and device specification for
793 * @param InstancePtr is a pointer to the XCanPs instance.
794 * @param FilterIndex defines which Acceptance Filter Mask Register to get
795 * Mask and ID from. Use any single XCANPS_FILTER_* value.
796 * @param MaskValue is a pointer to the data in which the Mask value read
797 * from the chosen Acceptance Filter Mask Register is returned.
798 * @param IdValue is a pointer to the data in which the ID value read
799 * from the chosen Acceptance Filter ID Register is returned.
805 ******************************************************************************/
806 void XCanPs_AcceptFilterGet(XCanPs *InstancePtr, u32 FilterIndex,
807 u32 *MaskValue, u32 *IdValue)
809 Xil_AssertVoid(InstancePtr != NULL);
810 Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
811 Xil_AssertVoid((FilterIndex == XCANPS_AFR_UAF4_MASK) ||
812 (FilterIndex == XCANPS_AFR_UAF3_MASK) ||
813 (FilterIndex == XCANPS_AFR_UAF2_MASK) ||
814 (FilterIndex == XCANPS_AFR_UAF1_MASK));
815 Xil_AssertVoid(MaskValue != NULL);
816 Xil_AssertVoid(IdValue != NULL);
819 * Read from the AFMR and AFIR of the specified filter.
821 switch (FilterIndex) {
822 case XCANPS_AFR_UAF1_MASK: /* Acceptance Filter No. 1 */
823 *MaskValue = XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr,
824 XCANPS_AFMR1_OFFSET);
825 *IdValue = XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr,
826 XCANPS_AFIR1_OFFSET);
829 case XCANPS_AFR_UAF2_MASK: /* Acceptance Filter No. 2 */
830 *MaskValue = XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr,
831 XCANPS_AFMR2_OFFSET);
832 *IdValue = XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr,
833 XCANPS_AFIR2_OFFSET);
836 case XCANPS_AFR_UAF3_MASK: /* Acceptance Filter No. 3 */
837 *MaskValue = XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr,
838 XCANPS_AFMR3_OFFSET);
839 *IdValue = XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr,
840 XCANPS_AFIR3_OFFSET);
843 case XCANPS_AFR_UAF4_MASK: /* Acceptance Filter No. 4 */
844 *MaskValue = XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr,
845 XCANPS_AFMR4_OFFSET);
846 *IdValue = XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr,
847 XCANPS_AFIR4_OFFSET);
852 /*****************************************************************************/
855 * This routine sets Baud Rate Prescaler value. The system clock for the CAN
856 * controller is divided by (Prescaler + 1) to generate the quantum clock
857 * needed for sampling and synchronization. Read the device specification
860 * Baud Rate Prescaler can be set only if the CAN device is in Configuration
861 * Mode. Call XCanPs_EnterMode() to enter Configuration Mode before using this
864 * @param InstancePtr is a pointer to the XCanPs instance.
865 * @param Prescaler is the value to set. Valid values are from 0 to 255.
868 * - XST_SUCCESS if the Baud Rate Prescaler value is set
870 * - XST_FAILURE if CAN device is not in Configuration Mode.
874 ******************************************************************************/
875 int XCanPs_SetBaudRatePrescaler(XCanPs *InstancePtr, u8 Prescaler)
877 Xil_AssertNonvoid(InstancePtr != NULL);
878 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
880 if (XCanPs_GetMode(InstancePtr) != XCANPS_MODE_CONFIG) {
884 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr, XCANPS_BRPR_OFFSET,
890 /*****************************************************************************/
893 * This routine gets Baud Rate Prescaler value. The system clock for the CAN
894 * controller is divided by (Prescaler + 1) to generate the quantum clock
895 * needed for sampling and synchronization. Read the device specification for
898 * @param InstancePtr is a pointer to the XCanPs instance.
900 * @return Current used Baud Rate Prescaler value. The value's range is
905 ******************************************************************************/
906 u8 XCanPs_GetBaudRatePrescaler(XCanPs *InstancePtr)
908 Xil_AssertNonvoid(InstancePtr != NULL);
909 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
911 return (u8) XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr,
916 /*****************************************************************************/
919 * This routine sets Bit time. Time segment 1, Time segment 2 and
920 * Synchronization Jump Width are set in this function. Device specification
921 * requires the values passed into this function be one less than the actual
922 * values of these fields. Read the device specification for details.
924 * Bit time can be set only if the CAN device is in Configuration Mode.
925 * Call XCanPs_EnterMode() to enter Configuration Mode before using this
928 * @param InstancePtr is a pointer to the XCanPs instance.
929 * @param SyncJumpWidth is the Synchronization Jump Width value to set.
930 * Valid values are from 0 to 3.
931 * @param TimeSegment2 is the Time Segment 2 value to set. Valid values
933 * @param TimeSegment1 is the Time Segment 1 value to set. Valid values
937 * - XST_SUCCESS if the Bit time is set successfully.
938 * - XST_FAILURE if CAN device is not in Configuration Mode.
942 ******************************************************************************/
943 int XCanPs_SetBitTiming(XCanPs *InstancePtr, u8 SyncJumpWidth,
944 u8 TimeSegment2, u8 TimeSegment1)
948 Xil_AssertNonvoid(InstancePtr != NULL);
949 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
950 Xil_AssertNonvoid(SyncJumpWidth <= 3);
951 Xil_AssertNonvoid(TimeSegment2 <= 7);
952 Xil_AssertNonvoid(TimeSegment1 <= 15 );
954 if (XCanPs_GetMode(InstancePtr) != XCANPS_MODE_CONFIG) {
958 Value = ((u32) TimeSegment1) & XCANPS_BTR_TS1_MASK;
959 Value |= (((u32) TimeSegment2) << XCANPS_BTR_TS2_SHIFT) &
961 Value |= (((u32) SyncJumpWidth) << XCANPS_BTR_SJW_SHIFT) &
964 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
965 XCANPS_BTR_OFFSET, Value);
970 /*****************************************************************************/
973 * This routine gets Bit time. Time segment 1, Time segment 2 and
974 * Synchronization Jump Width values are read in this function. According to
975 * device specification, the actual value of each of these fields is one
976 * more than the value read. Read the device specification for details.
978 * @param InstancePtr is a pointer to the XCanPs instance.
979 * @param SyncJumpWidth will store the Synchronization Jump Width value
980 * after this function returns. Its value ranges from 0 to 3.
981 * @param TimeSegment2 will store the Time Segment 2 value after this
982 * function returns. Its value ranges from 0 to 7.
983 * @param TimeSegment1 will store the Time Segment 1 value after this
984 * function returns. Its value ranges from 0 to 15.
990 ******************************************************************************/
991 void XCanPs_GetBitTiming(XCanPs *InstancePtr, u8 *SyncJumpWidth,
992 u8 *TimeSegment2, u8 *TimeSegment1)
996 Xil_AssertVoid(InstancePtr != NULL);
997 Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
998 Xil_AssertVoid(SyncJumpWidth != NULL);
999 Xil_AssertVoid(TimeSegment2 != NULL);
1000 Xil_AssertVoid(TimeSegment1 != NULL);
1002 Value = XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr,
1005 *TimeSegment1 = (u8) (Value & XCANPS_BTR_TS1_MASK);
1007 (u8) ((Value & XCANPS_BTR_TS2_MASK) >> XCANPS_BTR_TS2_SHIFT);
1009 (u8) ((Value & XCANPS_BTR_SJW_MASK) >> XCANPS_BTR_SJW_SHIFT);
1013 /****************************************************************************/
1016 * This routine sets the Rx Full threshold in the Watermark Interrupt Register.
1018 * @param InstancePtr is a pointer to the XCanPs instance.
1019 * @param Threshold is the threshold to be set. The valid values are
1023 * - XST_FAILURE - If the CAN device is not in Configuration Mode.
1024 * - XST_SUCCESS - If the Rx Full threshold is set in Watermark
1025 * Interrupt Register.
1027 * @note The threshold can only be set when the CAN device is in the
1028 * configuration mode.
1030 *****************************************************************************/
1031 int XCanPs_SetRxIntrWatermark(XCanPs *InstancePtr, u8 Threshold)
1035 Xil_AssertNonvoid(InstancePtr != NULL);
1036 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
1037 Xil_AssertNonvoid(Threshold <= 63);
1039 if (XCanPs_GetMode(InstancePtr) != XCANPS_MODE_CONFIG)
1042 ThrReg = XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr,
1045 ThrReg &= XCANPS_WIR_EW_MASK;
1046 ThrReg |= ((u32)Threshold & XCANPS_WIR_FW_MASK);
1047 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
1048 XCANPS_WIR_OFFSET, ThrReg);
1053 /****************************************************************************/
1056 * This routine gets the Rx Full threshold from the Watermark Interrupt Register.
1058 * @param InstancePtr is a pointer to the XCanPs instance.
1060 * @return The Rx FIFO full watermark threshold value. The valid values
1065 *****************************************************************************/
1066 u8 XCanPs_GetRxIntrWatermark(XCanPs *InstancePtr)
1069 Xil_AssertNonvoid(InstancePtr != NULL);
1070 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
1073 return (u8) (XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr,
1074 XCANPS_WIR_OFFSET) &
1075 XCANPS_WIR_FW_MASK);
1079 /****************************************************************************/
1082 * This routine sets the Tx Empty Threshold in the Watermark Interrupt Register.
1084 * @param InstancePtr is a pointer to the XCanPs instance.
1085 * @param Threshold is the threshold to be set. The valid values are
1089 * - XST_FAILURE - If the CAN device is not in Configuration Mode.
1090 * - XST_SUCCESS - If the threshold is set in Watermark
1091 * Interrupt Register.
1093 * @note The threshold can only be set when the CAN device is in the
1094 * configuration mode.
1096 *****************************************************************************/
1097 int XCanPs_SetTxIntrWatermark(XCanPs *InstancePtr, u8 Threshold)
1100 Xil_AssertNonvoid(InstancePtr != NULL);
1101 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
1102 Xil_AssertNonvoid(Threshold <= 63);
1104 if (XCanPs_GetMode(InstancePtr) != XCANPS_MODE_CONFIG)
1107 ThrReg = XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr,
1110 ThrReg &= XCANPS_WIR_FW_MASK;
1111 ThrReg |= ((u32)(Threshold << XCANPS_WIR_EW_SHIFT)
1112 & XCANPS_WIR_EW_MASK);
1113 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
1114 XCANPS_WIR_OFFSET, ThrReg);
1119 /****************************************************************************/
1122 * This routine gets the Tx Empty threshold from Watermark Interrupt Register.
1124 * @param InstancePtr is a pointer to the XCanPs instance.
1126 * @return The Tx Empty FIFO threshold value. The valid values are 1 to 63.
1130 *****************************************************************************/
1131 u8 XCanPs_GetTxIntrWatermark(XCanPs *InstancePtr)
1134 Xil_AssertNonvoid(InstancePtr != NULL);
1135 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
1138 return (u8) ((XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr,
1139 XCANPS_WIR_OFFSET) & XCANPS_WIR_EW_MASK) >>
1140 XCANPS_WIR_EW_SHIFT);
1145 /******************************************************************************/
1147 * This routine is a stub for the asynchronous callbacks. The stub is here in
1148 * case the upper layer forgot to set the handler(s). On initialization, all
1149 * handlers are set to this callback. It is considered an error for this handler
1152 ******************************************************************************/
1153 static void StubHandler(void)
1155 Xil_AssertVoidAlways();