]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - processor-sdk/performance-audio-sr.git/blob - psdk_cust/pdk_k2g_1_0_1_1_eng/packages/ti/board/diag/dcan/src/dcan.c
PASDK-258:Update PDK eng to 1.0.1.1. Using build number to differentiate PDK eng...
[processor-sdk/performance-audio-sr.git] / psdk_cust / pdk_k2g_1_0_1_1_eng / packages / ti / board / diag / dcan / src / dcan.c
1 /*
2  *  Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/
3  *
4  *  Redistribution and use in source and binary forms, with or without
5  *  modification, are permitted provided that the following conditions
6  *  are met:
7  *
8  *    Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  *
11  *    Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the
14  *    distribution.
15  *
16  *    Neither the name of Texas Instruments Incorporated nor the names of
17  *    its contributors may be used to endorse or promote products derived
18  *    from this software without specific prior written permission.
19  *
20  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23  *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24  *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25  *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26  *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27  *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28  *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30  *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  *
32  */
33 /**
34  *  \file     dcan.c
35  *
36  *  \brief    This file contains the device abstraction layer APIs for DCAN
37  *            peripheral.
38  *
39  */
40 /* ========================================================================== */
41 /*                             Include Files                                  */
42 /* ========================================================================== */
43 #include <stdio.h>
44 #include <stdint.h>
45 #include <ti/csl/csl_types.h>
46 #include <ti/csl/hw_types.h>
47 #include <dcan.h>
49 /* ========================================================================== */
50 /*                           Macros & Typedefs                                */
51 /* ========================================================================== */
53 /**
54  *  \brief Parity function is disabled
55  */
56 #define DCAN_PARITY_DISABLED            (5U)
57 /**
58  *  \brief Parity function is enabled
59  */
60 #define DCAN_PARITY_ENABLED             (0U)
61 /**
62  *  \brief ECC Diagnostic mode is disabled
63  */
64 #define DCAN_ECC_DIAG_DISABLED            (0xAU)
65 /**
66  *  \brief ECC Diagnostic mode is enabled
67  */
68 #define DCAN_ECC_DIAG_ENABLED             (0x5U)
69 /**
70  *  \brief SECDED Single bit Error correction is enabled
71  */
72 #define DCAN_ECC_MODE_ENABLED             (0x0U)
73 /**
74  *  \brief SECDED Single bit Error correction is disabled
75  */
76 #define DCAN_ECC_MODE_DISABLED            (0x5U)
77 /**
78  *  \brief SECDED Single bit Error Event is enabled
79  */
80 #define DCAN_ECC_SBE_EVT_ENABLED          (0x0U)
81 /**
82  *  \brief SECDED Single bit Error Event is disabled
83  */
84 #define DCAN_ECC_SBE_EVT_DISABLED            (0x5U)
86 /* ========================================================================== */
87 /*                         Structures and Enums                               */
88 /* ========================================================================== */
90 /* None*/
92 /* ========================================================================== */
93 /*                          Function Definitions                              */
94 /* ========================================================================== */
96 int32_t DCANReset(uint32_t baseAddr, uint32_t timeOut)
97 {
98     int32_t retVal = STW_SOK;
100     /* Reset the DCAN module. */
101     DCANSetMode(baseAddr, DCAN_MODE_INIT);
103     HW_WR_FIELD32((baseAddr + DCAN_CTL), DCAN_CTL_SWR, DCAN_CTL_SWR_EN_2_0X1);
105     /* Wait until the reset is done */
106     do
107     {
108         if (DCAN_CTL_SWR_MASK != (HW_RD_REG32(baseAddr + DCAN_CTL) &
109                                   DCAN_CTL_SWR_MASK))
110         {
111             break;
112         }
113         timeOut--;
114         if (timeOut == 0)
115         {
116             retVal = STW_EFAIL;
117         }
118     }
119     while (timeOut);
121     if (retVal == STW_SOK)
122     {
123         /* Configure TX I/O Control Register */
124         HW_WR_FIELD32(
125             (baseAddr + DCAN_TIOC),
126             DCAN_TIOC_FUNC,
127             DCAN_TIOC_FUNC_EN_2_0X1);
129         /* Configure RX I/O Control Register */
130         HW_WR_FIELD32(
131             (baseAddr + DCAN_RIOC),
132             DCAN_RIOC_FUNC,
133             DCAN_RIOC_FUNC_EN_2_0X1);
134     }
135     return retVal;
138 void DCANSetMode(uint32_t baseAddr, uint32_t mode)
140     /* Configure the DCAN mode of operation. */
141     HW_WR_FIELD32((baseAddr + DCAN_CTL), DCAN_CTL_INIT, mode);
144 void DCANSetBitTime(uint32_t baseAddr, const dcanBitTimeParams_t *pBitTimePrms)
146     uint32_t btrValue;
148     /* Write the BRP value */
149     btrValue = ((pBitTimePrms->baudRatePrescaler << DCAN_BTR_BRP_SHIFT) &
150                 DCAN_BTR_BRP_MASK);
151     btrValue |= ((pBitTimePrms->syncJumpWidth << DCAN_BTR_SJW_SHIFT) &
152                  DCAN_BTR_SJW_MASK);
153     btrValue |= ((pBitTimePrms->timeSegment1 << DCAN_BTR_TSEG1_SHIFT) &
154                  DCAN_BTR_TSEG1_MASK);
155     btrValue |= ((pBitTimePrms->timeSegment2 << DCAN_BTR_TSEG2_SHIFT) &
156                  DCAN_BTR_TSEG2_MASK);
157     btrValue |= ((pBitTimePrms->baudRatePrescalerExt << DCAN_BTR_BRPE_SHIFT) &
158                  DCAN_BTR_BRPE_MASK);
160     /* Enable write access to configuration register */
161     HW_WR_FIELD32(
162         (baseAddr + DCAN_CTL),
163         DCAN_CTL_CCE,
164         DCAN_CTL_CCE_EN_2_0X1);
166     /* Program the DCAN bit time value. */
167     HW_WR_REG32((baseAddr + DCAN_BTR), btrValue);
169     /* Disable write access to configuration register */
170     HW_WR_FIELD32(
171         (baseAddr + DCAN_CTL),
172         DCAN_CTL_CCE,
173         DCAN_CTL_CCE_EN_1_0X0);
176 void DCANConfig(uint32_t baseAddr, const dcanCfgParams_t *pDcanCfgPrms)
178     HW_WR_FIELD32(
179         (baseAddr + DCAN_CTL),
180         DCAN_CTL_ABO,
181         pDcanCfgPrms->autoBusOnEnable);
182     if (TRUE == pDcanCfgPrms->autoBusOnEnable)
183     {
184         HW_WR_FIELD32(
185             (baseAddr + DCAN_ABOTR),
186             DCAN_ABOTR_ABO_TIME,
187             pDcanCfgPrms->autoBusOnTimerVal);
188     }
190     DCANParityEnable(baseAddr, pDcanCfgPrms->parityEnable);
192     HW_WR_FIELD32(
193         (baseAddr + DCAN_CTL),
194         DCAN_CTL_DAR,
195         pDcanCfgPrms->autoRetransmitDisable);
197     HW_WR_FIELD32(
198         (baseAddr + DCAN_CTL),
199         DCAN_CTL_TEST,
200         pDcanCfgPrms->testModeEnable);
201     HW_WR_FIELD32(
202         (baseAddr + DCAN_TEST),
203         DCAN_TEST_RDA,
204         pDcanCfgPrms->ramAccessEnable);
205     switch (pDcanCfgPrms->testMode)
206     {
207         case DCAN_TEST_MODE_NONE:
208             HW_WR_FIELD32(
209                 (baseAddr + DCAN_TEST),
210                 DCAN_TEST_SILENT,
211                 DCAN_TEST_SILENT_EN_1_0X0);
212             HW_WR_FIELD32(
213                 (baseAddr + DCAN_TEST),
214                 DCAN_TEST_LBACK,
215                 DCAN_TEST_LBACK_EN_1_0X0);
216             HW_WR_FIELD32(
217                 (baseAddr + DCAN_TEST),
218                 DCAN_TEST_EXL,
219                 DCAN_TEST_EXL_EN_1_0X0);
220             break;
222         case DCAN_TEST_MODE_SILENT:
223             HW_WR_FIELD32(
224                 (baseAddr + DCAN_TEST),
225                 DCAN_TEST_SILENT,
226                 DCAN_TEST_SILENT_EN_2_0X1);
227             HW_WR_FIELD32(
228                 (baseAddr + DCAN_TEST),
229                 DCAN_TEST_LBACK,
230                 DCAN_TEST_LBACK_EN_1_0X0);
231             HW_WR_FIELD32(
232                 (baseAddr + DCAN_TEST),
233                 DCAN_TEST_EXL,
234                 DCAN_TEST_EXL_EN_1_0X0);
235             break;
237         case DCAN_TEST_MODE_LPBACK:
238             HW_WR_FIELD32(
239                 (baseAddr + DCAN_TEST),
240                 DCAN_TEST_SILENT,
241                 DCAN_TEST_SILENT_EN_1_0X0);
242             HW_WR_FIELD32(
243                 (baseAddr + DCAN_TEST),
244                 DCAN_TEST_LBACK,
245                 DCAN_TEST_LBACK_EN_2_0X1);
246             HW_WR_FIELD32(
247                 (baseAddr + DCAN_TEST),
248                 DCAN_TEST_EXL,
249                 DCAN_TEST_EXL_EN_1_0X0);
250             break;
252         case DCAN_TEST_MODE_LPBACK_SILENT:
253             HW_WR_FIELD32(
254                 (baseAddr + DCAN_TEST),
255                 DCAN_TEST_SILENT,
256                 DCAN_TEST_SILENT_EN_2_0X1);
257             HW_WR_FIELD32(
258                 (baseAddr + DCAN_TEST),
259                 DCAN_TEST_LBACK,
260                 DCAN_TEST_LBACK_EN_2_0X1);
261             HW_WR_FIELD32(
262                 (baseAddr + DCAN_TEST),
263                 DCAN_TEST_EXL,
264                 DCAN_TEST_EXL_EN_1_0X0);
265             break;
267         case DCAN_TEST_MODE_EXT_LPBACK:
268             HW_WR_FIELD32(
269                 (baseAddr + DCAN_TEST),
270                 DCAN_TEST_SILENT,
271                 DCAN_TEST_SILENT_EN_1_0X0);
272             HW_WR_FIELD32(
273                 (baseAddr + DCAN_TEST),
274                 DCAN_TEST_LBACK,
275                 DCAN_TEST_LBACK_EN_1_0X0);
276             HW_WR_FIELD32(
277                 (baseAddr + DCAN_TEST),
278                 DCAN_TEST_EXL,
279                 DCAN_TEST_EXL_EN_2_0X1);
280             break;
282         default:
283             /* Default to normal operation */
284             HW_WR_FIELD32(
285                 (baseAddr + DCAN_TEST),
286                 DCAN_TEST_SILENT,
287                 DCAN_TEST_SILENT_EN_1_0X0);
288             HW_WR_FIELD32(
289                 (baseAddr + DCAN_TEST),
290                 DCAN_TEST_LBACK,
291                 DCAN_TEST_LBACK_EN_1_0X0);
292             HW_WR_FIELD32(
293                 (baseAddr + DCAN_TEST),
294                 DCAN_TEST_EXL,
295                 DCAN_TEST_EXL_EN_1_0X0);
296             break;
297     }
299     HW_WR_FIELD32(
300         (baseAddr + DCAN_CTL),
301         DCAN_CTL_IE0,
302         pDcanCfgPrms->intrLine0Enable);
303     HW_WR_FIELD32(
304         (baseAddr + DCAN_CTL),
305         DCAN_CTL_IE1,
306         pDcanCfgPrms->intrLine1Enable);
307     HW_WR_FIELD32(
308         (baseAddr + DCAN_CTL),
309         DCAN_CTL_EIE,
310         pDcanCfgPrms->errIntrEnable);
311     HW_WR_FIELD32(
312         (baseAddr + DCAN_CTL),
313         DCAN_CTL_SIE,
314         pDcanCfgPrms->stsChangeIntrEnable);
316     HW_WR_FIELD32(
317         (baseAddr + DCAN_CTL),
318         DCAN_CTL_DE1,
319         pDcanCfgPrms->if1DmaEnable);
320     HW_WR_FIELD32(
321         (baseAddr + DCAN_CTL),
322         DCAN_CTL_DE2,
323         pDcanCfgPrms->if2DmaEnable);
324     HW_WR_FIELD32(
325         (baseAddr + DCAN_CTL),
326         DCAN_CTL_DE3,
327         pDcanCfgPrms->if3DmaEnable);
329 #if defined (SOC_TDA3XX)
330     DCANEccModeEnable(baseAddr,
331                       pDcanCfgPrms->eccModeEnable,
332                       pDcanCfgPrms->sbeEventEnable);
333     DCANEccDiagModeEnable(baseAddr, pDcanCfgPrms->eccDiagModeEnable);
334 #endif
337 int32_t DCANConfigMsgObj(uint32_t                     baseAddr,
338                          uint32_t                     msgObj,
339                          uint32_t                     ifRegNum,
340                          const dcanMsgObjCfgParams_t *pMsgObjCfgPrms)
342     int32_t  retVal = STW_SOK;
343     uint32_t regVal = 0;
344     uint32_t ifCmd  = 0;
346     if (TRUE != DCANIsIfRegBusy(baseAddr, ifRegNum))
347     {
348         /* Config identifier mask , MDir , MXtd */
349         HW_WR_FIELD32((baseAddr + DCAN_IFMSK(ifRegNum)),
350                       DCAN_IFMSK_MXTD,
351                       pMsgObjCfgPrms->xIdFlagMask);
353         HW_WR_FIELD32((baseAddr + DCAN_IFMSK(ifRegNum)),
354                       DCAN_IFMSK_MDIR,
355                       pMsgObjCfgPrms->dirMask);
357         HW_WR_FIELD32((baseAddr + DCAN_IFMSK(ifRegNum)),
358                       DCAN_IFMSK_MSK,
359                       pMsgObjCfgPrms->msgIdentifierMask);
361         /* Config STD identifier, Dir(TX/RX), ID = 1, message valid */
362         HW_WR_FIELD32((baseAddr + DCAN_IFARB(ifRegNum)),
363                       DCAN_IFARB_XTD,
364                       pMsgObjCfgPrms->xIdFlag);
366         HW_WR_FIELD32((baseAddr + DCAN_IFARB(ifRegNum)),
367                       DCAN_IFARB_MSGVAL,
368                       pMsgObjCfgPrms->msgValid);
370         HW_WR_FIELD32((baseAddr + DCAN_IFARB(ifRegNum)),
371                       DCAN_IFARB_MSGID,
372                       pMsgObjCfgPrms->msgIdentifier);
374         HW_WR_FIELD32((baseAddr + DCAN_IFARB(ifRegNum)),
375                       DCAN_IFARB_DIR,
376                       pMsgObjCfgPrms->direction);
378         /* Config umask, TXIE/RXIE, RMTEN  */
379         HW_WR_FIELD32((baseAddr + DCAN_IFMCTL(ifRegNum)),
380                       DCAN_IFMCTL_UMASK,
381                       pMsgObjCfgPrms->uMaskUsed);
383         if (DCAN_DIR_TX == pMsgObjCfgPrms->direction)
384         {
385             HW_WR_FIELD32((baseAddr + DCAN_IFMCTL(ifRegNum)),
386                           DCAN_IFMCTL_TXIE,
387                           pMsgObjCfgPrms->intEnable);
388         }
389         else
390         {
391             HW_WR_FIELD32((baseAddr + DCAN_IFMCTL(ifRegNum)),
392                           DCAN_IFMCTL_RXIE,
393                           pMsgObjCfgPrms->intEnable);
394         }
396         HW_WR_FIELD32((baseAddr + DCAN_IFMCTL(ifRegNum)),
397                       DCAN_IFMCTL_RMTEN,
398                       pMsgObjCfgPrms->remoteEnable);
400         HW_WR_FIELD32((baseAddr + DCAN_IFMCTL(ifRegNum)),
401                       DCAN_IFMCTL_EOB,
402                       pMsgObjCfgPrms->fifoEOBFlag);
404         regVal = HW_RD_REG32(baseAddr + DCAN_IFCMD(ifRegNum));
406         regVal &= ~(DCAN_IFCMD_DMAACTIVE_MASK |
407                     DCAN_IFCMD_DATAA_MASK |
408                     DCAN_IFCMD_DATAB_MASK |
409                     DCAN_IFCMD_TXRQST_NEWDAT_MASK |
410                     DCAN_IFCMD_CLRINTPND_MASK |
411                     DCAN_IFCMD_CONTROL_MASK |
412                     DCAN_IFCMD_ARB_MASK |
413                     DCAN_IFCMD_MASK_MASK |
414                     DCAN_IFCMD_MESSAGENUMBER_MASK |
415                     DCAN_IFCMD_WR_RD_MASK);
417         /* Config IFCMD Access for TX / RX  */
418         ifCmd = (DCAN_IFCMD_CLRINTPND_MASK |
419                  DCAN_IFCMD_CONTROL_MASK |
420                  DCAN_IFCMD_ARB_MASK |
421                  DCAN_IFCMD_MASK_MASK |
422                  DCAN_IFCMD_WR_RD_MASK);
424         regVal |= (ifCmd | (msgObj & DCAN_IFCMD_MESSAGENUMBER_MASK));
426         /* Now transfer from IF to RAM */
427         HW_WR_REG32(baseAddr + DCAN_IFCMD(ifRegNum), regVal);
428     }
429     else
430     {
431         retVal = STW_EFAIL;
432     }
434     return retVal;
437 int32_t DCANTransmitData(uint32_t              baseAddr,
438                          uint32_t              msgObj,
439                          uint32_t              ifRegNum,
440                          const dcanTxParams_t *pDcanTxPrms,
441                          uint32_t              timeOut)
443     int32_t  retVal    = STW_SOK;
444     uint32_t txDataVal = 0U;
445     uint32_t regVal    = 0U;
446     uint32_t ifCmd     = 0U;
448     if (TRUE != DCANIsIfRegBusy(baseAddr, ifRegNum))
449     {
450         regVal = HW_RD_REG32(baseAddr + DCAN_IFCMD(ifRegNum));
452         regVal &= ~(DCAN_IFCMD_DMAACTIVE_MASK |
453                     DCAN_IFCMD_DATAA_MASK |
454                     DCAN_IFCMD_DATAB_MASK |
455                     DCAN_IFCMD_TXRQST_NEWDAT_MASK |
456                     DCAN_IFCMD_CLRINTPND_MASK |
457                     DCAN_IFCMD_CONTROL_MASK |
458                     DCAN_IFCMD_ARB_MASK |
459                     DCAN_IFCMD_MASK_MASK |
460                     DCAN_IFCMD_MESSAGENUMBER_MASK |
461                     DCAN_IFCMD_WR_RD_MASK);
463         /* Config IFCMD Access to read IFMCTL read value  */
464         ifCmd = DCAN_IFCMD_CONTROL_MASK;
466         regVal |= (ifCmd | (msgObj & DCAN_IFCMD_MESSAGENUMBER_MASK));
468         /* Now transfer from RAM to IFMCTL */
469         HW_WR_REG32(baseAddr + DCAN_IFCMD(ifRegNum), regVal);
471         do
472         {
473             if (TRUE != DCANIsIfRegBusy(baseAddr, ifRegNum))
474             {
475                 break;
476             }
477             timeOut--;
478             if (timeOut == 0)
479             {
480                 retVal = STW_EFAIL;
481             }
482         }
483         while (timeOut);
485         if (retVal == STW_SOK)
486         {
487             regVal = HW_RD_REG32(baseAddr + DCAN_IFCMD(ifRegNum));
489             regVal &= ~(DCAN_IFCMD_DMAACTIVE_MASK |
490                         DCAN_IFCMD_DATAA_MASK |
491                         DCAN_IFCMD_DATAB_MASK |
492                         DCAN_IFCMD_TXRQST_NEWDAT_MASK |
493                         DCAN_IFCMD_CLRINTPND_MASK |
494                         DCAN_IFCMD_CONTROL_MASK |
495                         DCAN_IFCMD_ARB_MASK |
496                         DCAN_IFCMD_MASK_MASK |
497                         DCAN_IFCMD_MESSAGENUMBER_MASK |
498                         DCAN_IFCMD_WR_RD_MASK);
500             HW_WR_FIELD32((baseAddr + DCAN_IFMCTL(ifRegNum)),
501                           DCAN_IFMCTL_DATALENGTHCODE,
502                           pDcanTxPrms->dataLength);
504             HW_WR_FIELD32((baseAddr + DCAN_IFMCTL(ifRegNum)),
505                           DCAN_IFMCTL_TXRQST,
506                           DCAN_IFMCTL_TXRQST_REQUESTED);
508             if (pDcanTxPrms->dataLength > 0U)
509             {
510                 txDataVal = (((uint32_t) pDcanTxPrms->msgData[0]) |
511                              ((uint32_t) pDcanTxPrms->msgData[1] << 8U) |
512                              ((uint32_t) pDcanTxPrms->msgData[2] << 16U) |
513                              ((uint32_t) pDcanTxPrms->msgData[3] << 24U));
515                 /* Write the data values to message object.  */
516                 HW_WR_REG32(baseAddr + DCAN_IFDATA(ifRegNum), txDataVal);
518                 ifCmd = DCAN_IFCMD_DATAA_MASK;
519             }
521             if (pDcanTxPrms->dataLength > 4U)
522             {
523                 txDataVal = (((uint32_t) pDcanTxPrms->msgData[4]) |
524                              ((uint32_t) pDcanTxPrms->msgData[5] << 8U) |
525                              ((uint32_t) pDcanTxPrms->msgData[6] << 16U) |
526                              ((uint32_t) pDcanTxPrms->msgData[7] << 24U));
528                 HW_WR_REG32(baseAddr + DCAN_IFDATB(ifRegNum), txDataVal);
530                 ifCmd = (ifCmd | DCAN_IFCMD_DATAB_MASK);
531             }
533             ifCmd = (ifCmd | DCAN_IFCMD_CONTROL_MASK |
534                      DCAN_IFCMD_WR_RD_MASK);
536             regVal |= (ifCmd | (msgObj & DCAN_IFCMD_MESSAGENUMBER_MASK));
538             /* Now transfer from IF to RAM */
539             HW_WR_REG32(baseAddr + DCAN_IFCMD(ifRegNum), regVal);
541             /* Clear DLC & TXRQT Flag of IFMCTL after TX*/
542             HW_WR_FIELD32((baseAddr + DCAN_IFMCTL(ifRegNum)),
543                           DCAN_IFMCTL_DATALENGTHCODE,
544                           0);
546             HW_WR_FIELD32((baseAddr + DCAN_IFMCTL(ifRegNum)),
547                           DCAN_IFMCTL_TXRQST,
548                           DCAN_IFMCTL_TXRQST_NOREQUESTED);
549         }
550     }
551     else
552     {
553         retVal = STW_EFAIL;
554     }
556     return retVal;
559 int32_t DCANGetData(uint32_t        baseAddr,
560                     uint32_t        msgObj,
561                     uint32_t        ifRegNum,
562                     dcanRxParams_t *pDcanRxPrms,
563                     uint32_t        timeOut)
565     int32_t  retVal    = STW_SOK;
566     uint32_t msgData   = 0U;
567     uint32_t msgCtlVal = 0U;
568     uint32_t regVal    = 0U;
569     uint32_t ifCmd     = 0U;
571     if (TRUE != DCANIsIfRegBusy(baseAddr, ifRegNum))
572     {
573         regVal = HW_RD_REG32(baseAddr + DCAN_IFCMD(ifRegNum));
575         regVal &= ~(DCAN_IFCMD_DMAACTIVE_MASK |
576                     DCAN_IFCMD_DATAA_MASK |
577                     DCAN_IFCMD_DATAB_MASK |
578                     DCAN_IFCMD_TXRQST_NEWDAT_MASK |
579                     DCAN_IFCMD_CLRINTPND_MASK |
580                     DCAN_IFCMD_CONTROL_MASK |
581                     DCAN_IFCMD_ARB_MASK |
582                     DCAN_IFCMD_MASK_MASK |
583                     DCAN_IFCMD_MESSAGENUMBER_MASK |
584                     DCAN_IFCMD_WR_RD_MASK);
586         ifCmd = (DCAN_IFCMD_DATAA_MASK |
587                  DCAN_IFCMD_DATAB_MASK |
588                  DCAN_IFCMD_CONTROL_MASK |
589                  DCAN_IFCMD_TXRQST_NEWDAT_MASK);
591         regVal |= (ifCmd | (msgObj & DCAN_IFCMD_MESSAGENUMBER_MASK));
593         /* Now transfer from RAM to IF */
594         HW_WR_REG32(baseAddr + DCAN_IFCMD(ifRegNum), regVal);
596         do
597         {
598             if (TRUE != DCANIsIfRegBusy(baseAddr, ifRegNum))
599             {
600                 break;
601             }
602             timeOut--;
603             if (timeOut == 0)
604             {
605                 retVal = STW_EFAIL;
606             }
607         }
608         while (timeOut);
610         if (retVal == STW_SOK)
611         {
612             msgCtlVal = HW_RD_REG32(baseAddr + DCAN_IFMCTL(ifRegNum));
614             pDcanRxPrms->dataLength =
615                 (msgCtlVal & DCAN_IFMCTL_DATALENGTHCODE_MASK);
617             pDcanRxPrms->msgLostFlag =
618                 ((msgCtlVal & DCAN_IFMCTL_MSGLST_MASK) >>
619                  DCAN_IFMCTL_MSGLST_SHIFT);
621             /* Clear DLC & NEWDAT Flag of IFMCTL after RX*/
622             HW_WR_FIELD32((baseAddr + DCAN_IFMCTL(ifRegNum)),
623                           DCAN_IFMCTL_DATALENGTHCODE,
624                           0);
626             HW_WR_FIELD32((baseAddr + DCAN_IFMCTL(ifRegNum)),
627                           DCAN_IFMCTL_NEWDAT,
628                           DCAN_IFMCTL_NEWDAT_NONEWDATA);
630             if (pDcanRxPrms->dataLength > 0U)
631             {
632                 msgData = HW_RD_REG32(baseAddr + DCAN_IFDATA(ifRegNum));
633                 pDcanRxPrms->msgData[0] = (msgData & 0xFFU);
634                 pDcanRxPrms->msgData[1] = ((msgData & 0xFF00U) >> 8U);
635                 pDcanRxPrms->msgData[2] = ((msgData & 0xFF0000U) >> 16U);
636                 pDcanRxPrms->msgData[3] = ((msgData & 0xFF000000U) >> 24U);
637             }
639             if (pDcanRxPrms->dataLength > 4U)
640             {
641                 msgData = HW_RD_REG32(baseAddr + DCAN_IFDATB(ifRegNum));
642                 pDcanRxPrms->msgData[4] = (msgData & 0xFFU);
643                 pDcanRxPrms->msgData[5] = ((msgData & 0xFF00U) >> 8U);
644                 pDcanRxPrms->msgData[6] = ((msgData & 0xFF0000U) >> 16U);
645                 pDcanRxPrms->msgData[7] = ((msgData & 0xFF000000U) >> 24U);
646             }
647         }
648     }
649     else
650     {
651         retVal = STW_EFAIL;
652     }
654     return retVal;
657 uint32_t DCANIsTxMsgPending(uint32_t baseAddr, uint32_t msgObj)
659     uint32_t regNum, regOffSet;
660     uint32_t regVal, isPending;
662     regNum    = (msgObj - 1U) / 32U;
663     regOffSet = (msgObj - 1U) % 32U;
665     /* Return the status from DCAN_TXRQ register */
666     regVal = HW_RD_REG32(baseAddr + DCAN_TXRQ(regNum));
667     if ((regVal & ((uint32_t) 1 << regOffSet)) == ((uint32_t) 1 << regOffSet))
668     {
669         isPending = (uint32_t) TRUE;
670     }
671     else
672     {
673         isPending = (uint32_t) FALSE;
674     }
676     return (isPending);
679 uint32_t DCANHasRxMsgArrived(uint32_t baseAddr, uint32_t msgObj)
681     uint32_t regNum, regOffSet;
682     uint32_t regVal, isPending;
684     regNum    = (msgObj - 1U) / 32U;
685     regOffSet = (msgObj - 1U) % 32U;
687     /* Return the status from DCAN_NWDAT register. */
688     regVal = HW_RD_REG32(baseAddr + DCAN_NWDAT(regNum));
689     if ((regVal & ((uint32_t) 1 << regOffSet)) == ((uint32_t) 1 << regOffSet))
690     {
691         isPending = (uint32_t) TRUE;
692     }
693     else
694     {
695         isPending = (uint32_t) FALSE;
696     }
698     return (isPending);
701 uint32_t DCANIsMsgValid(uint32_t baseAddr, uint32_t msgObj)
703     uint32_t regNum    = 0U;
704     uint32_t regOffSet = 0U;
705     uint32_t regVal    = 0U;
706     uint32_t isValid   = 0U;
708     regNum    = (msgObj - 1U) / 32U;
709     regOffSet = (msgObj - 1U) % 32U;
711     /* Return the status from DCAN_MSGVAL register */
712     regVal = HW_RD_REG32(baseAddr + DCAN_MSGVAL(regNum));
713     if ((regVal & ((uint32_t) 1 << regOffSet)) == ((uint32_t) 1 << regOffSet))
714     {
715         isValid = (uint32_t) TRUE;
716     }
717     else
718     {
719         isValid = (uint32_t) FALSE;
720     }
722     return (isValid);
725 uint32_t DCANIsIfRegBusy(uint32_t baseAddr, uint32_t ifRegNum)
727     uint32_t ifRegStatus, isBusy;
729     ifRegStatus = HW_RD_REG32(baseAddr + DCAN_IFCMD(ifRegNum));
730     if ((ifRegStatus & DCAN_IFCMD_BUSY_MASK) == DCAN_IFCMD_BUSY_MASK)
731     {
732         isBusy = (uint32_t) TRUE;
733     }
734     else
735     {
736         isBusy = (uint32_t) FALSE;
737     }
739     return (isBusy);
742 void DCANConfigIntrMux(uint32_t baseAddr, uint32_t intrLineNum, uint32_t msgObj)
744     uint32_t regNum;
745     uint32_t regOffSet;
746     uint32_t regVal;
748     if (msgObj == DCAN_MAX_MSG_OBJECTS)
749     {
750         regNum    = 0U;
751         regOffSet = 0U;
752     }
753     else
754     {
755         regNum    = msgObj / 32U;
756         regOffSet = msgObj % 32U;
757     }
759     regVal = HW_RD_REG32(baseAddr + DCAN_INTMUX(regNum));
761     if (DCAN_INTR_LINE_NUM_0 == intrLineNum)
762     {
763         /* Clear the IntMux field of DCAN_INTMUX register. */
764         regVal &= ~((uint32_t) 1 << regOffSet);
765     }
766     else
767     {
768         /* Set the IntMux field of DCAN_INTMUX register. */
769         regVal |= ((uint32_t) 1 << regOffSet);
770     }
772     /* Set the DCAN_INTMUX field corresponding to msgNum. */
773     HW_WR_REG32((baseAddr + DCAN_INTMUX(regNum)), regVal);
776 uint32_t DCANGetIntrStatus(uint32_t baseAddr, uint32_t intrLineNum)
778     uint32_t retVal;
780     retVal = HW_RD_REG32(baseAddr + DCAN_INT);
781     if (DCAN_INTR_LINE_NUM_0 == intrLineNum)
782     {
783         /* Fetch the Interrupt line 0 status. */
784         retVal = (retVal & DCAN_INT_INT0ID_MASK);
785     }
786     else
787     {
788         /* Fetch the Interrupt line 1 status. */
789         retVal = ((retVal & DCAN_INT_INT1ID_MASK) >> DCAN_INT_INT1ID_SHIFT);
790     }
792     return (retVal);
795 uint32_t DCANIsMsgObjIntrPending(uint32_t baseAddr, uint32_t msgObj)
797     uint32_t regNum;
798     uint32_t regOffSet;
799     uint32_t regVal, isPending;
801     regNum    = (msgObj - 1U) / 32U;
802     regOffSet = (msgObj - 1U) % 32U;
804     /* Return the status from DCAN_INTPND register. */
805     regVal = HW_RD_REG32(baseAddr + DCAN_INTPND(regNum));
806     if ((regVal & ((uint32_t) 1 << regOffSet)) == ((uint32_t) 1 << regOffSet))
807     {
808         isPending = (uint32_t) TRUE;
809     }
810     else
811     {
812         isPending = (uint32_t) FALSE;
813     }
815     return (isPending);
818 void DCANIntrClearStatus(uint32_t baseAddr, uint32_t msgObj, uint32_t ifRegNum)
820     uint32_t regVal = 0U;
821     uint32_t ifCmd  = 0U;
823     regVal = HW_RD_REG32(baseAddr + DCAN_IFCMD(ifRegNum));
825     regVal &= ~(DCAN_IFCMD_DMAACTIVE_MASK |
826                 DCAN_IFCMD_DATAA_MASK |
827                 DCAN_IFCMD_DATAB_MASK |
828                 DCAN_IFCMD_TXRQST_NEWDAT_MASK |
829                 DCAN_IFCMD_CLRINTPND_MASK |
830                 DCAN_IFCMD_CONTROL_MASK |
831                 DCAN_IFCMD_ARB_MASK |
832                 DCAN_IFCMD_MASK_MASK |
833                 DCAN_IFCMD_MESSAGENUMBER_MASK |
834                 DCAN_IFCMD_WR_RD_MASK);
836     ifCmd = DCAN_IFCMD_CLRINTPND_MASK;
838     regVal |= (ifCmd | (msgObj & DCAN_IFCMD_MESSAGENUMBER_MASK));
840     /* Now transfer from RAM to IF  */
841     HW_WR_REG32(baseAddr + DCAN_IFCMD(ifRegNum), regVal);
844 uint32_t DCANGetErrStatus(uint32_t baseAddr)
846     /* Return the DCAN error and status register value. */
847     return (HW_RD_REG32(baseAddr + DCAN_ES));
850 uint32_t DCANGetErrCntrStatus(uint32_t baseAddr)
852     /* Return the DCAN error counter value. */
853     return (HW_RD_REG32(baseAddr + DCAN_ERRC));
856 uint32_t DCANGetParityErrStatus(uint32_t baseAddr)
858     /* Return the DCAN parity error value. */
859     return (HW_RD_REG32(baseAddr + DCAN_PERR));
862 uint32_t DCANGetMsgObjBitErrDetected(uint32_t baseAddr)
864     uint32_t retVal = (uint32_t) STW_SOK;
865 #if defined (SOC_TDA3XX)
866     /* Return the message object number where DCAN ECC Single Bit Error Code
867      * is detected
868      */
869     retVal = ((HW_RD_REG32(baseAddr + DCAN_ECC_SBE_CODE)) &
870               DCAN_ECC_SBE_CODE_MSG_NUM_MASK);
871 #else
872     retVal = DCAN_INVALID_MSG_OBJECT;
873 #endif
874     return retVal;
877 uint32_t DCANGetEccDiagErrStatus(uint32_t baseAddr)
879     uint32_t retVal = (uint32_t) STW_SOK;
880 #if defined (SOC_TDA3XX)
881     /* Returns the ECC disagnostic error status information. */
882     retVal = (HW_RD_REG32(baseAddr + DCAN_ECC_DIAG_STATUS));
883 #else
884     retVal = DCAN_INVALID_MSG_OBJECT;
885 #endif
886     return retVal;
889 uint32_t DCANGetEccErrStatus(uint32_t baseAddr)
891     uint32_t retVal = (uint32_t) STW_SOK;
892 #if defined (SOC_TDA3XX)
893     /* Returns the ECC error status information. */
894     retVal = (HW_RD_REG32(baseAddr + DCAN_ECC_CSR));
895 #else
896     retVal = DCAN_INVALID_MSG_OBJECT;
897 #endif
898     return retVal;
901 void DCANParityEnable(uint32_t baseAddr, uint32_t enablePMD)
903     if (TRUE == enablePMD)
904     {
905         /* Enable DCAN parity/ECC */
906         HW_WR_FIELD32((baseAddr + DCAN_CTL),
907                       DCAN_CTL_PMD,
908                       DCAN_PARITY_ENABLED);
909     }
910     else
911     {
912         /* Disable DCAN parity/ECC */
913         HW_WR_FIELD32((baseAddr + DCAN_CTL),
914                       DCAN_CTL_PMD,
915                       DCAN_PARITY_DISABLED);
916     }
919 void DCANTestModeEnable(uint32_t baseAddr,
920                         uint32_t enableTestMode,
921                         uint32_t testMode)
923     uint32_t regVal;
925     HW_WR_FIELD32(
926         (baseAddr + DCAN_CTL),
927         DCAN_CTL_TEST,
928         enableTestMode);
930     if (TRUE == enableTestMode)
931     {
932         regVal = HW_RD_REG32(baseAddr + DCAN_TEST);
933         regVal = (regVal & (~testMode));
934         /* Enable the DCAN test mode */
935         regVal = regVal | testMode;
936         HW_WR_REG32((baseAddr + DCAN_TEST), regVal);
937     }
940 void DCANEccDiagModeEnable(uint32_t baseAddr, uint32_t enableEccDiagMode)
942 #if defined (SOC_TDA3XX)
943     if (TRUE == enableEccDiagMode)
944     {
945         /* Enable DCAN ECC Diagnostic Mode */
946         HW_WR_FIELD32((baseAddr + DCAN_ECC_DIAG),
947                       DCAN_ECC_DIAG_ECCDIAG,
948                       DCAN_ECC_DIAG_ENABLED);
949     }
950     else
951     {
952         /* Disable DCAN ECC Diagnostic Mode */
953         HW_WR_FIELD32((baseAddr + DCAN_ECC_DIAG),
954                       DCAN_ECC_DIAG_ECCDIAG,
955                       DCAN_ECC_DIAG_DISABLED);
956     }
957 #endif
960 void DCANEccModeEnable(uint32_t baseAddr,
961                        uint32_t enableEccMode,
962                        uint32_t enableSbeEvent)
964 #if defined (SOC_TDA3XX)
965     uint32_t regVal;
967     regVal = HW_RD_REG32(baseAddr + DCAN_ECC_CSR);
969     if (TRUE == enableEccMode)
970     {
971         /* Enable SECDED Single bit Error correction */
972         HW_SET_FIELD32(
973             regVal,
974             DCAN_ECC_CSR_ECCMODE,
975             DCAN_ECC_MODE_ENABLED);
976     }
977     else
978     {
979         /* Disable SECDED Single bit Error correction */
980         HW_SET_FIELD32(
981             regVal,
982             DCAN_ECC_CSR_ECCMODE,
983             DCAN_ECC_MODE_DISABLED);
984     }
986     if (TRUE == enableSbeEvent)
987     {
988         /* Enable SECDED Single bit Error Event */
989         HW_SET_FIELD32(
990             regVal,
991             DCAN_ECC_CSR_SBE_EVT_EN,
992             DCAN_ECC_SBE_EVT_ENABLED);
993     }
994     else
995     {
996         /* Disable SECDED Single bit Error Event */
997         HW_SET_FIELD32(
998             regVal,
999             DCAN_ECC_CSR_SBE_EVT_EN,
1000             DCAN_ECC_SBE_EVT_DISABLED);
1001     }
1002     HW_WR_REG32((baseAddr + DCAN_ECC_CSR), regVal);
1003 #endif
1006 int32_t DCANClrEccErrStatus(uint32_t baseAddr, const dcanEccErrStatus_t *errClr)
1008     int32_t retVal = STW_SOK;
1009 #if defined (SOC_TDA3XX)
1010     if (NULL == errClr)
1011     {
1012         retVal = STW_EFAIL;
1013     }
1014     else
1015     {
1016         /* Writing 1 clears the bit, writing 0 has no effect */
1017         HW_WR_FIELD32(baseAddr + DCAN_ECC_CSR, DCAN_ECC_CSR_SE_FLAG,
1018                       errClr->singleBitErr);
1019         HW_WR_FIELD32(baseAddr + DCAN_ECC_CSR, DCAN_ECC_CSR_DE_FLAG,
1020                       errClr->doubleBitErr);
1021     }
1022 #endif
1023     return retVal;
1026 int32_t DCANClrEccDiagErrStatus(uint32_t                  baseAddr,
1027                                 const dcanEccErrStatus_t *errClr)
1029     int32_t retVal = STW_SOK;
1030 #if defined (SOC_TDA3XX)
1031     if (NULL == errClr)
1032     {
1033         retVal = STW_EFAIL;
1034     }
1035     else
1036     {
1037         /* Writing 1 clears the bit, writing 0 has no effect */
1038         HW_WR_FIELD32(baseAddr + DCAN_ECC_DIAG_STATUS,
1039                       DCAN_ECC_DIAG_STATUS_SE_FLAG,
1040                       errClr->singleBitErr);
1041         HW_WR_FIELD32(baseAddr + DCAN_ECC_DIAG_STATUS,
1042                       DCAN_ECC_DIAG_STATUS_DE_FLAG,
1043                       errClr->doubleBitErr);
1044     }
1045 #endif
1046     return retVal;
1049 void DCANClrParityIntrStatus(uint32_t baseAddr)
1051     HW_WR_FIELD32(baseAddr + DCAN_ES, DCAN_ES_PER,
1052                   DCAN_ES_PER_EN_2_0X1);
1055 /********************************* End of file ******************************/