1 /******************************************************************************
3 * Copyright (C) 2010 - 2015 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_v3_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.
53 * 3.00 kvn 02/13/15 Modified code for MISRA-C:2012 compliance.
56 ******************************************************************************/
58 /***************************** Include Files *********************************/
62 /************************** Constant Definitions *****************************/
64 /**************************** Type Definitions *******************************/
66 /***************** Macros (Inline Functions) Definitions *********************/
68 /************************** Variable Definitions *****************************/
70 /************************** Function Prototypes ******************************/
72 static void StubHandler(void);
74 /*****************************************************************************/
77 * This function initializes a XCanPs instance/driver.
79 * The initialization entails:
80 * - Initialize all members of the XCanPs structure.
81 * - Reset the CAN device. The CAN device will enter Configuration Mode
82 * immediately after the reset is finished.
84 * @param InstancePtr is a pointer to the XCanPs instance.
85 * @param ConfigPtr points to the XCanPs device configuration structure.
86 * @param EffectiveAddr is the device base address in the virtual memory
87 * address space. If the address translation is not used then the
88 * physical address is passed.
89 * Unexpected errors may occur if the address mapping is changed
90 * after this function is invoked.
92 * @return XST_SUCCESS always.
96 ******************************************************************************/
97 s32 XCanPs_CfgInitialize(XCanPs *InstancePtr, XCanPs_Config *ConfigPtr,
101 Xil_AssertNonvoid(InstancePtr != NULL);
102 Xil_AssertNonvoid(ConfigPtr != NULL);
105 * Set some default values for instance data, don't indicate the device
106 * is ready to use until everything has been initialized successfully.
108 InstancePtr->IsReady = 0U;
109 InstancePtr->CanConfig.BaseAddr = EffectiveAddr;
110 InstancePtr->CanConfig.DeviceId = ConfigPtr->DeviceId;
113 * Set all handlers to stub values, let user configure this data later.
115 InstancePtr->SendHandler = (XCanPs_SendRecvHandler) StubHandler;
116 InstancePtr->RecvHandler = (XCanPs_SendRecvHandler) StubHandler;
117 InstancePtr->ErrorHandler = (XCanPs_ErrorHandler) StubHandler;
118 InstancePtr->EventHandler = (XCanPs_EventHandler) StubHandler;
121 * Indicate the component is now ready to use.
123 InstancePtr->IsReady = XIL_COMPONENT_IS_READY;
126 * Reset the device to get it into its initial state.
128 XCanPs_Reset(InstancePtr);
130 Status = XST_SUCCESS;
134 /*****************************************************************************/
137 * This function resets the CAN device. Calling this function resets the device
138 * immediately, and any pending transmission or reception is terminated at once.
139 * Both Object Layer and Transfer Layer are reset. This function does not reset
140 * the Physical Layer. All registers are reset to the default values, and no
141 * previous status will be restored. TX FIFO, RX FIFO and TX High Priority
142 * Buffer are also reset.
144 * When a reset is required due to an internal error, the driver notifies the
145 * upper layer software of this need through the error status code or interrupts.
146 * The upper layer software is responsible for calling this Reset function and
147 * then re-configuring the device.
149 * The CAN device will be in Configuration Mode immediately after this function
152 * @param InstancePtr is a pointer to the XCanPs instance.
158 ******************************************************************************/
159 void XCanPs_Reset(XCanPs *InstancePtr)
161 Xil_AssertVoid(InstancePtr != NULL);
162 Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
164 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr, XCANPS_SRR_OFFSET, \
165 XCANPS_SRR_SRST_MASK);
168 /****************************************************************************/
171 * This routine returns the current operation mode of the CAN device.
173 * @param InstancePtr is a pointer to the XCanPs instance.
176 * - XCANPS_MODE_CONFIG if the device is in Configuration Mode.
177 * - XCANPS_MODE_SLEEP if the device is in Sleep Mode.
178 * - XCANPS_MODE_NORMAL if the device is in Normal Mode.
179 * - XCANPS_MODE_LOOPBACK if the device is in Loop Back Mode.
180 * - XCANPS_MODE_SNOOP if the device is in Snoop Mode.
184 *****************************************************************************/
185 u8 XCanPs_GetMode(XCanPs *InstancePtr)
189 Xil_AssertNonvoid(InstancePtr != NULL);
190 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
192 StatusReg = XCanPs_GetStatus(InstancePtr);
194 if ((StatusReg & XCANPS_SR_CONFIG_MASK) != (u32)0) {
195 return (u8)XCANPS_MODE_CONFIG;
198 else if ((StatusReg & XCANPS_SR_SLEEP_MASK) != (u32)0) {
199 return (u8)XCANPS_MODE_SLEEP;
202 else if ((StatusReg & XCANPS_SR_NORMAL_MASK) != (u32)0) {
203 if ((StatusReg & XCANPS_SR_SNOOP_MASK) != (u32)0) {
204 return (u8)XCANPS_MODE_SNOOP;
206 return (u8)XCANPS_MODE_NORMAL;
211 * If this line is reached, the device is in Loop Back Mode.
213 return (u8)XCANPS_MODE_LOOPBACK;
217 /*****************************************************************************/
220 * This function allows the CAN device to enter one of the following operation
222 * - Configuration Mode: Pass in parameter XCANPS_MODE_CONFIG
223 * - Sleep Mode: Pass in parameter XCANPS_MODE_SLEEP
224 * - Normal Mode: Pass in parameter XCANPS_MODE_NORMAL
225 * - Loop Back Mode: Pass in parameter XCANPS_MODE_LOOPBACK.
226 * - Snoop Mode: Pass in parameter XCANPS_MODE_SNOOP.
228 * Read the xcanps.h file and device specification for detailed description of
229 * each operation mode.
231 * @param InstancePtr is a pointer to the XCanPs instance.
232 * @param OperationMode specify which operation mode to enter. Valid value
233 * is any of XCANPS_MODE_* defined in xcanps.h. Multiple modes
234 * can not be entered at the same time.
240 * This function does NOT ensure CAN device enters the specified operation mode
241 * before it returns the control to the caller. The caller is responsible for
242 * checking current operation mode using XCanPs_GetMode().
244 ******************************************************************************/
245 void XCanPs_EnterMode(XCanPs *InstancePtr, u8 OperationMode)
249 Xil_AssertVoid(InstancePtr != NULL);
250 Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
251 Xil_AssertVoid((OperationMode == (u8)XCANPS_MODE_CONFIG) ||
252 (OperationMode == (u8)XCANPS_MODE_SLEEP) ||
253 (OperationMode == (u8)XCANPS_MODE_NORMAL) ||
254 (OperationMode == (u8)XCANPS_MODE_LOOPBACK) ||
255 (OperationMode == (u8)XCANPS_MODE_SNOOP));
257 CurrentMode = XCanPs_GetMode(InstancePtr);
260 * If current mode is Normal Mode and the mode to enter is Sleep Mode,
261 * or if current mode is Sleep Mode and the mode to enter is Normal
262 * Mode, no transition through Configuration Mode is needed.
264 if ((CurrentMode == (u8)XCANPS_MODE_NORMAL) &&
265 (OperationMode == (u8)XCANPS_MODE_SLEEP)) {
267 * Normal Mode ---> Sleep Mode
269 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
270 XCANPS_MSR_OFFSET, XCANPS_MSR_SLEEP_MASK);
273 } else if ((CurrentMode == (u8)XCANPS_MODE_SLEEP) &&
274 (OperationMode == (u8)XCANPS_MODE_NORMAL)) {
276 * Sleep Mode ---> Normal Mode
278 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
279 XCANPS_MSR_OFFSET, 0U);
283 /*This else was made for misra-c compliance*/
288 * If the mode transition is not any of the two cases above, CAN must
289 * enter Configuration Mode before switching into the target operation
292 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
293 XCANPS_SRR_OFFSET, 0U);
296 * Check if the device has entered Configuration Mode, if not, return to
299 if (XCanPs_GetMode(InstancePtr) != (u8)XCANPS_MODE_CONFIG) {
303 switch (OperationMode) {
304 case XCANPS_MODE_CONFIG:
306 * As CAN is in Configuration Mode already.
307 * Nothing is needed to be done here.
311 case XCANPS_MODE_SLEEP:
312 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
313 XCANPS_MSR_OFFSET, XCANPS_MSR_SLEEP_MASK);
314 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
315 XCANPS_SRR_OFFSET, XCANPS_SRR_CEN_MASK);
318 case XCANPS_MODE_NORMAL:
319 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
320 XCANPS_MSR_OFFSET, 0U);
321 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
322 XCANPS_SRR_OFFSET, XCANPS_SRR_CEN_MASK);
325 case XCANPS_MODE_LOOPBACK:
326 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
327 XCANPS_MSR_OFFSET, XCANPS_MSR_LBACK_MASK);
328 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
329 XCANPS_SRR_OFFSET, XCANPS_SRR_CEN_MASK);
332 case XCANPS_MODE_SNOOP:
333 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
334 XCANPS_MSR_OFFSET, XCANPS_MSR_SNOOP_MASK);
335 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
336 XCANPS_SRR_OFFSET, XCANPS_SRR_CEN_MASK);
340 /*This default was made for misra-c compliance*/
346 /*****************************************************************************/
349 * This function returns Status value from Status Register (SR). Use the
350 * XCANPS_SR_* constants defined in xcanps_hw.h to interpret the returned
353 * @param InstancePtr is a pointer to the XCanPs instance.
355 * @return The 32-bit value read from Status Register.
359 ******************************************************************************/
360 u32 XCanPs_GetStatus(XCanPs *InstancePtr)
363 Xil_AssertNonvoid(InstancePtr != NULL);
364 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
366 return XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr,
370 /*****************************************************************************/
373 * This function reads Receive and Transmit error counters.
375 * @param InstancePtr is a pointer to the XCanPs instance.
376 * @param RxErrorCount is a pointer to data in which the Receive Error
377 * counter value is returned.
378 * @param TxErrorCount is a pointer to data in which the Transmit Error
379 * counter value is returned.
385 ******************************************************************************/
386 void XCanPs_GetBusErrorCounter(XCanPs *InstancePtr, u8 *RxErrorCount,
391 Xil_AssertVoid(InstancePtr != NULL);
392 Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
393 Xil_AssertVoid(RxErrorCount != NULL);
394 Xil_AssertVoid(TxErrorCount != NULL);
396 * Read Error Counter Register and parse it.
398 ErrorCount = XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr,
400 *RxErrorCount = (u8)((ErrorCount & XCANPS_ECR_REC_MASK) >>
401 XCANPS_ECR_REC_SHIFT);
402 *TxErrorCount = (u8)(ErrorCount & XCANPS_ECR_TEC_MASK);
405 /*****************************************************************************/
408 * This function reads Error Status value from Error Status Register (ESR). Use
409 * the XCANPS_ESR_* constants defined in xcanps_hw.h to interpret the
412 * @param InstancePtr is a pointer to the XCanPs instance.
414 * @return The 32-bit value read from Error Status Register.
418 ******************************************************************************/
419 u32 XCanPs_GetBusErrorStatus(XCanPs *InstancePtr)
422 Xil_AssertNonvoid(InstancePtr != NULL);
423 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
425 return XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr,
429 /*****************************************************************************/
432 * This function clears Error Status bit(s) previously set in Error
433 * Status Register (ESR). Use the XCANPS_ESR_* constants defined in xcanps_hw.h
434 * to create the value to pass in. If a bit was cleared in Error Status Register
435 * before this function is called, it will not be modified.
437 * @param InstancePtr is a pointer to the XCanPs instance.
439 * @param Mask is he 32-bit mask used to clear bits in Error Status
440 * Register. Multiple XCANPS_ESR_* values can be 'OR'ed to clear
445 ******************************************************************************/
446 void XCanPs_ClearBusErrorStatus(XCanPs *InstancePtr, u32 Mask)
448 Xil_AssertVoid(InstancePtr != NULL);
449 Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
451 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
452 XCANPS_ESR_OFFSET, Mask);
455 /*****************************************************************************/
458 * This function sends a CAN Frame. If the TX FIFO is not full then the given
459 * frame is written into the the TX FIFO otherwise, it returns an error code
461 * This function does not wait for the given frame being sent to CAN bus.
463 * @param InstancePtr is a pointer to the XCanPs instance.
464 * @param FramePtr is a pointer to a 32-bit aligned buffer containing the
465 * CAN frame to be sent.
468 * - XST_SUCCESS if TX FIFO was not full and the given frame was
469 * written into the FIFO.
470 * - XST_FIFO_NO_ROOM if there is no room in the TX FIFO for the
475 ******************************************************************************/
476 s32 XCanPs_Send(XCanPs *InstancePtr, u32 *FramePtr)
479 Xil_AssertNonvoid(InstancePtr != NULL);
480 Xil_AssertNonvoid(FramePtr != NULL);
481 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
483 if (XCanPs_IsTxFifoFull(InstancePtr) == TRUE) {
484 Status = XST_FIFO_NO_ROOM;
488 * Write IDR, DLC, Data Word 1 and Data Word 2 to the CAN device.
490 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
491 XCANPS_TXFIFO_ID_OFFSET, FramePtr[0]);
492 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
493 XCANPS_TXFIFO_DLC_OFFSET, FramePtr[1]);
494 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
495 XCANPS_TXFIFO_DW1_OFFSET, Xil_EndianSwap32(FramePtr[2]));
496 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
497 XCANPS_TXFIFO_DW2_OFFSET, Xil_EndianSwap32(FramePtr[3]));
499 Status = XST_SUCCESS;
504 /*****************************************************************************/
507 * This function receives a CAN Frame. This function first checks if RX FIFO is
508 * empty, if not, it then reads a frame from the RX FIFO into the given buffer.
509 * This function returns error code immediately if there is no frame in the RX
512 * @param InstancePtr is a pointer to the XCanPs instance.
513 * @param FramePtr is a pointer to a 32-bit aligned buffer where the CAN
514 * frame to be written.
517 * - XST_SUCCESS if RX FIFO was not empty and a frame was read from
518 * RX FIFO successfully and written into the given buffer.
519 * - XST_NO_DATA if there is no frame to be received from the FIFO.
523 ******************************************************************************/
524 s32 XCanPs_Recv(XCanPs *InstancePtr, u32 *FramePtr)
527 Xil_AssertNonvoid(InstancePtr != NULL);
528 Xil_AssertNonvoid(FramePtr != NULL);
529 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
531 if (XCanPs_IsRxEmpty(InstancePtr) == TRUE) {
532 Status = XST_NO_DATA;
536 * Read IDR, DLC, Data Word 1 and Data Word 2 from the CAN device.
538 FramePtr[0] = XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr,
539 XCANPS_RXFIFO_ID_OFFSET);
540 FramePtr[1] = XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr,
541 XCANPS_RXFIFO_DLC_OFFSET);
542 FramePtr[2] = Xil_EndianSwap32(XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr,
543 XCANPS_RXFIFO_DW1_OFFSET));
544 FramePtr[3] = Xil_EndianSwap32(XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr,
545 XCANPS_RXFIFO_DW2_OFFSET));
548 * Clear RXNEMP bit in ISR. This allows future XCanPs_IsRxEmpty() call
549 * returns correct RX FIFO occupancy/empty condition.
551 XCanPs_IntrClear(InstancePtr, XCANPS_IXR_RXNEMP_MASK);
553 Status = XST_SUCCESS;
558 /*****************************************************************************/
561 * This routine sends a CAN High Priority frame. This function first checks if
562 * TX High Priority Buffer is empty. If yes, it then writes the given frame into
563 * the Buffer. If not, this function returns immediately. This function does not
564 * wait for the given frame being sent to CAN bus.
566 * @param InstancePtr is a pointer to the XCanPs instance.
567 * @param FramePtr is a pointer to a 32-bit aligned buffer containing the
568 * CAN High Priority frame to be sent.
571 * - XST_SUCCESS if TX High Priority Buffer was not full and the
572 * given frame was written into the buffer.
573 * - XST_FIFO_NO_ROOM if there is no room in the TX High Priority
574 * Buffer for this frame.
578 * If the frame needs to be sent immediately and not delayed by processor's
579 * interrupt handling, the caller should disable interrupt at processor
580 * level before invoking this function.
582 ******************************************************************************/
583 s32 XCanPs_SendHighPriority(XCanPs *InstancePtr, u32 *FramePtr)
586 Xil_AssertNonvoid(InstancePtr != NULL);
587 Xil_AssertNonvoid(FramePtr != NULL);
588 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
590 if (XCanPs_IsHighPriorityBufFull(InstancePtr) == TRUE) {
591 Status = XST_FIFO_NO_ROOM;
595 * Write IDR, DLC, Data Word 1 and Data Word 2 to the CAN device.
597 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
598 XCANPS_TXHPB_ID_OFFSET, FramePtr[0]);
599 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
600 XCANPS_TXHPB_DLC_OFFSET, FramePtr[1]);
601 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
602 XCANPS_TXHPB_DW1_OFFSET, Xil_EndianSwap32(FramePtr[2]));
603 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
604 XCANPS_TXHPB_DW2_OFFSET, Xil_EndianSwap32(FramePtr[3]));
606 Status = XST_SUCCESS;
611 /*****************************************************************************/
614 * This routine enables individual acceptance filters. Up to 4 filters could
617 * @param InstancePtr is a pointer to the XCanPs instance.
618 * @param FilterIndexes specifies which filter(s) to enable. Use
619 * any XCANPS_AFR_UAF*_MASK to enable one filter, and "Or"
620 * multiple XCANPS_AFR_UAF*_MASK values if multiple filters need
621 * to be enabled. Any filter not specified in this parameter will
622 * keep its previous enable/disable setting.
629 ******************************************************************************/
630 void XCanPs_AcceptFilterEnable(XCanPs *InstancePtr, u32 FilterIndexes)
634 Xil_AssertVoid(InstancePtr != NULL);
635 Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
638 * Calculate the new value and write to AFR.
640 EnabledFilters = XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr,
642 EnabledFilters |= FilterIndexes;
643 EnabledFilters &= (u32)XCANPS_AFR_UAF_ALL_MASK;
644 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr, XCANPS_AFR_OFFSET,
648 /*****************************************************************************/
651 * This routine disables individual acceptance filters. Up to 4 filters could
652 * be disabled. If all acceptance filters are disabled then all the received
653 * frames are stored in the RX FIFO.
655 * @param InstancePtr is a pointer to the XCanPs instance.
656 * @param FilterIndexes specifies which filter(s) to disable. Use
657 * any XCANPS_AFR_UAF*_MASK to disable one filter, and "Or"
658 * multiple XCANPS_AFR_UAF*_MASK values if multiple filters need
659 * to be disabled. Any filter not specified in this parameter will
660 * keep its previous enable/disable setting. If all acceptance
661 * filters are disabled then all received frames are stored in the
668 ******************************************************************************/
669 void XCanPs_AcceptFilterDisable(XCanPs *InstancePtr, u32 FilterIndexes)
673 Xil_AssertVoid(InstancePtr != NULL);
674 Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
677 * Calculate the new value and write to AFR.
679 EnabledFilters = XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr,
681 EnabledFilters &= (u32)XCANPS_AFR_UAF_ALL_MASK & (~FilterIndexes);
682 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr, XCANPS_AFR_OFFSET,
686 /*****************************************************************************/
689 * This function returns enabled acceptance filters. Use XCANPS_AFR_UAF*_MASK
690 * defined in xcanps_hw.h to interpret the returned value. If no acceptance
691 * filters are enabled then all received frames are stored in the RX FIFO.
693 * @param InstancePtr is a pointer to the XCanPs instance.
695 * @return The value stored in Acceptance Filter Register.
700 ******************************************************************************/
701 u32 XCanPs_AcceptFilterGetEnabled(XCanPs *InstancePtr)
704 Xil_AssertNonvoid(InstancePtr != NULL);
705 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
707 return XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr,
712 /*****************************************************************************/
715 * This function sets values to the Acceptance Filter Mask Register (AFMR) and
716 * Acceptance Filter ID Register (AFIR) for the specified Acceptance Filter.
717 * Use XCANPS_IDR_* defined in xcanps_hw.h to create the values to set the
718 * filter. Read the xcanps.h file and device specification for details.
720 * This function should be called only after:
721 * - The given filter is disabled by calling XCanPs_AcceptFilterDisable()
722 * - And the CAN device is ready to accept writes to AFMR and AFIR, i.e.,
723 * XCanPs_IsAcceptFilterBusy() returns FALSE.
725 * @param InstancePtr is a pointer to the XCanPs instance.
726 * @param FilterIndex defines which Acceptance Filter Mask and ID Register
727 * to set. Use any single XCANPS_AFR_UAF*_MASK value.
728 * @param MaskValue is the value to write to the chosen Acceptance Filter
730 * @param IdValue is the value to write to the chosen Acceptance Filter
734 * - XST_SUCCESS if the values were set successfully.
735 * - XST_FAILURE if the given filter was not disabled, or the CAN
736 * device was not ready to accept writes to AFMR and AFIR.
740 ******************************************************************************/
741 s32 XCanPs_AcceptFilterSet(XCanPs *InstancePtr, u32 FilterIndex,
742 u32 MaskValue, u32 IdValue)
747 Xil_AssertNonvoid(InstancePtr != NULL);
748 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
749 Xil_AssertNonvoid((FilterIndex == XCANPS_AFR_UAF4_MASK) ||
750 (FilterIndex == XCANPS_AFR_UAF3_MASK) ||
751 (FilterIndex == XCANPS_AFR_UAF2_MASK) ||
752 (FilterIndex == XCANPS_AFR_UAF1_MASK));
755 * Return an error if the given filter is currently enabled.
757 EnabledFilters = XCanPs_AcceptFilterGetEnabled(InstancePtr);
758 if ((EnabledFilters & FilterIndex) == FilterIndex) {
759 Status = XST_FAILURE;
763 * If the CAN device is not ready to accept writes to AFMR and AFIR,
766 if (XCanPs_IsAcceptFilterBusy(InstancePtr) == TRUE) {
767 Status = XST_FAILURE;
771 * Write to the AFMR and AFIR of the specified filter.
773 switch (FilterIndex) {
774 case XCANPS_AFR_UAF1_MASK: /* Acceptance Filter No. 1 */
776 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
777 XCANPS_AFMR1_OFFSET, MaskValue);
778 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
779 XCANPS_AFIR1_OFFSET, IdValue);
782 case XCANPS_AFR_UAF2_MASK: /* Acceptance Filter No. 2 */
783 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
784 XCANPS_AFMR2_OFFSET, MaskValue);
785 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
786 XCANPS_AFIR2_OFFSET, IdValue);
789 case XCANPS_AFR_UAF3_MASK: /* Acceptance Filter No. 3 */
790 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
791 XCANPS_AFMR3_OFFSET, MaskValue);
792 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
793 XCANPS_AFIR3_OFFSET, IdValue);
796 case XCANPS_AFR_UAF4_MASK: /* Acceptance Filter No. 4 */
797 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
798 XCANPS_AFMR4_OFFSET, MaskValue);
799 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
800 XCANPS_AFIR4_OFFSET, IdValue);
804 /*This default was made for misra-c compliance*/
808 Status = XST_SUCCESS;
814 /*****************************************************************************/
817 * This function reads the values of the Acceptance Filter Mask and ID Register
818 * for the specified Acceptance Filter. Use XCANPS_IDR_* defined in xcanps_hw.h
819 * to interpret the values. Read the xcanps.h file and device specification for
822 * @param InstancePtr is a pointer to the XCanPs instance.
823 * @param FilterIndex defines which Acceptance Filter Mask Register to get
824 * Mask and ID from. Use any single XCANPS_FILTER_* value.
825 * @param MaskValue is a pointer to the data in which the Mask value read
826 * from the chosen Acceptance Filter Mask Register is returned.
827 * @param IdValue is a pointer to the data in which the ID value read
828 * from the chosen Acceptance Filter ID Register is returned.
834 ******************************************************************************/
835 void XCanPs_AcceptFilterGet(XCanPs *InstancePtr, u32 FilterIndex,
836 u32 *MaskValue, u32 *IdValue)
838 Xil_AssertVoid(InstancePtr != NULL);
839 Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
840 Xil_AssertVoid((FilterIndex == XCANPS_AFR_UAF4_MASK) ||
841 (FilterIndex == XCANPS_AFR_UAF3_MASK) ||
842 (FilterIndex == XCANPS_AFR_UAF2_MASK) ||
843 (FilterIndex == XCANPS_AFR_UAF1_MASK));
844 Xil_AssertVoid(MaskValue != NULL);
845 Xil_AssertVoid(IdValue != NULL);
848 * Read from the AFMR and AFIR of the specified filter.
850 switch (FilterIndex) {
851 case XCANPS_AFR_UAF1_MASK: /* Acceptance Filter No. 1 */
852 *MaskValue = XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr,
853 XCANPS_AFMR1_OFFSET);
854 *IdValue = XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr,
855 XCANPS_AFIR1_OFFSET);
858 case XCANPS_AFR_UAF2_MASK: /* Acceptance Filter No. 2 */
859 *MaskValue = XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr,
860 XCANPS_AFMR2_OFFSET);
861 *IdValue = XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr,
862 XCANPS_AFIR2_OFFSET);
865 case XCANPS_AFR_UAF3_MASK: /* Acceptance Filter No. 3 */
866 *MaskValue = XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr,
867 XCANPS_AFMR3_OFFSET);
868 *IdValue = XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr,
869 XCANPS_AFIR3_OFFSET);
872 case XCANPS_AFR_UAF4_MASK: /* Acceptance Filter No. 4 */
873 *MaskValue = XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr,
874 XCANPS_AFMR4_OFFSET);
875 *IdValue = XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr,
876 XCANPS_AFIR4_OFFSET);
880 /*This default was made for misra-c compliance*/
885 /*****************************************************************************/
888 * This routine sets Baud Rate Prescaler value. The system clock for the CAN
889 * controller is divided by (Prescaler + 1) to generate the quantum clock
890 * needed for sampling and synchronization. Read the device specification
893 * Baud Rate Prescaler can be set only if the CAN device is in Configuration
894 * Mode. Call XCanPs_EnterMode() to enter Configuration Mode before using this
897 * @param InstancePtr is a pointer to the XCanPs instance.
898 * @param Prescaler is the value to set. Valid values are from 0 to 255.
901 * - XST_SUCCESS if the Baud Rate Prescaler value is set
903 * - XST_FAILURE if CAN device is not in Configuration Mode.
907 ******************************************************************************/
908 s32 XCanPs_SetBaudRatePrescaler(XCanPs *InstancePtr, u8 Prescaler)
911 Xil_AssertNonvoid(InstancePtr != NULL);
912 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
914 if (XCanPs_GetMode(InstancePtr) != (u8)XCANPS_MODE_CONFIG) {
915 Status = XST_FAILURE;
918 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr, XCANPS_BRPR_OFFSET,
921 Status = XST_SUCCESS;
926 /*****************************************************************************/
929 * This routine gets Baud Rate Prescaler value. The system clock for the CAN
930 * controller is divided by (Prescaler + 1) to generate the quantum clock
931 * needed for sampling and synchronization. Read the device specification for
934 * @param InstancePtr is a pointer to the XCanPs instance.
936 * @return Current used Baud Rate Prescaler value. The value's range is
941 ******************************************************************************/
942 u8 XCanPs_GetBaudRatePrescaler(XCanPs *InstancePtr)
945 Xil_AssertNonvoid(InstancePtr != NULL);
946 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
948 ReadValue = XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr,
950 return ((u8)ReadValue);
953 /*****************************************************************************/
956 * This routine sets Bit time. Time segment 1, Time segment 2 and
957 * Synchronization Jump Width are set in this function. Device specification
958 * requires the values passed into this function be one less than the actual
959 * values of these fields. Read the device specification for details.
961 * Bit time can be set only if the CAN device is in Configuration Mode.
962 * Call XCanPs_EnterMode() to enter Configuration Mode before using this
965 * @param InstancePtr is a pointer to the XCanPs instance.
966 * @param SyncJumpWidth is the Synchronization Jump Width value to set.
967 * Valid values are from 0 to 3.
968 * @param TimeSegment2 is the Time Segment 2 value to set. Valid values
970 * @param TimeSegment1 is the Time Segment 1 value to set. Valid values
974 * - XST_SUCCESS if the Bit time is set successfully.
975 * - XST_FAILURE if CAN device is not in Configuration Mode.
979 ******************************************************************************/
980 s32 XCanPs_SetBitTiming(XCanPs *InstancePtr, u8 SyncJumpWidth,
981 u8 TimeSegment2, u8 TimeSegment1)
986 Xil_AssertNonvoid(InstancePtr != NULL);
987 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
988 Xil_AssertNonvoid(SyncJumpWidth <= (u8)3U);
989 Xil_AssertNonvoid(TimeSegment2 <= (u8)7U);
990 Xil_AssertNonvoid(TimeSegment1 <= (u8)15U );
992 if (XCanPs_GetMode(InstancePtr) != (u8)XCANPS_MODE_CONFIG) {
993 Status = XST_FAILURE;
996 Value = ((u32) TimeSegment1) & XCANPS_BTR_TS1_MASK;
997 Value |= (((u32) TimeSegment2) << XCANPS_BTR_TS2_SHIFT) &
999 Value |= (((u32) SyncJumpWidth) << XCANPS_BTR_SJW_SHIFT) &
1000 XCANPS_BTR_SJW_MASK;
1002 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
1003 XCANPS_BTR_OFFSET, Value);
1005 Status = XST_SUCCESS;
1010 /*****************************************************************************/
1013 * This routine gets Bit time. Time segment 1, Time segment 2 and
1014 * Synchronization Jump Width values are read in this function. According to
1015 * device specification, the actual value of each of these fields is one
1016 * more than the value read. Read the device specification for details.
1018 * @param InstancePtr is a pointer to the XCanPs instance.
1019 * @param SyncJumpWidth will store the Synchronization Jump Width value
1020 * after this function returns. Its value ranges from 0 to 3.
1021 * @param TimeSegment2 will store the Time Segment 2 value after this
1022 * function returns. Its value ranges from 0 to 7.
1023 * @param TimeSegment1 will store the Time Segment 1 value after this
1024 * function returns. Its value ranges from 0 to 15.
1030 ******************************************************************************/
1031 void XCanPs_GetBitTiming(XCanPs *InstancePtr, u8 *SyncJumpWidth,
1032 u8 *TimeSegment2, u8 *TimeSegment1)
1036 Xil_AssertVoid(InstancePtr != NULL);
1037 Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
1038 Xil_AssertVoid(SyncJumpWidth != NULL);
1039 Xil_AssertVoid(TimeSegment2 != NULL);
1040 Xil_AssertVoid(TimeSegment1 != NULL);
1042 Value = XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr,
1045 *TimeSegment1 = (u8) (Value & XCANPS_BTR_TS1_MASK);
1047 (u8) ((Value & XCANPS_BTR_TS2_MASK) >> XCANPS_BTR_TS2_SHIFT);
1049 (u8) ((Value & XCANPS_BTR_SJW_MASK) >> XCANPS_BTR_SJW_SHIFT);
1053 /****************************************************************************/
1056 * This routine sets the Rx Full threshold in the Watermark Interrupt Register.
1058 * @param InstancePtr is a pointer to the XCanPs instance.
1059 * @param Threshold is the threshold to be set. The valid values are
1063 * - XST_FAILURE - If the CAN device is not in Configuration Mode.
1064 * - XST_SUCCESS - If the Rx Full threshold is set in Watermark
1065 * Interrupt Register.
1067 * @note The threshold can only be set when the CAN device is in the
1068 * configuration mode.
1070 *****************************************************************************/
1071 s32 XCanPs_SetRxIntrWatermark(XCanPs *InstancePtr, u8 Threshold)
1076 Xil_AssertNonvoid(InstancePtr != NULL);
1077 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
1078 Xil_AssertNonvoid(Threshold <= (u8)63);
1080 if (XCanPs_GetMode(InstancePtr) != (u8)XCANPS_MODE_CONFIG) {
1081 Status = XST_FAILURE;
1084 ThrReg = XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr,
1087 ThrReg &= XCANPS_WIR_EW_MASK;
1088 ThrReg |= ((u32)Threshold & XCANPS_WIR_FW_MASK);
1089 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
1090 XCANPS_WIR_OFFSET, ThrReg);
1092 Status = XST_SUCCESS;
1097 /****************************************************************************/
1100 * This routine gets the Rx Full threshold from the Watermark Interrupt Register.
1102 * @param InstancePtr is a pointer to the XCanPs instance.
1104 * @return The Rx FIFO full watermark threshold value. The valid values
1109 *****************************************************************************/
1110 u8 XCanPs_GetRxIntrWatermark(XCanPs *InstancePtr)
1113 Xil_AssertNonvoid(InstancePtr != NULL);
1114 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
1117 return (u8) (XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr,
1118 XCANPS_WIR_OFFSET) &
1119 XCANPS_WIR_FW_MASK);
1123 /****************************************************************************/
1126 * This routine sets the Tx Empty Threshold in the Watermark Interrupt Register.
1128 * @param InstancePtr is a pointer to the XCanPs instance.
1129 * @param Threshold is the threshold to be set. The valid values are
1133 * - XST_FAILURE - If the CAN device is not in Configuration Mode.
1134 * - XST_SUCCESS - If the threshold is set in Watermark
1135 * Interrupt Register.
1137 * @note The threshold can only be set when the CAN device is in the
1138 * configuration mode.
1140 *****************************************************************************/
1141 s32 XCanPs_SetTxIntrWatermark(XCanPs *InstancePtr, u8 Threshold)
1145 Xil_AssertNonvoid(InstancePtr != NULL);
1146 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
1147 Xil_AssertNonvoid(Threshold <= (u8)63);
1149 if (XCanPs_GetMode(InstancePtr) != (u8)XCANPS_MODE_CONFIG) {
1150 Status = XST_FAILURE;
1153 ThrReg = XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr,
1156 ThrReg &= XCANPS_WIR_FW_MASK;
1157 ThrReg |= (((u32)Threshold << XCANPS_WIR_EW_SHIFT)
1158 & XCANPS_WIR_EW_MASK);
1159 XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
1160 XCANPS_WIR_OFFSET, ThrReg);
1162 Status = XST_SUCCESS;
1167 /****************************************************************************/
1170 * This routine gets the Tx Empty threshold from Watermark Interrupt Register.
1172 * @param InstancePtr is a pointer to the XCanPs instance.
1174 * @return The Tx Empty FIFO threshold value. The valid values are 1 to 63.
1178 *****************************************************************************/
1179 u8 XCanPs_GetTxIntrWatermark(XCanPs *InstancePtr)
1182 Xil_AssertNonvoid(InstancePtr != NULL);
1183 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
1186 return (u8) ((XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr,
1187 XCANPS_WIR_OFFSET) & XCANPS_WIR_EW_MASK) >>
1188 XCANPS_WIR_EW_SHIFT);
1193 /******************************************************************************/
1195 * This routine is a stub for the asynchronous callbacks. The stub is here in
1196 * case the upper layer forgot to set the handler(s). On initialization, all
1197 * handlers are set to this callback. It is considered an error for this handler
1200 ******************************************************************************/
1201 static void StubHandler(void)
1203 Xil_AssertVoidAlways();