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 /*****************************************************************************/
37 * Functions in this file are the minimum required functions for the XCanPs
38 * driver. See xcanps.h for a detailed description of the driver.
44 * MODIFICATION HISTORY:
46 * Ver Who Date Changes
47 * ----- ----- -------- -----------------------------------------------
48 * 1.00a xd/sv 01/12/10 First release
49 * 1.01a bss 12/27/11 Added the APIs XCanPs_SetTxIntrWatermark and
50 * XCanPs_GetTxIntrWatermark.
53 ******************************************************************************/
55 /***************************** Include Files *********************************/
59 /************************** Constant Definitions *****************************/
61 /**************************** Type Definitions *******************************/
63 /***************** Macros (Inline Functions) Definitions *********************/
65 /************************** Variable Definitions *****************************/
67 /************************** Function Prototypes ******************************/
69 static void StubHandler(void);
71 /*****************************************************************************/
74 * This function initializes a XCanPs instance/driver.
76 * The initialization entails:
77 * - Initialize all members of the XCanPs structure.
78 * - Reset the CAN device. The CAN device will enter Configuration Mode
79 * immediately after the reset is finished.
81 * @param InstancePtr is a pointer to the XCanPs instance.
82 * @param ConfigPtr points to the XCanPs device configuration structure.
83 * @param EffectiveAddr is the device base address in the virtual memory
84 * address space. If the address translation is not used then the
85 * physical address is passed.
86 * Unexpected errors may occur if the address mapping is changed
87 * after this function is invoked.
89 * @return XST_SUCCESS always.
93 ******************************************************************************/
94 int XCanPs_CfgInitialize(XCanPs *InstancePtr, XCanPs_Config *ConfigPtr,
98 Xil_AssertNonvoid(InstancePtr != NULL);
99 Xil_AssertNonvoid(ConfigPtr != NULL);
102 * Set some default values for instance data, don't indicate the device
103 * is ready to use until everything has been initialized successfully.
105 InstancePtr->IsReady = 0;
106 InstancePtr->CanConfig.BaseAddr = EffectiveAddr;
107 InstancePtr->CanConfig.DeviceId = ConfigPtr->DeviceId;
110 * Set all handlers to stub values, let user configure this data later.
112 InstancePtr->SendHandler = (XCanPs_SendRecvHandler) StubHandler;
113 InstancePtr->RecvHandler = (XCanPs_SendRecvHandler) StubHandler;
114 InstancePtr->ErrorHandler = (XCanPs_ErrorHandler) StubHandler;
115 InstancePtr->EventHandler = (XCanPs_EventHandler) StubHandler;
118 * Indicate the component is now ready to use.
120 InstancePtr->IsReady = XIL_COMPONENT_IS_READY;
123 * Reset the device to get it into its initial state.
125 XCanPs_Reset(InstancePtr);
130 /*****************************************************************************/
133 * This function resets the CAN device. Calling this function resets the device
134 * immediately, and any pending transmission or reception is terminated at once.
135 * Both Object Layer and Transfer Layer are reset. This function does not reset
136 * the Physical Layer. All registers are reset to the default values, and no
137 * previous status will be restored. TX FIFO, RX FIFO and TX High Priority
138 * Buffer are also reset.
140 * When a reset is required due to an internal error, the driver notifies the
141 * upper layer software of this need through the error status code or interrupts.
142 * The upper layer software is responsible for calling this Reset function and
143 * then re-configuring the device.
145 * The CAN device will be in Configuration Mode immediately after this function
148 * @param InstancePtr is a pointer to the XCanPs instance.
154 ******************************************************************************/
155 void XCanPs_Reset(XCanPs *InstancePtr)
157 Xil_AssertVoid(InstancePtr != NULL);
158 Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
160 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr, XCANPS_SRR_OFFSET, \
161 XCANPS_SRR_SRST_MASK);
164 /****************************************************************************/
167 * This routine returns the current operation mode of the CAN device.
169 * @param InstancePtr is a pointer to the XCanPs instance.
172 * - XCANPS_MODE_CONFIG if the device is in Configuration Mode.
173 * - XCANPS_MODE_SLEEP if the device is in Sleep Mode.
174 * - XCANPS_MODE_NORMAL if the device is in Normal Mode.
175 * - XCANPS_MODE_LOOPBACK if the device is in Loop Back Mode.
176 * - XCANPS_MODE_SNOOP if the device is in Snoop Mode.
180 *****************************************************************************/
181 u8 XCanPs_GetMode(XCanPs *InstancePtr)
185 Xil_AssertNonvoid(InstancePtr != NULL);
186 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
188 StatusReg = XCanPs_GetStatus(InstancePtr);
190 if (StatusReg & XCANPS_SR_CONFIG_MASK) {
191 return XCANPS_MODE_CONFIG;
193 } else if (StatusReg & XCANPS_SR_SLEEP_MASK) {
194 return XCANPS_MODE_SLEEP;
196 } else if (StatusReg & XCANPS_SR_NORMAL_MASK) {
197 if (StatusReg & XCANPS_SR_SNOOP_MASK) {
198 return XCANPS_MODE_SNOOP;
200 return XCANPS_MODE_NORMAL;
204 * If this line is reached, the device is in Loop Back Mode.
206 return XCANPS_MODE_LOOPBACK;
210 /*****************************************************************************/
213 * This function allows the CAN device to enter one of the following operation
215 * - Configuration Mode: Pass in parameter XCANPS_MODE_CONFIG
216 * - Sleep Mode: Pass in parameter XCANPS_MODE_SLEEP
217 * - Normal Mode: Pass in parameter XCANPS_MODE_NORMAL
218 * - Loop Back Mode: Pass in parameter XCANPS_MODE_LOOPBACK.
219 * - Snoop Mode: Pass in parameter XCANPS_MODE_SNOOP.
221 * Read the xcanps.h file and device specification for detailed description of
222 * each operation mode.
224 * @param InstancePtr is a pointer to the XCanPs instance.
225 * @param OperationMode specify which operation mode to enter. Valid value
226 * is any of XCANPS_MODE_* defined in xcanps.h. Multiple modes
227 * can not be entered at the same time.
233 * This function does NOT ensure CAN device enters the specified operation mode
234 * before it returns the control to the caller. The caller is responsible for
235 * checking current operation mode using XCanPs_GetMode().
237 ******************************************************************************/
238 void XCanPs_EnterMode(XCanPs *InstancePtr, u8 OperationMode)
242 Xil_AssertVoid(InstancePtr != NULL);
243 Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
244 Xil_AssertVoid((OperationMode == XCANPS_MODE_CONFIG) ||
245 (OperationMode == XCANPS_MODE_SLEEP) ||
246 (OperationMode == XCANPS_MODE_NORMAL) ||
247 (OperationMode == XCANPS_MODE_LOOPBACK) ||
248 (OperationMode == XCANPS_MODE_SNOOP));
250 CurrentMode = XCanPs_GetMode(InstancePtr);
253 * If current mode is Normal Mode and the mode to enter is Sleep Mode,
254 * or if current mode is Sleep Mode and the mode to enter is Normal
255 * Mode, no transition through Configuration Mode is needed.
257 if ((CurrentMode == XCANPS_MODE_NORMAL) &&
258 (OperationMode == XCANPS_MODE_SLEEP)) {
260 * Normal Mode ---> Sleep Mode
262 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
263 XCANPS_MSR_OFFSET, XCANPS_MSR_SLEEP_MASK);
266 } else if ((CurrentMode == XCANPS_MODE_SLEEP) &&
267 (OperationMode == XCANPS_MODE_NORMAL)) {
269 * Sleep Mode ---> Normal Mode
271 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
272 XCANPS_MSR_OFFSET, 0);
278 * If the mode transition is not any of the two cases above, CAN must
279 * enter Configuration Mode before switching into the target operation
282 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
283 XCANPS_SRR_OFFSET, 0);
286 * Check if the device has entered Configuration Mode, if not, return to
289 if (XCanPs_GetMode(InstancePtr) != XCANPS_MODE_CONFIG) {
293 switch (OperationMode) {
294 case XCANPS_MODE_CONFIG:
296 * As CAN is in Configuration Mode already.
297 * Nothing is needed to be done here.
301 case XCANPS_MODE_SLEEP:
302 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
303 XCANPS_MSR_OFFSET, XCANPS_MSR_SLEEP_MASK);
304 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
305 XCANPS_SRR_OFFSET, XCANPS_SRR_CEN_MASK);
308 case XCANPS_MODE_NORMAL:
309 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
310 XCANPS_MSR_OFFSET, 0);
311 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
312 XCANPS_SRR_OFFSET, XCANPS_SRR_CEN_MASK);
315 case XCANPS_MODE_LOOPBACK:
316 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
317 XCANPS_MSR_OFFSET, XCANPS_MSR_LBACK_MASK);
318 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
319 XCANPS_SRR_OFFSET, XCANPS_SRR_CEN_MASK);
322 case XCANPS_MODE_SNOOP:
323 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
324 XCANPS_MSR_OFFSET, XCANPS_MSR_SNOOP_MASK);
325 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
326 XCANPS_SRR_OFFSET, XCANPS_SRR_CEN_MASK);
332 /*****************************************************************************/
335 * This function returns Status value from Status Register (SR). Use the
336 * XCANPS_SR_* constants defined in xcanps_hw.h to interpret the returned
339 * @param InstancePtr is a pointer to the XCanPs instance.
341 * @return The 32-bit value read from Status Register.
345 ******************************************************************************/
346 u32 XCanPs_GetStatus(XCanPs *InstancePtr)
349 Xil_AssertNonvoid(InstancePtr != NULL);
350 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
352 return XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr,
356 /*****************************************************************************/
359 * This function reads Receive and Transmit error counters.
361 * @param InstancePtr is a pointer to the XCanPs instance.
362 * @param RxErrorCount is a pointer to data in which the Receive Error
363 * counter value is returned.
364 * @param TxErrorCount is a pointer to data in which the Transmit Error
365 * counter value is returned.
371 ******************************************************************************/
372 void XCanPs_GetBusErrorCounter(XCanPs *InstancePtr, u8 *RxErrorCount,
377 Xil_AssertVoid(InstancePtr != NULL);
378 Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
379 Xil_AssertVoid(RxErrorCount != NULL);
380 Xil_AssertVoid(TxErrorCount != NULL);
382 * Read Error Counter Register and parse it.
384 ErrorCount = XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr,
386 *RxErrorCount = (ErrorCount & XCANPS_ECR_REC_MASK) >>
387 XCANPS_ECR_REC_SHIFT;
388 *TxErrorCount = ErrorCount & XCANPS_ECR_TEC_MASK;
391 /*****************************************************************************/
394 * This function reads Error Status value from Error Status Register (ESR). Use
395 * the XCANPS_ESR_* constants defined in xcanps_hw.h to interpret the
398 * @param InstancePtr is a pointer to the XCanPs instance.
400 * @return The 32-bit value read from Error Status Register.
404 ******************************************************************************/
405 u32 XCanPs_GetBusErrorStatus(XCanPs *InstancePtr)
408 Xil_AssertNonvoid(InstancePtr != NULL);
409 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
411 return XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr,
415 /*****************************************************************************/
418 * This function clears Error Status bit(s) previously set in Error
419 * Status Register (ESR). Use the XCANPS_ESR_* constants defined in xcanps_hw.h
420 * to create the value to pass in. If a bit was cleared in Error Status Register
421 * before this function is called, it will not be modified.
423 * @param InstancePtr is a pointer to the XCanPs instance.
425 * @param Mask is he 32-bit mask used to clear bits in Error Status
426 * Register. Multiple XCANPS_ESR_* values can be 'OR'ed to clear
431 ******************************************************************************/
432 void XCanPs_ClearBusErrorStatus(XCanPs *InstancePtr, u32 Mask)
434 Xil_AssertVoid(InstancePtr != NULL);
435 Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
437 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
438 XCANPS_ESR_OFFSET, Mask);
441 /*****************************************************************************/
444 * This function sends a CAN Frame. If the TX FIFO is not full then the given
445 * frame is written into the the TX FIFO otherwise, it returns an error code
447 * This function does not wait for the given frame being sent to CAN bus.
449 * @param InstancePtr is a pointer to the XCanPs instance.
450 * @param FramePtr is a pointer to a 32-bit aligned buffer containing the
451 * CAN frame to be sent.
454 * - XST_SUCCESS if TX FIFO was not full and the given frame was
455 * written into the FIFO.
456 * - XST_FIFO_NO_ROOM if there is no room in the TX FIFO for the
461 ******************************************************************************/
462 int XCanPs_Send(XCanPs *InstancePtr, u32 *FramePtr)
464 Xil_AssertNonvoid(InstancePtr != NULL);
465 Xil_AssertNonvoid(FramePtr != NULL);
466 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
468 if (XCanPs_IsTxFifoFull(InstancePtr) == TRUE) {
469 return XST_FIFO_NO_ROOM;
473 * Write IDR, DLC, Data Word 1 and Data Word 2 to the CAN device.
475 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
476 XCANPS_TXFIFO_ID_OFFSET, FramePtr[0]);
477 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
478 XCANPS_TXFIFO_DLC_OFFSET, FramePtr[1]);
479 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
480 XCANPS_TXFIFO_DW1_OFFSET, FramePtr[2]);
481 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
482 XCANPS_TXFIFO_DW2_OFFSET, FramePtr[3]);
487 /*****************************************************************************/
490 * This function receives a CAN Frame. This function first checks if RX FIFO is
491 * empty, if not, it then reads a frame from the RX FIFO into the given buffer.
492 * This function returns error code immediately if there is no frame in the RX
495 * @param InstancePtr is a pointer to the XCanPs instance.
496 * @param FramePtr is a pointer to a 32-bit aligned buffer where the CAN
497 * frame to be written.
500 * - XST_SUCCESS if RX FIFO was not empty and a frame was read from
501 * RX FIFO successfully and written into the given buffer.
502 * - XST_NO_DATA if there is no frame to be received from the FIFO.
506 ******************************************************************************/
507 int XCanPs_Recv(XCanPs *InstancePtr, u32 *FramePtr)
509 Xil_AssertNonvoid(InstancePtr != NULL);
510 Xil_AssertNonvoid(FramePtr != NULL);
511 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
513 if (XCanPs_IsRxEmpty(InstancePtr) == TRUE) {
518 * Read IDR, DLC, Data Word 1 and Data Word 2 from the CAN device.
520 FramePtr[0] = XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr,
521 XCANPS_RXFIFO_ID_OFFSET);
522 FramePtr[1] = XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr,
523 XCANPS_RXFIFO_DLC_OFFSET);
524 FramePtr[2] = XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr,
525 XCANPS_RXFIFO_DW1_OFFSET);
526 FramePtr[3] = XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr,
527 XCANPS_RXFIFO_DW2_OFFSET);
530 * Clear RXNEMP bit in ISR. This allows future XCanPs_IsRxEmpty() call
531 * returns correct RX FIFO occupancy/empty condition.
533 XCanPs_IntrClear(InstancePtr, XCANPS_IXR_RXNEMP_MASK);
538 /*****************************************************************************/
541 * This routine sends a CAN High Priority frame. This function first checks if
542 * TX High Priority Buffer is empty. If yes, it then writes the given frame into
543 * the Buffer. If not, this function returns immediately. This function does not
544 * wait for the given frame being sent to CAN bus.
546 * @param InstancePtr is a pointer to the XCanPs instance.
547 * @param FramePtr is a pointer to a 32-bit aligned buffer containing the
548 * CAN High Priority frame to be sent.
551 * - XST_SUCCESS if TX High Priority Buffer was not full and the
552 * given frame was written into the buffer;
553 * - XST_FIFO_NO_ROOM if there is no room in the TX High Priority
554 * Buffer for this frame.
558 * If the frame needs to be sent immediately and not delayed by processor's
559 * interrupt handling, the caller should disable interrupt at processor
560 * level before invoking this function.
562 ******************************************************************************/
563 int XCanPs_SendHighPriority(XCanPs *InstancePtr, u32 *FramePtr)
565 Xil_AssertNonvoid(InstancePtr != NULL);
566 Xil_AssertNonvoid(FramePtr != NULL);
567 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
569 if (XCanPs_IsHighPriorityBufFull(InstancePtr) == TRUE) {
570 return XST_FIFO_NO_ROOM;
574 * Write IDR, DLC, Data Word 1 and Data Word 2 to the CAN device.
576 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
577 XCANPS_TXHPB_ID_OFFSET, FramePtr[0]);
578 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
579 XCANPS_TXHPB_DLC_OFFSET, FramePtr[1]);
580 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
581 XCANPS_TXHPB_DW1_OFFSET, FramePtr[2]);
582 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
583 XCANPS_TXHPB_DW2_OFFSET, FramePtr[3]);
588 /*****************************************************************************/
591 * This routine enables individual acceptance filters. Up to 4 filters could
594 * @param InstancePtr is a pointer to the XCanPs instance.
595 * @param FilterIndexes specifies which filter(s) to enable. Use
596 * any XCANPS_AFR_UAF*_MASK to enable one filter, and "Or"
597 * multiple XCANPS_AFR_UAF*_MASK values if multiple filters need
598 * to be enabled. Any filter not specified in this parameter will
599 * keep its previous enable/disable setting.
606 ******************************************************************************/
607 void XCanPs_AcceptFilterEnable(XCanPs *InstancePtr, u32 FilterIndexes)
611 Xil_AssertVoid(InstancePtr != NULL);
612 Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
615 * Calculate the new value and write to AFR.
617 EnabledFilters = XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr,
619 EnabledFilters |= FilterIndexes;
620 EnabledFilters &= XCANPS_AFR_UAF_ALL_MASK;
621 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr, XCANPS_AFR_OFFSET,
625 /*****************************************************************************/
628 * This routine disables individual acceptance filters. Up to 4 filters could
629 * be disabled. If all acceptance filters are disabled then all the received
630 * frames are stored in the RX FIFO.
632 * @param InstancePtr is a pointer to the XCanPs instance.
633 * @param FilterIndexes specifies which filter(s) to disable. Use
634 * any XCANPS_AFR_UAF*_MASK to disable one filter, and "Or"
635 * multiple XCANPS_AFR_UAF*_MASK values if multiple filters need
636 * to be disabled. Any filter not specified in this parameter will
637 * keep its previous enable/disable setting. If all acceptance
638 * filters are disabled then all received frames are stored in the
645 ******************************************************************************/
646 void XCanPs_AcceptFilterDisable(XCanPs *InstancePtr, u32 FilterIndexes)
650 Xil_AssertVoid(InstancePtr != NULL);
651 Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
654 * Calculate the new value and write to AFR.
656 EnabledFilters = XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr,
658 EnabledFilters &= XCANPS_AFR_UAF_ALL_MASK & (~FilterIndexes);
659 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr, XCANPS_AFR_OFFSET,
663 /*****************************************************************************/
666 * This function returns enabled acceptance filters. Use XCANPS_AFR_UAF*_MASK
667 * defined in xcanps_hw.h to interpret the returned value. If no acceptance
668 * filters are enabled then all received frames are stored in the RX FIFO.
670 * @param InstancePtr is a pointer to the XCanPs instance.
672 * @return The value stored in Acceptance Filter Register.
677 ******************************************************************************/
678 u32 XCanPs_AcceptFilterGetEnabled(XCanPs *InstancePtr)
681 Xil_AssertNonvoid(InstancePtr != NULL);
682 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
684 return XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr,
689 /*****************************************************************************/
692 * This function sets values to the Acceptance Filter Mask Register (AFMR) and
693 * Acceptance Filter ID Register (AFIR) for the specified Acceptance Filter.
694 * Use XCANPS_IDR_* defined in xcanps_hw.h to create the values to set the
695 * filter. Read the xcanps.h file and device specification for details.
697 * This function should be called only after:
698 * - The given filter is disabled by calling XCanPs_AcceptFilterDisable();
699 * - And the CAN device is ready to accept writes to AFMR and AFIR, i.e.,
700 * XCanPs_IsAcceptFilterBusy() returns FALSE.
702 * @param InstancePtr is a pointer to the XCanPs instance.
703 * @param FilterIndex defines which Acceptance Filter Mask and ID Register
704 * to set. Use any single XCANPS_AFR_UAF*_MASK value.
705 * @param MaskValue is the value to write to the chosen Acceptance Filter
707 * @param IdValue is the value to write to the chosen Acceptance Filter
711 * - XST_SUCCESS if the values were set successfully.
712 * - XST_FAILURE if the given filter was not disabled, or the CAN
713 * device was not ready to accept writes to AFMR and AFIR.
717 ******************************************************************************/
718 int XCanPs_AcceptFilterSet(XCanPs *InstancePtr, u32 FilterIndex,
719 u32 MaskValue, u32 IdValue)
723 Xil_AssertNonvoid(InstancePtr != NULL);
724 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
725 Xil_AssertNonvoid((FilterIndex == XCANPS_AFR_UAF4_MASK) ||
726 (FilterIndex == XCANPS_AFR_UAF3_MASK) ||
727 (FilterIndex == XCANPS_AFR_UAF2_MASK) ||
728 (FilterIndex == XCANPS_AFR_UAF1_MASK));
731 * Return an error if the given filter is currently enabled.
733 EnabledFilters = XCanPs_AcceptFilterGetEnabled(InstancePtr);
734 if ((EnabledFilters & FilterIndex) == FilterIndex) {
739 * If the CAN device is not ready to accept writes to AFMR and AFIR,
742 if (XCanPs_IsAcceptFilterBusy(InstancePtr) == TRUE) {
747 * Write to the AFMR and AFIR of the specified filter.
749 switch (FilterIndex) {
750 case XCANPS_AFR_UAF1_MASK: /* Acceptance Filter No. 1 */
752 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
753 XCANPS_AFMR1_OFFSET, MaskValue);
754 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
755 XCANPS_AFIR1_OFFSET, IdValue);
758 case XCANPS_AFR_UAF2_MASK: /* Acceptance Filter No. 2 */
759 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
760 XCANPS_AFMR2_OFFSET, MaskValue);
761 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
762 XCANPS_AFIR2_OFFSET, IdValue);
765 case XCANPS_AFR_UAF3_MASK: /* Acceptance Filter No. 3 */
766 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
767 XCANPS_AFMR3_OFFSET, MaskValue);
768 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
769 XCANPS_AFIR3_OFFSET, IdValue);
772 case XCANPS_AFR_UAF4_MASK: /* Acceptance Filter No. 4 */
773 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
774 XCANPS_AFMR4_OFFSET, MaskValue);
775 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
776 XCANPS_AFIR4_OFFSET, IdValue);
783 /*****************************************************************************/
786 * This function reads the values of the Acceptance Filter Mask and ID Register
787 * for the specified Acceptance Filter. Use XCANPS_IDR_* defined in xcanps_hw.h
788 * to interpret the values. Read the xcanps.h file and device specification for
791 * @param InstancePtr is a pointer to the XCanPs instance.
792 * @param FilterIndex defines which Acceptance Filter Mask Register to get
793 * Mask and ID from. Use any single XCANPS_FILTER_* value.
794 * @param MaskValue is a pointer to the data in which the Mask value read
795 * from the chosen Acceptance Filter Mask Register is returned.
796 * @param IdValue is a pointer to the data in which the ID value read
797 * from the chosen Acceptance Filter ID Register is returned.
803 ******************************************************************************/
804 void XCanPs_AcceptFilterGet(XCanPs *InstancePtr, u32 FilterIndex,
805 u32 *MaskValue, u32 *IdValue)
807 Xil_AssertVoid(InstancePtr != NULL);
808 Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
809 Xil_AssertVoid((FilterIndex == XCANPS_AFR_UAF4_MASK) ||
810 (FilterIndex == XCANPS_AFR_UAF3_MASK) ||
811 (FilterIndex == XCANPS_AFR_UAF2_MASK) ||
812 (FilterIndex == XCANPS_AFR_UAF1_MASK));
813 Xil_AssertVoid(MaskValue != NULL);
814 Xil_AssertVoid(IdValue != NULL);
817 * Read from the AFMR and AFIR of the specified filter.
819 switch (FilterIndex) {
820 case XCANPS_AFR_UAF1_MASK: /* Acceptance Filter No. 1 */
821 *MaskValue = XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr,
822 XCANPS_AFMR1_OFFSET);
823 *IdValue = XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr,
824 XCANPS_AFIR1_OFFSET);
827 case XCANPS_AFR_UAF2_MASK: /* Acceptance Filter No. 2 */
828 *MaskValue = XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr,
829 XCANPS_AFMR2_OFFSET);
830 *IdValue = XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr,
831 XCANPS_AFIR2_OFFSET);
834 case XCANPS_AFR_UAF3_MASK: /* Acceptance Filter No. 3 */
835 *MaskValue = XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr,
836 XCANPS_AFMR3_OFFSET);
837 *IdValue = XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr,
838 XCANPS_AFIR3_OFFSET);
841 case XCANPS_AFR_UAF4_MASK: /* Acceptance Filter No. 4 */
842 *MaskValue = XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr,
843 XCANPS_AFMR4_OFFSET);
844 *IdValue = XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr,
845 XCANPS_AFIR4_OFFSET);
850 /*****************************************************************************/
853 * This routine sets Baud Rate Prescaler value. The system clock for the CAN
854 * controller is divided by (Prescaler + 1) to generate the quantum clock
855 * needed for sampling and synchronization. Read the device specification
858 * Baud Rate Prescaler can be set only if the CAN device is in Configuration
859 * Mode. Call XCanPs_EnterMode() to enter Configuration Mode before using this
862 * @param InstancePtr is a pointer to the XCanPs instance.
863 * @param Prescaler is the value to set. Valid values are from 0 to 255.
866 * - XST_SUCCESS if the Baud Rate Prescaler value is set
868 * - XST_FAILURE if CAN device is not in Configuration Mode.
872 ******************************************************************************/
873 int XCanPs_SetBaudRatePrescaler(XCanPs *InstancePtr, u8 Prescaler)
875 Xil_AssertNonvoid(InstancePtr != NULL);
876 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
878 if (XCanPs_GetMode(InstancePtr) != XCANPS_MODE_CONFIG) {
882 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr, XCANPS_BRPR_OFFSET,
888 /*****************************************************************************/
891 * This routine gets Baud Rate Prescaler value. The system clock for the CAN
892 * controller is divided by (Prescaler + 1) to generate the quantum clock
893 * needed for sampling and synchronization. Read the device specification for
896 * @param InstancePtr is a pointer to the XCanPs instance.
898 * @return Current used Baud Rate Prescaler value. The value's range is
903 ******************************************************************************/
904 u8 XCanPs_GetBaudRatePrescaler(XCanPs *InstancePtr)
906 Xil_AssertNonvoid(InstancePtr != NULL);
907 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
909 return (u8) XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr,
914 /*****************************************************************************/
917 * This routine sets Bit time. Time segment 1, Time segment 2 and
918 * Synchronization Jump Width are set in this function. Device specification
919 * requires the values passed into this function be one less than the actual
920 * values of these fields. Read the device specification for details.
922 * Bit time can be set only if the CAN device is in Configuration Mode.
923 * Call XCanPs_EnterMode() to enter Configuration Mode before using this
926 * @param InstancePtr is a pointer to the XCanPs instance.
927 * @param SyncJumpWidth is the Synchronization Jump Width value to set.
928 * Valid values are from 0 to 3.
929 * @param TimeSegment2 is the Time Segment 2 value to set. Valid values
931 * @param TimeSegment1 is the Time Segment 1 value to set. Valid values
935 * - XST_SUCCESS if the Bit time is set successfully.
936 * - XST_FAILURE if CAN device is not in Configuration Mode.
940 ******************************************************************************/
941 int XCanPs_SetBitTiming(XCanPs *InstancePtr, u8 SyncJumpWidth,
942 u8 TimeSegment2, u8 TimeSegment1)
946 Xil_AssertNonvoid(InstancePtr != NULL);
947 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
948 Xil_AssertNonvoid(SyncJumpWidth <= 3);
949 Xil_AssertNonvoid(TimeSegment2 <= 7);
950 Xil_AssertNonvoid(TimeSegment1 <= 15 );
952 if (XCanPs_GetMode(InstancePtr) != XCANPS_MODE_CONFIG) {
956 Value = ((u32) TimeSegment1) & XCANPS_BTR_TS1_MASK;
957 Value |= (((u32) TimeSegment2) << XCANPS_BTR_TS2_SHIFT) &
959 Value |= (((u32) SyncJumpWidth) << XCANPS_BTR_SJW_SHIFT) &
962 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
963 XCANPS_BTR_OFFSET, Value);
968 /*****************************************************************************/
971 * This routine gets Bit time. Time segment 1, Time segment 2 and
972 * Synchronization Jump Width values are read in this function. According to
973 * device specification, the actual value of each of these fields is one
974 * more than the value read. Read the device specification for details.
976 * @param InstancePtr is a pointer to the XCanPs instance.
977 * @param SyncJumpWidth will store the Synchronization Jump Width value
978 * after this function returns. Its value ranges from 0 to 3.
979 * @param TimeSegment2 will store the Time Segment 2 value after this
980 * function returns. Its value ranges from 0 to 7.
981 * @param TimeSegment1 will store the Time Segment 1 value after this
982 * function returns. Its value ranges from 0 to 15.
988 ******************************************************************************/
989 void XCanPs_GetBitTiming(XCanPs *InstancePtr, u8 *SyncJumpWidth,
990 u8 *TimeSegment2, u8 *TimeSegment1)
994 Xil_AssertVoid(InstancePtr != NULL);
995 Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
996 Xil_AssertVoid(SyncJumpWidth != NULL);
997 Xil_AssertVoid(TimeSegment2 != NULL);
998 Xil_AssertVoid(TimeSegment1 != NULL);
1000 Value = XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr,
1003 *TimeSegment1 = (u8) (Value & XCANPS_BTR_TS1_MASK);
1005 (u8) ((Value & XCANPS_BTR_TS2_MASK) >> XCANPS_BTR_TS2_SHIFT);
1007 (u8) ((Value & XCANPS_BTR_SJW_MASK) >> XCANPS_BTR_SJW_SHIFT);
1011 /****************************************************************************/
1014 * This routine sets the Rx Full threshold in the Watermark Interrupt Register.
1016 * @param InstancePtr is a pointer to the XCanPs instance.
1017 * @param Threshold is the threshold to be set. The valid values are
1021 * - XST_FAILURE - If the CAN device is not in Configuration Mode.
1022 * - XST_SUCCESS - If the Rx Full threshold is set in Watermark
1023 * Interrupt Register.
1025 * @note The threshold can only be set when the CAN device is in the
1026 * configuration mode.
1028 *****************************************************************************/
1029 int XCanPs_SetRxIntrWatermark(XCanPs *InstancePtr, u8 Threshold)
1033 Xil_AssertNonvoid(InstancePtr != NULL);
1034 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
1035 Xil_AssertNonvoid(Threshold <= 63);
1037 if (XCanPs_GetMode(InstancePtr) != XCANPS_MODE_CONFIG)
1040 ThrReg = XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr,
1043 ThrReg &= XCANPS_WIR_EW_MASK;
1044 ThrReg |= ((u32)Threshold & XCANPS_WIR_FW_MASK);
1045 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
1046 XCANPS_WIR_OFFSET, ThrReg);
1051 /****************************************************************************/
1054 * This routine gets the Rx Full threshold from the Watermark Interrupt Register.
1056 * @param InstancePtr is a pointer to the XCanPs instance.
1058 * @return The Rx FIFO full watermark threshold value. The valid values
1063 *****************************************************************************/
1064 u8 XCanPs_GetRxIntrWatermark(XCanPs *InstancePtr)
1067 Xil_AssertNonvoid(InstancePtr != NULL);
1068 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
1071 return (u8) (XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr,
1072 XCANPS_WIR_OFFSET) &
1073 XCANPS_WIR_FW_MASK);
1077 /****************************************************************************/
1080 * This routine sets the Tx Empty Threshold in the Watermark Interrupt Register.
1082 * @param InstancePtr is a pointer to the XCanPs instance.
1083 * @param Threshold is the threshold to be set. The valid values are
1087 * - XST_FAILURE - If the CAN device is not in Configuration Mode.
1088 * - XST_SUCCESS - If the threshold is set in Watermark
1089 * Interrupt Register.
1091 * @note The threshold can only be set when the CAN device is in the
1092 * configuration mode.
1094 *****************************************************************************/
1095 int XCanPs_SetTxIntrWatermark(XCanPs *InstancePtr, u8 Threshold)
1098 Xil_AssertNonvoid(InstancePtr != NULL);
1099 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
1100 Xil_AssertNonvoid(Threshold <= 63);
1102 if (XCanPs_GetMode(InstancePtr) != XCANPS_MODE_CONFIG)
1105 ThrReg = XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr,
1108 ThrReg &= XCANPS_WIR_FW_MASK;
1109 ThrReg |= ((u32)(Threshold << XCANPS_WIR_EW_SHIFT)
1110 & XCANPS_WIR_EW_MASK);
1111 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
1112 XCANPS_WIR_OFFSET, ThrReg);
1117 /****************************************************************************/
1120 * This routine gets the Tx Empty threshold from Watermark Interrupt Register.
1122 * @param InstancePtr is a pointer to the XCanPs instance.
1124 * @return The Tx Empty FIFO threshold value. The valid values are 1 to 63.
1128 *****************************************************************************/
1129 u8 XCanPs_GetTxIntrWatermark(XCanPs *InstancePtr)
1132 Xil_AssertNonvoid(InstancePtr != NULL);
1133 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
1136 return (u8) ((XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr,
1137 XCANPS_WIR_OFFSET) & XCANPS_WIR_EW_MASK) >>
1138 XCANPS_WIR_EW_SHIFT);
1143 /******************************************************************************/
1145 * This routine is a stub for the asynchronous callbacks. The stub is here in
1146 * case the upper layer forgot to set the handler(s). On initialization, all
1147 * handlers are set to this callback. It is considered an error for this handler
1150 ******************************************************************************/
1151 static void StubHandler(void)
1153 Xil_AssertVoidAlways();