EE445M RTOS
Taken at the University of Texas Spring 2015
can.c
Go to the documentation of this file.
1 //*****************************************************************************
2 //
3 // can.c - Driver for the CAN module.
4 //
5 // Copyright (c) 2006-2014 Texas Instruments Incorporated. All rights reserved.
6 // Software License Agreement
7 //
8 // Redistribution and use in source and binary forms, with or without
9 // modification, are permitted provided that the following conditions
10 // are met:
11 //
12 // Redistributions of source code must retain the above copyright
13 // notice, this list of conditions and the following disclaimer.
14 //
15 // Redistributions in binary form must reproduce the above copyright
16 // notice, this list of conditions and the following disclaimer in the
17 // documentation and/or other materials provided with the
18 // distribution.
19 //
20 // Neither the name of Texas Instruments Incorporated nor the names of
21 // its contributors may be used to endorse or promote products derived
22 // from this software without specific prior written permission.
23 //
24 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
27 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
28 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
29 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
30 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
31 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
32 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
34 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 //
36 // This is part of revision 2.1.0.12573 of the Tiva Peripheral Driver Library.
37 //
38 //*****************************************************************************
39 
40 //*****************************************************************************
41 //
44 //
45 //*****************************************************************************
46 
47 #include <stdbool.h>
48 #include <stdint.h>
49 #include "inc/hw_can.h"
50 #include "inc/hw_ints.h"
51 #include "inc/hw_nvic.h"
52 #include "inc/hw_memmap.h"
53 #include "inc/hw_sysctl.h"
54 #include "inc/hw_types.h"
55 #include "driverlib/can.h"
56 #include "driverlib/debug.h"
57 #include "driverlib/interrupt.h"
58 
59 //*****************************************************************************
60 //
61 // This is the maximum number that can be stored as an 11bit Message
62 // identifier.
63 //
64 //*****************************************************************************
65 #define CAN_MAX_11BIT_MSG_ID 0x7ff
66 
67 //*****************************************************************************
68 //
69 // The maximum CAN bit timing divisor is 19.
70 //
71 //*****************************************************************************
72 #define CAN_MAX_BIT_DIVISOR 19
73 
74 //*****************************************************************************
75 //
76 // The minimum CAN bit timing divisor is 4.
77 //
78 //*****************************************************************************
79 #define CAN_MIN_BIT_DIVISOR 4
80 
81 //*****************************************************************************
82 //
83 // The maximum CAN pre-divisor is 1024.
84 //
85 //*****************************************************************************
86 #define CAN_MAX_PRE_DIVISOR 1024
87 
88 //*****************************************************************************
89 //
90 // The minimum CAN pre-divisor is 1.
91 //
92 //*****************************************************************************
93 #define CAN_MIN_PRE_DIVISOR 1
94 
95 //*****************************************************************************
96 //
97 // Converts a set of CAN bit timing values into the value that needs to be
98 // programmed into the CAN_BIT register to achieve those timings.
99 //
100 //*****************************************************************************
101 #define CAN_BIT_VALUE(seg1, seg2, sjw) \
102  ((((seg1 - 1) << CAN_BIT_TSEG1_S) & \
103  CAN_BIT_TSEG1_M) | \
104  (((seg2 - 1) << CAN_BIT_TSEG2_S) & \
105  CAN_BIT_TSEG2_M) | \
106  (((sjw - 1) << CAN_BIT_SJW_S) & \
107  CAN_BIT_SJW_M))
108 
109 //*****************************************************************************
110 //
111 // This table is used by the CANBitRateSet() API as the register defaults for
112 // the bit timing values.
113 //
114 //*****************************************************************************
115 static const uint16_t g_ui16CANBitValues[] =
116 {
117  CAN_BIT_VALUE(2, 1, 1), // 4 clocks/bit
118  CAN_BIT_VALUE(3, 1, 1), // 5 clocks/bit
119  CAN_BIT_VALUE(3, 2, 2), // 6 clocks/bit
120  CAN_BIT_VALUE(4, 2, 2), // 7 clocks/bit
121  CAN_BIT_VALUE(4, 3, 3), // 8 clocks/bit
122  CAN_BIT_VALUE(5, 3, 3), // 9 clocks/bit
123  CAN_BIT_VALUE(5, 4, 4), // 10 clocks/bit
124  CAN_BIT_VALUE(6, 4, 4), // 11 clocks/bit
125  CAN_BIT_VALUE(6, 5, 4), // 12 clocks/bit
126  CAN_BIT_VALUE(7, 5, 4), // 13 clocks/bit
127  CAN_BIT_VALUE(7, 6, 4), // 14 clocks/bit
128  CAN_BIT_VALUE(8, 6, 4), // 15 clocks/bit
129  CAN_BIT_VALUE(8, 7, 4), // 16 clocks/bit
130  CAN_BIT_VALUE(9, 7, 4), // 17 clocks/bit
131  CAN_BIT_VALUE(9, 8, 4), // 18 clocks/bit
132  CAN_BIT_VALUE(10, 8, 4) // 19 clocks/bit
133 };
134 
135 //*****************************************************************************
136 //
146 //
147 //*****************************************************************************
148 #ifdef DEBUG
149 static bool
150 _CANBaseValid(uint32_t ui32Base)
151 {
152  return((ui32Base == CAN0_BASE) || (ui32Base == CAN1_BASE));
153 }
154 #endif
155 
156 //*****************************************************************************
157 //
167 //
168 //*****************************************************************************
169 static uint_fast8_t
170 _CANIntNumberGet(uint32_t ui32Base)
171 {
172  uint_fast8_t ui8Int;
173 
174  ASSERT((ui32Base == CAN0_BASE) || (ui32Base == CAN1_BASE));
175 
176  ui8Int = 0;
177 
178  //
179  // Find the valid interrupt number for this CAN controller.
180  //
181  if(CLASS_IS_TM4C123)
182  {
183  if(ui32Base == CAN0_BASE)
184  {
185  ui8Int = INT_CAN0_TM4C123;
186  }
187  else if(ui32Base == CAN1_BASE)
188  {
189  ui8Int = INT_CAN1_TM4C123;
190  }
191  }
192  else if(CLASS_IS_TM4C129)
193  {
194  if(ui32Base == CAN0_BASE)
195  {
196  ui8Int = INT_CAN0_TM4C129;
197  }
198  else if(ui32Base == CAN1_BASE)
199  {
200  ui8Int = INT_CAN1_TM4C129;
201  }
202  }
203 
204  return(ui8Int);
205 }
206 
207 //*****************************************************************************
208 //
226 //
227 //*****************************************************************************
228 static void
229 _CANDataRegWrite(uint8_t *pui8Data, uint32_t *pui32Register, uint32_t ui32Size)
230 {
231  uint32_t ui32Idx, ui32Value;
232 
233  //
234  // Loop always copies 1 or 2 bytes per iteration.
235  //
236  for(ui32Idx = 0; ui32Idx < ui32Size; )
237  {
238  //
239  // Write out the data 16 bits at a time since this is how the registers
240  // are aligned in memory.
241  //
242  ui32Value = pui8Data[ui32Idx++];
243 
244  //
245  // Only write the second byte if needed otherwise the value is zero.
246  //
247  if(ui32Idx < ui32Size)
248  {
249  ui32Value |= (pui8Data[ui32Idx++] << 8);
250  }
251 
252  HWREG(pui32Register++) = ui32Value;
253  }
254 }
255 
256 //*****************************************************************************
257 //
275 //
276 //*****************************************************************************
277 static void
278 _CANDataRegRead(uint8_t *pui8Data, uint32_t *pui32Register, uint32_t ui32Size)
279 {
280  uint32_t ui32Idx, ui32Value;
281 
282  //
283  // Loop always copies 1 or 2 bytes per iteration.
284  //
285  for(ui32Idx = 0; ui32Idx < ui32Size; )
286  {
287  //
288  // Read out the data 16 bits at a time since this is how the registers
289  // are aligned in memory.
290  //
291  ui32Value = HWREG(pui32Register++);
292 
293  //
294  // Store the first byte.
295  //
296  pui8Data[ui32Idx++] = (uint8_t)ui32Value;
297 
298  //
299  // Only read the second byte if needed.
300  //
301  if(ui32Idx < ui32Size)
302  {
303  pui8Data[ui32Idx++] = (uint8_t)(ui32Value >> 8);
304  }
305  }
306 }
307 
308 //*****************************************************************************
309 //
322 //
323 //*****************************************************************************
324 void
325 CANInit(uint32_t ui32Base)
326 {
327  uint32_t ui32Msg;
328 
329  //
330  // Check the arguments.
331  //
332  ASSERT(_CANBaseValid(ui32Base));
333 
334  //
335  // Place CAN controller in init state, regardless of previous state. This
336  // puts controller in idle, and allow the message object RAM to be
337  // programmed.
338  //
339  HWREG(ui32Base + CAN_O_CTL) = CAN_CTL_INIT;
340 
341  //
342  // Wait for busy bit to clear
343  //
344  while(HWREG(ui32Base + CAN_O_IF1CRQ) & CAN_IF1CRQ_BUSY)
345  {
346  }
347 
348  //
349  // Clear the message value bit in the arbitration register. This indicates
350  // the message is not valid and is a "safe" condition to leave the message
351  // object. The same arb reg is used to program all the message objects.
352  //
355  HWREG(ui32Base + CAN_O_IF1ARB2) = 0;
356  HWREG(ui32Base + CAN_O_IF1MCTL) = 0;
357 
358  //
359  // Loop through to program all 32 message objects
360  //
361  for(ui32Msg = 1; ui32Msg <= 32; ui32Msg++)
362  {
363  //
364  // Wait for busy bit to clear
365  //
366  while(HWREG(ui32Base + CAN_O_IF1CRQ) & CAN_IF1CRQ_BUSY)
367  {
368  }
369 
370  //
371  // Initiate programming the message object
372  //
373  HWREG(ui32Base + CAN_O_IF1CRQ) = ui32Msg;
374  }
375 
376  //
377  // Make sure that the interrupt and new data flags are updated for the
378  // message objects.
379  //
380  HWREG(ui32Base + CAN_O_IF1CMSK) = (CAN_IF1CMSK_NEWDAT |
382 
383  //
384  // Loop through to program all 32 message objects
385  //
386  for(ui32Msg = 1; ui32Msg <= 32; ui32Msg++)
387  {
388  //
389  // Wait for busy bit to clear.
390  //
391  while(HWREG(ui32Base + CAN_O_IF1CRQ) & CAN_IF1CRQ_BUSY)
392  {
393  }
394 
395  //
396  // Initiate programming the message object
397  //
398  HWREG(ui32Base + CAN_O_IF1CRQ) = ui32Msg;
399  }
400 
401  //
402  // Acknowledge any pending status interrupts.
403  //
404  HWREG(ui32Base + CAN_O_STS);
405 }
406 
407 //*****************************************************************************
408 //
421 //
422 //*****************************************************************************
423 void
424 CANEnable(uint32_t ui32Base)
425 {
426  //
427  // Check the arguments.
428  //
429  ASSERT(_CANBaseValid(ui32Base));
430 
431  //
432  // Clear the init bit in the control register.
433  //
434  HWREG(ui32Base + CAN_O_CTL) &= ~CAN_CTL_INIT;
435 }
436 
437 //*****************************************************************************
438 //
450 //
451 //*****************************************************************************
452 void
453 CANDisable(uint32_t ui32Base)
454 {
455  //
456  // Check the arguments.
457  //
458  ASSERT(_CANBaseValid(ui32Base));
459 
460  //
461  // Set the init bit in the control register.
462  //
463  HWREG(ui32Base + CAN_O_CTL) |= CAN_CTL_INIT;
464 }
465 
466 //*****************************************************************************
467 //
480 //
481 //*****************************************************************************
482 void
483 CANBitTimingGet(uint32_t ui32Base, tCANBitClkParms *psClkParms)
484 {
485  uint32_t ui32BitReg;
486 
487  //
488  // Check the arguments.
489  //
490  ASSERT(_CANBaseValid(ui32Base));
491  ASSERT(psClkParms);
492 
493  //
494  // Read out all the bit timing values from the CAN controller registers.
495  //
496  ui32BitReg = HWREG(ui32Base + CAN_O_BIT);
497 
498  //
499  // Set the phase 2 segment.
500  //
501  psClkParms->ui32Phase2Seg =
502  ((ui32BitReg & CAN_BIT_TSEG2_M) >> CAN_BIT_TSEG2_S) + 1;
503 
504  //
505  // Set the phase 1 segment.
506  //
507  psClkParms->ui32SyncPropPhase1Seg =
508  ((ui32BitReg & CAN_BIT_TSEG1_M) >> CAN_BIT_TSEG1_S) + 1;
509 
510  //
511  // Set the synchronous jump width.
512  //
513  psClkParms->ui32SJW = ((ui32BitReg & CAN_BIT_SJW_M) >> CAN_BIT_SJW_S) + 1;
514 
515  //
516  // Set the pre-divider for the CAN bus bit clock.
517  //
518  psClkParms->ui32QuantumPrescaler =
519  ((ui32BitReg & CAN_BIT_BRP_M) |
520  ((HWREG(ui32Base + CAN_O_BRPE) & CAN_BRPE_BRPE_M) << 6)) + 1;
521 }
522 
523 //*****************************************************************************
524 //
552 //*****************************************************************************
553 uint32_t
554 CANBitRateSet(uint32_t ui32Base, uint32_t ui32SourceClock,
555  uint32_t ui32BitRate)
556 {
557  uint32_t ui32DesiredRatio;
558  uint32_t ui32CANBits;
559  uint32_t ui32PreDivide;
560  uint32_t ui32RegValue;
561  uint16_t ui16CANCTL;
562 
563  //
564  // Check the arguments.
565  //
566  ASSERT(_CANBaseValid(ui32Base));
567  ASSERT(ui32SourceClock);
568  ASSERT(ui32BitRate);
569 
570  //
571  // Calculate the desired clock rate.
572  //
573  ui32DesiredRatio = ui32SourceClock / ui32BitRate;
574 
575  //
576  // Make sure that the ratio of CAN bit rate to processor clock is not too
577  // small or too large.
578  //
579  ASSERT(ui32DesiredRatio <= (CAN_MAX_PRE_DIVISOR * CAN_MAX_BIT_DIVISOR));
580  ASSERT(ui32DesiredRatio >= (CAN_MIN_PRE_DIVISOR * CAN_MIN_BIT_DIVISOR));
581 
582  //
583  // Make sure that the Desired Ratio is not too large. This enforces the
584  // requirement that the bit rate is larger than requested.
585  //
586  if((ui32SourceClock / ui32DesiredRatio) > ui32BitRate)
587  {
588  ui32DesiredRatio += 1;
589  }
590 
591  //
592  // Check all possible values to find a matching value.
593  //
594  while(ui32DesiredRatio <= (CAN_MAX_PRE_DIVISOR * CAN_MAX_BIT_DIVISOR))
595  {
596  //
597  // Loop through all possible CAN bit divisors.
598  //
599  for(ui32CANBits = CAN_MAX_BIT_DIVISOR;
600  ui32CANBits >= CAN_MIN_BIT_DIVISOR; ui32CANBits--)
601  {
602  //
603  // For a given CAN bit divisor save the pre divisor.
604  //
605  ui32PreDivide = ui32DesiredRatio / ui32CANBits;
606 
607  //
608  // If the calculated divisors match the desired clock ratio then
609  // return these bit rate and set the CAN bit timing.
610  //
611  if((ui32PreDivide * ui32CANBits) == ui32DesiredRatio)
612  {
613  //
614  // Start building the bit timing value by adding the bit timing
615  // in time quanta.
616  //
617  ui32RegValue = g_ui16CANBitValues[ui32CANBits -
619 
620  //
621  // To set the bit timing register, the controller must be
622  // placed in init mode (if not already), and also configuration
623  // change bit enabled. The state of the register must be
624  // saved so it can be restored.
625  //
626  ui16CANCTL = HWREG(ui32Base + CAN_O_CTL);
627  HWREG(ui32Base + CAN_O_CTL) = ui16CANCTL | CAN_CTL_INIT |
628  CAN_CTL_CCE;
629 
630  //
631  // Now add in the pre-scalar on the bit rate.
632  //
633  ui32RegValue |= ((ui32PreDivide - 1) & CAN_BIT_BRP_M);
634 
635  //
636  // Set the clock bits in the and the lower bits of the
637  // pre-scalar.
638  //
639  HWREG(ui32Base + CAN_O_BIT) = ui32RegValue;
640 
641  //
642  // Set the divider upper bits in the extension register.
643  //
644  HWREG(ui32Base + CAN_O_BRPE) = ((ui32PreDivide - 1) >> 6) &
646 
647  //
648  // Restore the saved CAN Control register.
649  //
650  HWREG(ui32Base + CAN_O_CTL) = ui16CANCTL;
651 
652  //
653  // Return the computed bit rate.
654  //
655  return(ui32SourceClock / (ui32PreDivide * ui32CANBits));
656  }
657  }
658 
659  //
660  // Move the divisor up one and look again. Only in rare cases are
661  // more than 2 loops required to find the value.
662  //
663  ui32DesiredRatio++;
664  }
665 
666  //
667  // A valid combination could not be found, so return 0 to indicate that the
668  // bit rate was not changed.
669  //
670  return(0);
671 }
672 
673 //*****************************************************************************
674 //
710 //
711 //*****************************************************************************
712 void
713 CANBitTimingSet(uint32_t ui32Base, tCANBitClkParms *psClkParms)
714 {
715  uint32_t ui32BitReg, ui32SavedInit;
716 
717  //
718  // Check the arguments.
719  //
720  ASSERT(_CANBaseValid(ui32Base));
721  ASSERT(psClkParms);
722 
723  //
724  // The phase 1 segment must be in the range from 2 to 16.
725  //
726  ASSERT((psClkParms->ui32SyncPropPhase1Seg >= 2) &&
727  (psClkParms->ui32SyncPropPhase1Seg <= 16));
728 
729  //
730  // The phase 2 segment must be in the range from 1 to 8.
731  //
732  ASSERT((psClkParms->ui32Phase2Seg >= 1) &&
733  (psClkParms->ui32Phase2Seg <= 8));
734 
735  //
736  // The synchronous jump windows must be in the range from 1 to 4.
737  //
738  ASSERT((psClkParms->ui32SJW >= 1) && (psClkParms->ui32SJW <= 4));
739 
740  //
741  // The CAN clock pre-divider must be in the range from 1 to 1024.
742  //
743  ASSERT((psClkParms->ui32QuantumPrescaler <= 1024) &&
744  (psClkParms->ui32QuantumPrescaler >= 1));
745 
746  //
747  // To set the bit timing register, the controller must be placed in init
748  // mode (if not already), and also configuration change bit enabled. State
749  // of the init bit must be saved so it can be restored at the end.
750  //
751  ui32SavedInit = HWREG(ui32Base + CAN_O_CTL);
752  HWREG(ui32Base + CAN_O_CTL) = ui32SavedInit | CAN_CTL_INIT | CAN_CTL_CCE;
753 
754  //
755  // Set the bit fields of the bit timing register according to the parms.
756  //
757  ui32BitReg = (((psClkParms->ui32Phase2Seg - 1) << CAN_BIT_TSEG2_S) &
759  ui32BitReg |= (((psClkParms->ui32SyncPropPhase1Seg - 1) <<
761  ui32BitReg |= ((psClkParms->ui32SJW - 1) << CAN_BIT_SJW_S) & CAN_BIT_SJW_M;
762  ui32BitReg |= (psClkParms->ui32QuantumPrescaler - 1) & CAN_BIT_BRP_M;
763  HWREG(ui32Base + CAN_O_BIT) = ui32BitReg;
764 
765  //
766  // Set the divider upper bits in the extension register.
767  //
768  HWREG(ui32Base + CAN_O_BRPE) =
769  ((psClkParms->ui32QuantumPrescaler - 1) >> 6) & CAN_BRPE_BRPE_M;
770 
771  //
772  // Clear the config change bit, and restore the init bit.
773  //
774  ui32SavedInit &= ~CAN_CTL_CCE;
775 
776  //
777  // If Init was not set before, then clear it.
778  //
779  if(ui32SavedInit & CAN_CTL_INIT)
780  {
781  ui32SavedInit &= ~CAN_CTL_INIT;
782  }
783 
784  HWREG(ui32Base + CAN_O_CTL) = ui32SavedInit;
785 }
786 
787 //*****************************************************************************
788 //
810 //
811 //*****************************************************************************
812 void
813 CANIntRegister(uint32_t ui32Base, void (*pfnHandler)(void))
814 {
815  uint_fast8_t ui8IntNumber;
816 
817  //
818  // Check the arguments.
819  //
820  ASSERT(_CANBaseValid(ui32Base));
821 
822  //
823  // Get the actual interrupt number for this CAN controller.
824  //
825  ui8IntNumber = _CANIntNumberGet(ui32Base);
826  ASSERT(ui8IntNumber != 0);
827 
828  //
829  // Register the interrupt handler.
830  //
831  IntRegister(ui8IntNumber, pfnHandler);
832 
833  //
834  // Enable the Ethernet interrupt.
835  //
836  IntEnable(ui8IntNumber);
837 }
838 
839 //*****************************************************************************
840 //
852 //
853 //*****************************************************************************
854 void
855 CANIntUnregister(uint32_t ui32Base)
856 {
857  uint_fast8_t ui8IntNumber;
858 
859  //
860  // Check the arguments.
861  //
862  ASSERT(_CANBaseValid(ui32Base));
863 
864  //
865  // Get the actual interrupt number for this CAN controller.
866  //
867  ui8IntNumber = _CANIntNumberGet(ui32Base);
868  ASSERT(ui8IntNumber != 0);
869 
870  //
871  // Disable the CAN interrupt.
872  //
873  IntDisable(ui8IntNumber);
874 
875  //
876  // Register the interrupt handler.
877  //
878  IntUnregister(ui8IntNumber);
879 }
880 
881 //*****************************************************************************
882 //
909 //
910 //*****************************************************************************
911 void
912 CANIntEnable(uint32_t ui32Base, uint32_t ui32IntFlags)
913 {
914  //
915  // Check the arguments.
916  //
917  ASSERT(_CANBaseValid(ui32Base));
918  ASSERT((ui32IntFlags & ~(CAN_CTL_EIE | CAN_CTL_SIE | CAN_CTL_IE)) == 0);
919 
920  //
921  // Enable the specified interrupts.
922  //
923  HWREG(ui32Base + CAN_O_CTL) |= ui32IntFlags;
924 }
925 
926 //*****************************************************************************
927 //
941 //
942 //*****************************************************************************
943 void
944 CANIntDisable(uint32_t ui32Base, uint32_t ui32IntFlags)
945 {
946  //
947  // Check the arguments.
948  //
949  ASSERT(_CANBaseValid(ui32Base));
950  ASSERT((ui32IntFlags & ~(CAN_CTL_EIE | CAN_CTL_SIE | CAN_CTL_IE)) == 0);
951 
952  //
953  // Disable the specified interrupts.
954  //
955  HWREG(ui32Base + CAN_O_CTL) &= ~ui32IntFlags;
956 }
957 
958 //*****************************************************************************
959 //
992 //
993 //*****************************************************************************
994 uint32_t
995 CANIntStatus(uint32_t ui32Base, tCANIntStsReg eIntStsReg)
996 {
997  uint32_t ui32Status;
998 
999  //
1000  // Check the arguments.
1001  //
1002  ASSERT(_CANBaseValid(ui32Base));
1003 
1004  //
1005  // See which status the caller is looking for.
1006  //
1007  switch(eIntStsReg)
1008  {
1009  //
1010  // The caller wants the global interrupt status for the CAN controller
1011  // specified by ui32Base.
1012  //
1013  case CAN_INT_STS_CAUSE:
1014  {
1015  ui32Status = HWREG(ui32Base + CAN_O_INT);
1016  break;
1017  }
1018 
1019  //
1020  // The caller wants the current message status interrupt for all
1021  // messages.
1022  //
1023  case CAN_INT_STS_OBJECT:
1024  {
1025  //
1026  // Read and combine both 16 bit values into one 32bit status.
1027  //
1028  ui32Status = (HWREG(ui32Base + CAN_O_MSG1INT) &
1030  ui32Status |= (HWREG(ui32Base + CAN_O_MSG2INT) << 16);
1031  break;
1032  }
1033 
1034  //
1035  // Request was for unknown status so just return 0.
1036  //
1037  default:
1038  {
1039  ui32Status = 0;
1040  break;
1041  }
1042  }
1043 
1044  //
1045  // Return the interrupt status value
1046  //
1047  return(ui32Status);
1048 }
1049 
1050 //*****************************************************************************
1051 //
1081 //
1082 //*****************************************************************************
1083 void
1084 CANIntClear(uint32_t ui32Base, uint32_t ui32IntClr)
1085 {
1086  //
1087  // Check the arguments.
1088  //
1089  ASSERT(_CANBaseValid(ui32Base));
1090  ASSERT((ui32IntClr == CAN_INT_INTID_STATUS) ||
1091  ((ui32IntClr >= 1) && (ui32IntClr <= 32)));
1092 
1093  if(ui32IntClr == CAN_INT_INTID_STATUS)
1094  {
1095  //
1096  // Simply read and discard the status to clear the interrupt.
1097  //
1098  HWREG(ui32Base + CAN_O_STS);
1099  }
1100  else
1101  {
1102  //
1103  // Wait to be sure that this interface is not busy.
1104  //
1105  while(HWREG(ui32Base + CAN_O_IF1CRQ) & CAN_IF1CRQ_BUSY)
1106  {
1107  }
1108 
1109  //
1110  // Only change the interrupt pending state by setting only the
1111  // CAN_IF1CMSK_CLRINTPND bit.
1112  //
1114 
1115  //
1116  // Send the clear pending interrupt command to the CAN controller.
1117  //
1118  HWREG(ui32Base + CAN_O_IF1CRQ) = ui32IntClr & CAN_IF1CRQ_MNUM_M;
1119 
1120  //
1121  // Wait to be sure that this interface is not busy.
1122  //
1123  while(HWREG(ui32Base + CAN_O_IF1CRQ) & CAN_IF1CRQ_BUSY)
1124  {
1125  }
1126  }
1127 }
1128 
1129 //*****************************************************************************
1130 //
1141 //
1142 //*****************************************************************************
1143 void
1144 CANRetrySet(uint32_t ui32Base, bool bAutoRetry)
1145 {
1146  uint32_t ui32CtlReg;
1147 
1148  //
1149  // Check the arguments.
1150  //
1151  ASSERT(_CANBaseValid(ui32Base));
1152 
1153  ui32CtlReg = HWREG(ui32Base + CAN_O_CTL);
1154 
1155  //
1156  // Conditionally set the DAR bit to enable/disable auto-retry.
1157  //
1158  if(bAutoRetry)
1159  {
1160  //
1161  // Clearing the DAR bit tells the controller to not disable the
1162  // auto-retry of messages which were not transmitted or received
1163  // correctly.
1164  //
1165  ui32CtlReg &= ~CAN_CTL_DAR;
1166  }
1167  else
1168  {
1169  //
1170  // Setting the DAR bit tells the controller to disable the auto-retry
1171  // of messages which were not transmitted or received correctly.
1172  //
1173  ui32CtlReg |= CAN_CTL_DAR;
1174  }
1175 
1176  HWREG(ui32Base + CAN_O_CTL) = ui32CtlReg;
1177 }
1178 
1179 //*****************************************************************************
1180 //
1190 //
1191 //*****************************************************************************
1192 bool
1193 CANRetryGet(uint32_t ui32Base)
1194 {
1195  //
1196  // Check the arguments.
1197  //
1198  ASSERT(_CANBaseValid(ui32Base));
1199 
1200  //
1201  // Read the disable automatic retry setting from the CAN controller.
1202  //
1203  if(HWREG(ui32Base + CAN_O_CTL) & CAN_CTL_DAR)
1204  {
1205  //
1206  // Automatic data retransmission is not enabled.
1207  //
1208  return(false);
1209  }
1210 
1211  //
1212  // Automatic data retransmission is enabled.
1213  //
1214  return(true);
1215 }
1216 
1217 //*****************************************************************************
1218 //
1273 //
1274 //*****************************************************************************
1275 uint32_t
1276 CANStatusGet(uint32_t ui32Base, tCANStsReg eStatusReg)
1277 {
1278  uint32_t ui32Status;
1279 
1280  //
1281  // Check the arguments.
1282  //
1283  ASSERT(_CANBaseValid(ui32Base));
1284 
1285  switch(eStatusReg)
1286  {
1287  //
1288  // Just return the global CAN status register since that is what was
1289  // requested.
1290  //
1291  case CAN_STS_CONTROL:
1292  {
1293  ui32Status = HWREG(ui32Base + CAN_O_STS);
1294  HWREG(ui32Base + CAN_O_STS) = ~(CAN_STS_RXOK | CAN_STS_TXOK |
1295  CAN_STS_LEC_M);
1296  break;
1297  }
1298 
1299  //
1300  // Combine the Transmit status bits into one 32bit value.
1301  //
1302  case CAN_STS_TXREQUEST:
1303  {
1304  ui32Status = HWREG(ui32Base + CAN_O_TXRQ1);
1305  ui32Status |= HWREG(ui32Base + CAN_O_TXRQ2) << 16;
1306  break;
1307  }
1308 
1309  //
1310  // Combine the New Data status bits into one 32bit value.
1311  //
1312  case CAN_STS_NEWDAT:
1313  {
1314  ui32Status = HWREG(ui32Base + CAN_O_NWDA1);
1315  ui32Status |= HWREG(ui32Base + CAN_O_NWDA2) << 16;
1316  break;
1317  }
1318 
1319  //
1320  // Combine the Message valid status bits into one 32bit value.
1321  //
1322  case CAN_STS_MSGVAL:
1323  {
1324  ui32Status = HWREG(ui32Base + CAN_O_MSG1VAL);
1325  ui32Status |= HWREG(ui32Base + CAN_O_MSG2VAL) << 16;
1326  break;
1327  }
1328 
1329  //
1330  // Unknown CAN status requested so return 0.
1331  //
1332  default:
1333  {
1334  ui32Status = 0;
1335  break;
1336  }
1337  }
1338  return(ui32Status);
1339 }
1340 
1341 //*****************************************************************************
1342 //
1361 //
1362 //*****************************************************************************
1363 bool
1364 CANErrCntrGet(uint32_t ui32Base, uint32_t *pui32RxCount,
1365  uint32_t *pui32TxCount)
1366 {
1367  uint32_t ui32CANError;
1368 
1369  //
1370  // Check the arguments.
1371  //
1372  ASSERT(_CANBaseValid(ui32Base));
1373 
1374  //
1375  // Read the current count of transmit/receive errors.
1376  //
1377  ui32CANError = HWREG(ui32Base + CAN_O_ERR);
1378 
1379  //
1380  // Extract the error numbers from the register value.
1381  //
1382  *pui32RxCount = (ui32CANError & CAN_ERR_REC_M) >> CAN_ERR_REC_S;
1383  *pui32TxCount = (ui32CANError & CAN_ERR_TEC_M) >> CAN_ERR_TEC_S;
1384 
1385  if(ui32CANError & CAN_ERR_RP)
1386  {
1387  return(true);
1388  }
1389  return(false);
1390 }
1391 
1392 //*****************************************************************************
1393 //
1474 //
1475 //*****************************************************************************
1476 void
1477 CANMessageSet(uint32_t ui32Base, uint32_t ui32ObjID,
1478  tCANMsgObject *psMsgObject, tMsgObjType eMsgType)
1479 {
1480  uint16_t ui16CmdMaskReg;
1481  uint16_t ui16MaskReg0, ui16MaskReg1;
1482  uint16_t ui16ArbReg0, ui16ArbReg1;
1483  uint16_t ui16MsgCtrl;
1484  bool bTransferData;
1485  bool bUseExtendedID;
1486 
1487  bTransferData = 0;
1488 
1489  //
1490  // Check the arguments.
1491  //
1492  ASSERT(_CANBaseValid(ui32Base));
1493  ASSERT((ui32ObjID <= 32) && (ui32ObjID != 0));
1494  ASSERT((eMsgType == MSG_OBJ_TYPE_TX) ||
1495  (eMsgType == MSG_OBJ_TYPE_TX_REMOTE) ||
1496  (eMsgType == MSG_OBJ_TYPE_RX) ||
1497  (eMsgType == MSG_OBJ_TYPE_RX_REMOTE) ||
1498  (eMsgType == MSG_OBJ_TYPE_TX_REMOTE) ||
1499  (eMsgType == MSG_OBJ_TYPE_RXTX_REMOTE));
1500 
1501  //
1502  // Wait for busy bit to clear
1503  //
1504  while(HWREG(ui32Base + CAN_O_IF1CRQ) & CAN_IF1CRQ_BUSY)
1505  {
1506  }
1507 
1508  //
1509  // See if we need to use an extended identifier or not.
1510  //
1511  if((psMsgObject->ui32MsgID > CAN_MAX_11BIT_MSG_ID) ||
1512  (psMsgObject->ui32Flags & MSG_OBJ_EXTENDED_ID))
1513  {
1514  bUseExtendedID = 1;
1515  }
1516  else
1517  {
1518  bUseExtendedID = 0;
1519  }
1520 
1521  //
1522  // This is always a write to the Message object as this call is setting a
1523  // message object. This call always sets all size bits so it sets
1524  // both data bits. The call uses the CONTROL register to set control
1525  // bits so this bit needs to be set as well.
1526  //
1527  ui16CmdMaskReg = (CAN_IF1CMSK_WRNRD | CAN_IF1CMSK_DATAA |
1529 
1530  //
1531  // Initialize the values to a known state before filling them in based on
1532  // the type of message object that is being configured.
1533  //
1534  ui16ArbReg0 = 0;
1535  ui16ArbReg1 = 0;
1536  ui16MsgCtrl = 0;
1537  ui16MaskReg0 = 0;
1538  ui16MaskReg1 = 0;
1539 
1540  switch(eMsgType)
1541  {
1542  //
1543  // Transmit message object.
1544  //
1545  case MSG_OBJ_TYPE_TX:
1546  {
1547  //
1548  // Set the TXRQST bit and the reset the rest of the register.
1549  //
1550  ui16MsgCtrl |= CAN_IF1MCTL_TXRQST;
1551  ui16ArbReg1 = CAN_IF1ARB2_DIR;
1552  bTransferData = 1;
1553  break;
1554  }
1555 
1556  //
1557  // Transmit remote request message object
1558  //
1560  {
1561  //
1562  // Set the TXRQST bit and the reset the rest of the register.
1563  //
1564  ui16MsgCtrl |= CAN_IF1MCTL_TXRQST;
1565  ui16ArbReg1 = 0;
1566  break;
1567  }
1568 
1569  //
1570  // Receive message object.
1571  //
1572  case MSG_OBJ_TYPE_RX:
1573  {
1574  //
1575  // This clears the DIR bit along with everything else. The TXRQST
1576  // bit was cleared by defaulting ui16MsgCtrl to 0.
1577  //
1578  ui16ArbReg1 = 0;
1579  break;
1580  }
1581 
1582  //
1583  // Receive remote request message object.
1584  //
1586  {
1587  //
1588  // The DIR bit is set to one for remote receivers. The TXRQST bit
1589  // was cleared by defaulting ui16MsgCtrl to 0.
1590  //
1591  ui16ArbReg1 = CAN_IF1ARB2_DIR;
1592 
1593  //
1594  // Set this object so that it only indicates that a remote frame
1595  // was received and allow for software to handle it by sending back
1596  // a data frame.
1597  //
1598  ui16MsgCtrl = CAN_IF1MCTL_UMASK;
1599 
1600  //
1601  // Use the full Identifier by default.
1602  //
1603  ui16MaskReg0 = 0xffff;
1604  ui16MaskReg1 = 0x1fff;
1605 
1606  //
1607  // Make sure to send the mask to the message object.
1608  //
1609  ui16CmdMaskReg |= CAN_IF1CMSK_MASK;
1610  break;
1611  }
1612 
1613  //
1614  // Remote frame receive remote, with auto-transmit message object.
1615  //
1617  {
1618  //
1619  // Oddly the DIR bit is set to one for remote receivers.
1620  //
1621  ui16ArbReg1 = CAN_IF1ARB2_DIR;
1622 
1623  //
1624  // Set this object to auto answer if a matching identifier is seen.
1625  //
1626  ui16MsgCtrl = CAN_IF1MCTL_RMTEN | CAN_IF1MCTL_UMASK;
1627 
1628  //
1629  // The data to be returned needs to be filled in.
1630  //
1631  bTransferData = 1;
1632  break;
1633  }
1634 
1635  //
1636  // This case never happens due to the ASSERT statement at the
1637  // beginning of this function.
1638  //
1639  default:
1640  {
1641  return;
1642  }
1643  }
1644 
1645  //
1646  // Configure the Mask Registers.
1647  //
1648  if(psMsgObject->ui32Flags & MSG_OBJ_USE_ID_FILTER)
1649  {
1650  if(bUseExtendedID)
1651  {
1652  //
1653  // Set the 29 bits of Identifier mask that were requested.
1654  //
1655  ui16MaskReg0 = psMsgObject->ui32MsgIDMask & CAN_IF1MSK1_IDMSK_M;
1656  ui16MaskReg1 = ((psMsgObject->ui32MsgIDMask >> 16) &
1658  }
1659  else
1660  {
1661  //
1662  // Lower 16 bit are unused so set them to zero.
1663  //
1664  ui16MaskReg0 = 0;
1665 
1666  //
1667  // Put the 11 bit Mask Identifier into the upper bits of the field
1668  // in the register.
1669  //
1670  ui16MaskReg1 = ((psMsgObject->ui32MsgIDMask << 2) &
1672  }
1673  }
1674 
1675  //
1676  // If the caller wants to filter on the extended ID bit then set it.
1677  //
1678  if((psMsgObject->ui32Flags & MSG_OBJ_USE_EXT_FILTER) ==
1680  {
1681  ui16MaskReg1 |= CAN_IF1MSK2_MXTD;
1682  }
1683 
1684  //
1685  // The caller wants to filter on the message direction field.
1686  //
1687  if((psMsgObject->ui32Flags & MSG_OBJ_USE_DIR_FILTER) ==
1689  {
1690  ui16MaskReg1 |= CAN_IF1MSK2_MDIR;
1691  }
1692 
1693  if(psMsgObject->ui32Flags &
1696  {
1697  //
1698  // Set the UMASK bit to enable using the mask register.
1699  //
1700  ui16MsgCtrl |= CAN_IF1MCTL_UMASK;
1701 
1702  //
1703  // Set the MASK bit so that this gets transferred to the Message
1704  // Object.
1705  //
1706  ui16CmdMaskReg |= CAN_IF1CMSK_MASK;
1707  }
1708 
1709  //
1710  // Set the Arb bit so that this gets transferred to the Message object.
1711  //
1712  ui16CmdMaskReg |= CAN_IF1CMSK_ARB;
1713 
1714  //
1715  // Configure the Arbitration registers.
1716  //
1717  if(bUseExtendedID)
1718  {
1719  //
1720  // Set the 29 bit version of the Identifier for this message object.
1721  //
1722  ui16ArbReg0 |= psMsgObject->ui32MsgID & CAN_IF1ARB1_ID_M;
1723  ui16ArbReg1 |= (psMsgObject->ui32MsgID >> 16) & CAN_IF1ARB2_ID_M;
1724 
1725  //
1726  // Mark the message as valid and set the extended ID bit.
1727  //
1728  ui16ArbReg1 |= CAN_IF1ARB2_MSGVAL | CAN_IF1ARB2_XTD;
1729  }
1730  else
1731  {
1732  //
1733  // Set the 11 bit version of the Identifier for this message object.
1734  // The lower 18 bits are set to zero.
1735  //
1736  ui16ArbReg1 |= (psMsgObject->ui32MsgID << 2) & CAN_IF1ARB2_ID_M;
1737 
1738  //
1739  // Mark the message as valid.
1740  //
1741  ui16ArbReg1 |= CAN_IF1ARB2_MSGVAL;
1742  }
1743 
1744  //
1745  // Set the data length since this is set for all transfers. This is also a
1746  // single transfer and not a FIFO transfer so set EOB bit.
1747  //
1748  ui16MsgCtrl |= (psMsgObject->ui32MsgLen & CAN_IF1MCTL_DLC_M);
1749 
1750  //
1751  // Mark this as the last entry if this is not the last entry in a FIFO.
1752  //
1753  if((psMsgObject->ui32Flags & MSG_OBJ_FIFO) == 0)
1754  {
1755  ui16MsgCtrl |= CAN_IF1MCTL_EOB;
1756  }
1757 
1758  //
1759  // Enable transmit interrupts if they should be enabled.
1760  //
1761  if(psMsgObject->ui32Flags & MSG_OBJ_TX_INT_ENABLE)
1762  {
1763  ui16MsgCtrl |= CAN_IF1MCTL_TXIE;
1764  }
1765 
1766  //
1767  // Enable receive interrupts if they should be enabled.
1768  //
1769  if(psMsgObject->ui32Flags & MSG_OBJ_RX_INT_ENABLE)
1770  {
1771  ui16MsgCtrl |= CAN_IF1MCTL_RXIE;
1772  }
1773 
1774  //
1775  // Write the data out to the CAN Data registers if needed.
1776  //
1777  if(bTransferData)
1778  {
1779  _CANDataRegWrite(psMsgObject->pui8MsgData,
1780  (uint32_t *)(ui32Base + CAN_O_IF1DA1),
1781  psMsgObject->ui32MsgLen);
1782  }
1783 
1784  //
1785  // Write out the registers to program the message object.
1786  //
1787  HWREG(ui32Base + CAN_O_IF1CMSK) = ui16CmdMaskReg;
1788  HWREG(ui32Base + CAN_O_IF1MSK1) = ui16MaskReg0;
1789  HWREG(ui32Base + CAN_O_IF1MSK2) = ui16MaskReg1;
1790  HWREG(ui32Base + CAN_O_IF1ARB1) = ui16ArbReg0;
1791  HWREG(ui32Base + CAN_O_IF1ARB2) = ui16ArbReg1;
1792  HWREG(ui32Base + CAN_O_IF1MCTL) = ui16MsgCtrl;
1793 
1794  //
1795  // Transfer the message object to the message object specified by
1796  // ui32ObjID.
1797  //
1798  HWREG(ui32Base + CAN_O_IF1CRQ) = ui32ObjID & CAN_IF1CRQ_MNUM_M;
1799 }
1800 
1801 //*****************************************************************************
1802 //
1835 //
1836 //*****************************************************************************
1837 void
1838 CANMessageGet(uint32_t ui32Base, uint32_t ui32ObjID,
1839  tCANMsgObject *psMsgObject, bool bClrPendingInt)
1840 {
1841  uint16_t ui16CmdMaskReg;
1842  uint16_t ui16MaskReg0, ui16MaskReg1;
1843  uint16_t ui16ArbReg0, ui16ArbReg1;
1844  uint16_t ui16MsgCtrl;
1845 
1846  //
1847  // Check the arguments.
1848  //
1849  ASSERT(_CANBaseValid(ui32Base));
1850  ASSERT((ui32ObjID <= 32) && (ui32ObjID != 0));
1851 
1852  //
1853  // This is always a read to the Message object as this call is setting a
1854  // message object.
1855  //
1856  ui16CmdMaskReg = (CAN_IF1CMSK_DATAA | CAN_IF1CMSK_DATAB |
1858  CAN_IF1CMSK_ARB);
1859 
1860  //
1861  // Clear a pending interrupt and new data in a message object.
1862  //
1863  if(bClrPendingInt)
1864  {
1865  ui16CmdMaskReg |= CAN_IF1CMSK_CLRINTPND;
1866  }
1867 
1868  //
1869  // Set up the request for data from the message object.
1870  //
1871  HWREG(ui32Base + CAN_O_IF2CMSK) = ui16CmdMaskReg;
1872 
1873  //
1874  // Transfer the message object to the message object specified by
1875  // ui32ObjID.
1876  //
1877  HWREG(ui32Base + CAN_O_IF2CRQ) = ui32ObjID & CAN_IF1CRQ_MNUM_M;
1878 
1879  //
1880  // Wait for busy bit to clear
1881  //
1882  while(HWREG(ui32Base + CAN_O_IF2CRQ) & CAN_IF1CRQ_BUSY)
1883  {
1884  }
1885 
1886  //
1887  // Read out the IF Registers.
1888  //
1889  ui16MaskReg0 = HWREG(ui32Base + CAN_O_IF2MSK1);
1890  ui16MaskReg1 = HWREG(ui32Base + CAN_O_IF2MSK2);
1891  ui16ArbReg0 = HWREG(ui32Base + CAN_O_IF2ARB1);
1892  ui16ArbReg1 = HWREG(ui32Base + CAN_O_IF2ARB2);
1893  ui16MsgCtrl = HWREG(ui32Base + CAN_O_IF2MCTL);
1894 
1895  psMsgObject->ui32Flags = MSG_OBJ_NO_FLAGS;
1896 
1897  //
1898  // Determine if this is a remote frame by checking the TXRQST and DIR bits.
1899  //
1900  if((!(ui16MsgCtrl & CAN_IF1MCTL_TXRQST) &&
1901  (ui16ArbReg1 & CAN_IF1ARB2_DIR)) ||
1902  ((ui16MsgCtrl & CAN_IF1MCTL_TXRQST) &&
1903  (!(ui16ArbReg1 & CAN_IF1ARB2_DIR))))
1904  {
1905  psMsgObject->ui32Flags |= MSG_OBJ_REMOTE_FRAME;
1906  }
1907 
1908  //
1909  // Get the identifier out of the register, the format depends on size of
1910  // the mask.
1911  //
1912  if(ui16ArbReg1 & CAN_IF1ARB2_XTD)
1913  {
1914  //
1915  // Set the 29 bit version of the Identifier for this message object.
1916  //
1917  psMsgObject->ui32MsgID = (((ui16ArbReg1 & CAN_IF1ARB2_ID_M) << 16) |
1918  ui16ArbReg0);
1919 
1920  psMsgObject->ui32Flags |= MSG_OBJ_EXTENDED_ID;
1921  }
1922  else
1923  {
1924  //
1925  // The Identifier is an 11 bit value.
1926  //
1927  psMsgObject->ui32MsgID = (ui16ArbReg1 & CAN_IF1ARB2_ID_M) >> 2;
1928  }
1929 
1930  //
1931  // Indicate that we lost some data.
1932  //
1933  if(ui16MsgCtrl & CAN_IF1MCTL_MSGLST)
1934  {
1935  psMsgObject->ui32Flags |= MSG_OBJ_DATA_LOST;
1936  }
1937 
1938  //
1939  // Set the flag to indicate if ID masking was used.
1940  //
1941  if(ui16MsgCtrl & CAN_IF1MCTL_UMASK)
1942  {
1943  if(ui16ArbReg1 & CAN_IF1ARB2_XTD)
1944  {
1945  //
1946  // The Identifier Mask is assumed to also be a 29 bit value.
1947  //
1948  psMsgObject->ui32MsgIDMask =
1949  ((ui16MaskReg1 & CAN_IF1MSK2_IDMSK_M) << 16) | ui16MaskReg0;
1950 
1951  //
1952  // If this is a fully specified Mask and a remote frame then don't
1953  // set the MSG_OBJ_USE_ID_FILTER because the ID was not really
1954  // filtered.
1955  //
1956  if((psMsgObject->ui32MsgIDMask != 0x1fffffff) ||
1957  ((psMsgObject->ui32Flags & MSG_OBJ_REMOTE_FRAME) == 0))
1958  {
1959  psMsgObject->ui32Flags |= MSG_OBJ_USE_ID_FILTER;
1960  }
1961  }
1962  else
1963  {
1964  //
1965  // The Identifier Mask is assumed to also be an 11 bit value.
1966  //
1967  psMsgObject->ui32MsgIDMask =
1968  (ui16MaskReg1 & CAN_IF1MSK2_IDMSK_M) >> 2;
1969 
1970  //
1971  // If this is a fully specified Mask and a remote frame then don't
1972  // set the MSG_OBJ_USE_ID_FILTER because the ID was not really
1973  // filtered.
1974  //
1975  if((psMsgObject->ui32MsgIDMask != 0x7ff) ||
1976  ((psMsgObject->ui32Flags & MSG_OBJ_REMOTE_FRAME) == 0))
1977  {
1978  psMsgObject->ui32Flags |= MSG_OBJ_USE_ID_FILTER;
1979  }
1980  }
1981 
1982  //
1983  // Indicate if the extended bit was used in filtering.
1984  //
1985  if(ui16MaskReg1 & CAN_IF1MSK2_MXTD)
1986  {
1987  psMsgObject->ui32Flags |= MSG_OBJ_USE_EXT_FILTER;
1988  }
1989 
1990  //
1991  // Indicate if direction filtering was enabled.
1992  //
1993  if(ui16MaskReg1 & CAN_IF1MSK2_MDIR)
1994  {
1995  psMsgObject->ui32Flags |= MSG_OBJ_USE_DIR_FILTER;
1996  }
1997  }
1998 
1999  //
2000  // Set the interrupt flags.
2001  //
2002  if(ui16MsgCtrl & CAN_IF1MCTL_TXIE)
2003  {
2004  psMsgObject->ui32Flags |= MSG_OBJ_TX_INT_ENABLE;
2005  }
2006  if(ui16MsgCtrl & CAN_IF1MCTL_RXIE)
2007  {
2008  psMsgObject->ui32Flags |= MSG_OBJ_RX_INT_ENABLE;
2009  }
2010 
2011  //
2012  // See if there is new data available.
2013  //
2014  if(ui16MsgCtrl & CAN_IF1MCTL_NEWDAT)
2015  {
2016  //
2017  // Get the amount of data needed to be read.
2018  //
2019  psMsgObject->ui32MsgLen = (ui16MsgCtrl & CAN_IF1MCTL_DLC_M);
2020 
2021  //
2022  // Don't read any data for a remote frame, there is nothing valid in
2023  // that buffer anyway.
2024  //
2025  if((psMsgObject->ui32Flags & MSG_OBJ_REMOTE_FRAME) == 0)
2026  {
2027  //
2028  // Read out the data from the CAN registers.
2029  //
2030  _CANDataRegRead(psMsgObject->pui8MsgData,
2031  (uint32_t *)(ui32Base + CAN_O_IF2DA1),
2032  psMsgObject->ui32MsgLen);
2033  }
2034 
2035  //
2036  // Now clear out the new data flag.
2037  //
2038  HWREG(ui32Base + CAN_O_IF2CMSK) = CAN_IF1CMSK_NEWDAT;
2039 
2040  //
2041  // Transfer the message object to the message object specified by
2042  // ui32ObjID.
2043  //
2044  HWREG(ui32Base + CAN_O_IF2CRQ) = ui32ObjID & CAN_IF1CRQ_MNUM_M;
2045 
2046  //
2047  // Wait for busy bit to clear
2048  //
2049  while(HWREG(ui32Base + CAN_O_IF2CRQ) & CAN_IF1CRQ_BUSY)
2050  {
2051  }
2052 
2053  //
2054  // Indicate that there is new data in this message.
2055  //
2056  psMsgObject->ui32Flags |= MSG_OBJ_NEW_DATA;
2057  }
2058  else
2059  {
2060  //
2061  // Along with the MSG_OBJ_NEW_DATA not being set the amount of data
2062  // needs to be set to zero if none was available.
2063  //
2064  psMsgObject->ui32MsgLen = 0;
2065  }
2066 }
2067 
2068 //*****************************************************************************
2069 //
2080 //
2081 //*****************************************************************************
2082 void
2083 CANMessageClear(uint32_t ui32Base, uint32_t ui32ObjID)
2084 {
2085  //
2086  // Check the arguments.
2087  //
2088  ASSERT(_CANBaseValid(ui32Base));
2089  ASSERT((ui32ObjID >= 1) && (ui32ObjID <= 32));
2090 
2091  //
2092  // Wait for busy bit to clear
2093  //
2094  while(HWREG(ui32Base + CAN_O_IF1CRQ) & CAN_IF1CRQ_BUSY)
2095  {
2096  }
2097 
2098  //
2099  // Clear the message value bit in the arbitration register. This indicates
2100  // the message is not valid.
2101  //
2103  HWREG(ui32Base + CAN_O_IF1ARB1) = 0;
2104  HWREG(ui32Base + CAN_O_IF1ARB2) = 0;
2105 
2106  //
2107  // Initiate programming the message object
2108  //
2109  HWREG(ui32Base + CAN_O_IF1CRQ) = ui32ObjID & CAN_IF1CRQ_MNUM_M;
2110 }
2111 
2112 //*****************************************************************************
2113 //
2114 // Close the Doxygen group.
2116 //
2117 //*****************************************************************************
#define CAN_O_IF2MCTL
Definition: hw_can.h:73
void CANEnable(uint32_t ui32Base)
Definition: can.c:424
#define CAN_O_IF1DA1
Definition: hw_can.h:63
#define CAN_CTL_CCE
Definition: hw_can.h:93
#define CAN_IF1ARB2_DIR
Definition: hw_can.h:235
uint32_t ui32Phase2Seg
Definition: can.h:200
void CANIntDisable(uint32_t ui32Base, uint32_t ui32IntFlags)
Definition: can.c:944
#define MSG_OBJ_RX_INT_ENABLE
This indicates that receive interrupts are enabled.
Definition: can.h:82
#define CAN_O_IF1MCTL
Definition: hw_can.h:62
#define CAN_MAX_PRE_DIVISOR
Definition: can.c:86
#define CAN_STS_LEC_M
Definition: hw_can.h:111
#define CAN_O_IF1ARB1
Definition: hw_can.h:60
#define CAN_IF1CMSK_ARB
Definition: hw_can.h:194
#define CAN_O_IF1MSK2
Definition: hw_can.h:59
#define CAN_O_MSG2VAL
Definition: hw_can.h:85
bool CANRetryGet(uint32_t ui32Base)
Definition: can.c:1193
#define CAN_BIT_SJW_M
Definition: hw_can.h:139
uint32_t ui32MsgLen
This value is the number of bytes of data in the message object.
Definition: can.h:171
#define CAN_IF1ARB2_ID_M
Definition: hw_can.h:236
#define CAN_O_IF2ARB1
Definition: hw_can.h:71
#define CAN_BIT_SJW_S
Definition: hw_can.h:143
#define CAN_O_BRPE
Definition: hw_can.h:54
#define MSG_OBJ_EXTENDED_ID
This indicates that a message object is using an extended identifier.
Definition: can.h:87
static const uint16_t g_ui16CANBitValues[]
Definition: can.c:115
void CANMessageGet(uint32_t ui32Base, uint32_t ui32ObjID, tCANMsgObject *psMsgObject, bool bClrPendingInt)
Definition: can.c:1838
uint32_t ui32MsgID
The CAN message identifier used for 11 or 29 bit identifiers.
Definition: can.h:155
uint32_t ui32SyncPropPhase1Seg
Definition: can.h:194
#define HWREG(x)
Definition: hw_types.h:48
void CANInit(uint32_t ui32Base)
Definition: can.c:325
uint8_t * pui8MsgData
This is a pointer to the message object's data.
Definition: can.h:176
#define MSG_OBJ_USE_EXT_FILTER
Definition: can.h:118
void CANBitTimingGet(uint32_t ui32Base, tCANBitClkParms *psClkParms)
Definition: can.c:483
#define CAN_BIT_BRP_M
Definition: hw_can.h:140
tCANIntStsReg
Definition: can.h:222
#define CAN_O_IF2CRQ
Definition: hw_can.h:67
#define CAN_IF1MCTL_DLC_M
Definition: hw_can.h:253
#define CAN_IF1CMSK_NEWDAT
Definition: hw_can.h:197
#define CAN_O_TXRQ1
Definition: hw_can.h:78
#define CAN_BIT_VALUE(seg1, seg2, sjw)
Definition: can.c:101
#define CAN_ERR_RP
Definition: hw_can.h:126
#define CAN_O_IF2DA1
Definition: hw_can.h:74
#define MSG_OBJ_REMOTE_FRAME
This indicates that a message object is a remote frame.
Definition: can.h:123
void CANIntUnregister(uint32_t ui32Base)
Definition: can.c:855
#define CAN_O_STS
Definition: hw_can.h:49
#define CAN_IF1CMSK_DATAB
Definition: hw_can.h:200
uint32_t ui32QuantumPrescaler
Definition: can.h:212
#define CAN_O_IF1CRQ
Definition: hw_can.h:56
#define CAN_MSG1INT_INTPND_M
Definition: hw_can.h:435
#define ASSERT(expr)
Definition: debug.h:67
#define CAN_IF1CRQ_MNUM_M
Definition: hw_can.h:184
#define CAN_O_IF2MSK1
Definition: hw_can.h:69
#define CAN_IF1CRQ_BUSY
Definition: hw_can.h:183
#define CAN_IF1ARB2_XTD
Definition: hw_can.h:234
#define CAN1_BASE
Definition: hw_memmap.h:94
void CANBitTimingSet(uint32_t ui32Base, tCANBitClkParms *psClkParms)
Definition: can.c:713
#define CAN_IF1MCTL_MSGLST
Definition: hw_can.h:245
#define CAN_IF1CMSK_CLRINTPND
Definition: hw_can.h:196
#define CAN_CTL_INIT
Definition: hw_can.h:98
#define CAN_O_INT
Definition: hw_can.h:52
#define MSG_OBJ_FIFO
Definition: can.h:129
#define CAN_STS_TXOK
Definition: hw_can.h:109
#define CAN_IF1ARB1_ID_M
Definition: hw_can.h:225
#define CAN_IF1MSK1_IDMSK_M
Definition: hw_can.h:207
#define CAN_CTL_SIE
Definition: hw_can.h:96
#define CAN_CTL_DAR
Definition: hw_can.h:94
#define CAN_CTL_IE
Definition: hw_can.h:97
#define CAN_O_MSG2INT
Definition: hw_can.h:83
#define MSG_OBJ_TX_INT_ENABLE
This indicates that transmit interrupts are enabled.
Definition: can.h:77
uint32_t ui32MsgIDMask
The message identifier mask used when identifier filtering is enabled.
Definition: can.h:160
static uint_fast8_t _CANIntNumberGet(uint32_t ui32Base)
Definition: can.c:170
#define CAN_IF1ARB2_MSGVAL
Definition: hw_can.h:233
Receive message object.
Definition: can.h:313
#define CAN_IF1MCTL_TXIE
Definition: hw_can.h:248
uint32_t ui32SJW
Definition: can.h:206
Transmit remote request message object.
Definition: can.h:308
void CANDisable(uint32_t ui32Base)
Definition: can.c:453
#define MSG_OBJ_NEW_DATA
This indicates that new data was available in the message object.
Definition: can.h:98
#define CAN_IF1MCTL_NEWDAT
Definition: hw_can.h:244
#define CAN_IF1MCTL_EOB
Definition: hw_can.h:252
bool CANErrCntrGet(uint32_t ui32Base, uint32_t *pui32RxCount, uint32_t *pui32TxCount)
Definition: can.c:1364
#define CAN_ERR_TEC_M
Definition: hw_can.h:128
uint32_t CANStatusGet(uint32_t ui32Base, tCANStsReg eStatusReg)
Definition: can.c:1276
Transmit message object.
Definition: can.h:303
tCANStsReg
Definition: can.h:242
void CANMessageSet(uint32_t ui32Base, uint32_t ui32ObjID, tCANMsgObject *psMsgObject, tMsgObjType eMsgType)
Definition: can.c:1477
#define CAN_STS_RXOK
Definition: hw_can.h:108
void CANIntRegister(uint32_t ui32Base, void(*pfnHandler)(void))
Definition: can.c:813
#define CAN_IF1CMSK_DATAA
Definition: hw_can.h:199
uint32_t ui32Flags
Definition: can.h:166
#define CAN_MIN_BIT_DIVISOR
Definition: can.c:79
#define MSG_OBJ_USE_DIR_FILTER
Definition: can.h:111
#define CAN_BIT_TSEG2_S
Definition: hw_can.h:141
#define CAN_O_IF2ARB2
Definition: hw_can.h:72
#define CAN_IF1MCTL_RXIE
Definition: hw_can.h:249
#define CAN_IF1MCTL_UMASK
Definition: hw_can.h:247
#define CAN_O_IF1MSK1
Definition: hw_can.h:58
#define CAN_MAX_BIT_DIVISOR
Definition: can.c:72
uint32_t CANBitRateSet(uint32_t ui32Base, uint32_t ui32SourceClock, uint32_t ui32BitRate)
Definition: can.c:554
#define CAN_O_IF1CMSK
Definition: hw_can.h:57
#define MSG_OBJ_NO_FLAGS
This indicates that a message object has no flags set.
Definition: can.h:134
#define CAN_IF1MCTL_RMTEN
Definition: hw_can.h:250
#define CAN_IF1CMSK_MASK
Definition: hw_can.h:193
#define CAN_IF1CMSK_CONTROL
Definition: hw_can.h:195
#define CAN0_BASE
Definition: hw_memmap.h:93
#define CAN_MAX_11BIT_MSG_ID
Definition: can.c:65
#define CAN_O_TXRQ2
Definition: hw_can.h:79
#define MSG_OBJ_USE_ID_FILTER
Definition: can.h:93
void CANIntClear(uint32_t ui32Base, uint32_t ui32IntClr)
Definition: can.c:1084
#define CAN_O_MSG1VAL
Definition: hw_can.h:84
#define CLASS_IS_TM4C123
Definition: hw_types.h:93
Read the full CAN controller status.
Definition: can.h:247
void CANRetrySet(uint32_t ui32Base, bool bAutoRetry)
Definition: can.c:1144
#define CAN_O_IF2MSK2
Definition: hw_can.h:70
#define CAN_ERR_TEC_S
Definition: hw_can.h:130
#define CAN_MIN_PRE_DIVISOR
Definition: can.c:93
Read the CAN interrupt status information.
Definition: can.h:227
#define INT_CAN0_TM4C123
Definition: hw_ints.h:104
#define CAN_IF1MSK2_MXTD
Definition: hw_can.h:215
void IntUnregister(uint32_t ui32Interrupt)
Definition: interrupt.c:381
Read the full 32-bit mask of message objects that are enabled.
Definition: can.h:263
#define INT_CAN0_TM4C129
Definition: hw_ints.h:214
Read a message object's interrupt status.
Definition: can.h:232
#define MSG_OBJ_DATA_LOST
Definition: can.h:104
#define CAN_O_CTL
Definition: hw_can.h:48
#define CAN_IF1MSK2_IDMSK_M
Definition: hw_can.h:217
#define CAN_IF1MCTL_TXRQST
Definition: hw_can.h:251
uint32_t CANIntStatus(uint32_t ui32Base, tCANIntStsReg eIntStsReg)
Definition: can.c:995
Read the full 32-bit mask of message objects with new data available.
Definition: can.h:258
#define CAN_IF1MSK2_MDIR
Definition: hw_can.h:216
#define CAN_O_ERR
Definition: hw_can.h:50
Receive remote request message object.
Definition: can.h:318
#define CAN_O_MSG1INT
Definition: hw_can.h:82
static void _CANDataRegRead(uint8_t *pui8Data, uint32_t *pui32Register, uint32_t ui32Size)
Definition: can.c:278
tMsgObjType
Definition: can.h:298
Remote frame receive remote, with auto-transmit message object.
Definition: can.h:323
void CANIntEnable(uint32_t ui32Base, uint32_t ui32IntFlags)
Definition: can.c:912
#define CLASS_IS_TM4C129
Definition: hw_types.h:99
static void _CANDataRegWrite(uint8_t *pui8Data, uint32_t *pui32Register, uint32_t ui32Size)
Definition: can.c:229
#define CAN_BRPE_BRPE_M
Definition: hw_can.h:175
#define CAN_INT_INTID_STATUS
Definition: hw_can.h:153
#define CAN_O_NWDA2
Definition: hw_can.h:81
#define CAN_O_IF2CMSK
Definition: hw_can.h:68
#define INT_CAN1_TM4C123
Definition: hw_ints.h:105
#define CAN_IF1CMSK_WRNRD
Definition: hw_can.h:192
#define CAN_O_BIT
Definition: hw_can.h:51
#define CAN_BIT_TSEG1_S
Definition: hw_can.h:142
#define CAN_ERR_REC_M
Definition: hw_can.h:127
void CANMessageClear(uint32_t ui32Base, uint32_t ui32ObjID)
Definition: can.c:2083
#define CAN_O_NWDA1
Definition: hw_can.h:80
#define CAN_ERR_REC_S
Definition: hw_can.h:129
#define CAN_BIT_TSEG1_M
Definition: hw_can.h:138
void IntDisable(uint32_t ui32Interrupt)
Definition: interrupt.c:684
void IntRegister(uint32_t ui32Interrupt, void(*pfnHandler)(void))
Definition: interrupt.c:309
void IntEnable(uint32_t ui32Interrupt)
Definition: interrupt.c:610
#define CAN_CTL_EIE
Definition: hw_can.h:95
#define INT_CAN1_TM4C129
Definition: hw_ints.h:215
#define CAN_O_IF1ARB2
Definition: hw_can.h:61
#define CAN_BIT_TSEG2_M
Definition: hw_can.h:137