1 /* -------------------------------- Arctic Core ------------------------------
\r
2 * Arctic Core - the open source AUTOSAR platform http://arccore.com
\r
4 * Copyright (C) 2009 ArcCore AB <contact@arccore.com>
\r
6 * This source code is free software; you can redistribute it and/or modify it
\r
7 * under the terms of the GNU General Public License version 2 as published by the
\r
8 * Free Software Foundation; See <http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt>.
\r
10 * This program is distributed in the hope that it will be useful, but
\r
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
\r
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
\r
14 * -------------------------------- Arctic Core ------------------------------*/
\r
18 #include "core_cr4.h"
\r
19 #if defined(USE_DEM)
\r
23 #include "CanIf_Cbk.h"
\r
28 #define DCAN1_MAX_MESSAGEBOXES 64
\r
29 #define DCAN2_MAX_MESSAGEBOXES 64
\r
30 #define DCAN3_MAX_MESSAGEBOXES 32
\r
32 #define CAN_TIMEOUT_DURATION 0xFFFFFFFF
\r
33 #define CAN_INSTANCE 0
\r
36 #if !defined(USE_DEM)
\r
37 #define Dem_ReportErrorStatus(...)
\r
41 /*----------------------------------------------------------------------------*/
\r
42 /* Variable Definition */
\r
44 // Array for easy access to DCAN register definitions.
\r
45 static Can_RegisterType* CanBase[]=
\r
63 Can_PduType *PduPtr;
\r
66 } Controller_PreConfigType;
\r
69 #if(CAN_DEV_ERROR_DETECT == STD_ON)
\r
70 /* Module is in uninitialized state */
\r
71 static Can_StateType ModuleState = CAN_UNINIT;
\r
74 static CanIf_ControllerModeType ControllerMode[CAN_ARC_CTRL_CONFIG_CNT];
\r
76 /* Used to switch between IF1 and IF2 of DCAN */
\r
77 static uint8 IfRegId = 0;
\r
79 /* Used to order Data Bytes according to hardware registers in DCAN */
\r
80 static const uint8 ElementIndex[] = {3, 2, 1, 0, 7, 6, 5, 4};
\r
82 /* To save pointer to the configuration set */
\r
83 static const Can_ConfigType *CurConfig;
\r
85 /* To save the PduData of transmission objects */
\r
86 static Can_PduType PduInfoArray_1[DCAN1_MAX_MESSAGEBOXES];
\r
87 /* To save pending Cancel Requests of transmission objects */
\r
88 static uint8 CancelRqstArray_1[DCAN1_MAX_MESSAGEBOXES];
\r
89 /* To save pending Transmit Requests of transmission objects */
\r
90 static uint8 TxRqstArray_1[DCAN1_MAX_MESSAGEBOXES];
\r
92 static Can_PduType PduInfoArray_2[DCAN2_MAX_MESSAGEBOXES];
\r
93 static uint8 CancelRqstArray_2[DCAN2_MAX_MESSAGEBOXES];
\r
94 static uint8 TxRqstArray_2[DCAN2_MAX_MESSAGEBOXES];
\r
96 static Can_PduType PduInfoArray_3[DCAN3_MAX_MESSAGEBOXES];
\r
97 static uint8 CancelRqstArray_3[DCAN3_MAX_MESSAGEBOXES];
\r
98 static uint8 TxRqstArray_3[DCAN3_MAX_MESSAGEBOXES];
\r
101 /* Holds the Controller specific configuration */
\r
102 static Controller_PreConfigType ControllerConfig[] =
\r
105 .MaxBoxes = DCAN1_MAX_MESSAGEBOXES,
\r
107 .PduPtr = PduInfoArray_1,
\r
108 .CancelPtr = CancelRqstArray_1,
\r
109 .TxPtr = TxRqstArray_1
\r
112 .MaxBoxes = DCAN2_MAX_MESSAGEBOXES,
\r
114 .PduPtr = PduInfoArray_2,
\r
115 .CancelPtr = CancelRqstArray_2,
\r
116 .TxPtr = TxRqstArray_2
\r
119 .MaxBoxes = DCAN3_MAX_MESSAGEBOXES,
\r
121 .PduPtr = PduInfoArray_3,
\r
122 .CancelPtr = CancelRqstArray_3,
\r
123 .TxPtr = TxRqstArray_3
\r
128 /* Shadow Buffer is used for buffering of received data */
\r
129 static uint8 RxShadowBuf[CAN_ARC_CTRL_CONFIG_CNT][8];
\r
131 /* Driver must know how often Can_DisableControllerInterrupts() has been called */
\r
132 static uint32 IntDisableCount[CAN_ARC_CTRL_CONFIG_CNT];
\r
135 static inline const Can_HardwareObjectType * Can_FindTxHoh(Can_Arc_HTHType hth) {
\r
136 for (int i = 0; i < CAN_ARC_CTRL_CONFIG_CNT; i++) {
\r
137 const Can_HardwareObjectType * hoh = CanControllerConfigData[i].Can_Arc_Hoh;
\r
141 if (hoh->CanObjectType == CAN_OBJECT_TYPE_TRANSMIT && hoh->CanObjectId == hth) {
\r
144 } while (!hoh->Can_Arc_EOL);
\r
149 static inline uint8 Can_FindControllerId(Can_Arc_HTHType hth) {
\r
150 for (int i = 0; i < CAN_ARC_CTRL_CONFIG_CNT; i++) {
\r
151 const Can_HardwareObjectType * hoh = CanControllerConfigData[i].Can_Arc_Hoh;
\r
155 if (hoh->CanObjectType == CAN_OBJECT_TYPE_TRANSMIT && hoh->CanObjectId == hth) {
\r
158 } while (!hoh->Can_Arc_EOL);
\r
163 static inline const Can_HardwareObjectType * Can_FindRxHoh(CanControllerIdType Controller, uint8 msgNr) {
\r
164 const Can_HardwareObjectType * hoh = CanControllerConfigData[Controller].Can_Arc_Hoh;
\r
168 if (hoh->CanObjectType == CAN_OBJECT_TYPE_RECEIVE
\r
169 && (hoh->Can_Arc_MbMask & (1 << (msgNr - 1))) ) {
\r
172 } while (!hoh->Can_Arc_EOL);
\r
177 void Can_InterruptHandler(CanControllerIdType controller)
\r
183 uint8 DataByteIndex;
\r
186 //Can_DisableControllerInterrupts(0);
\r
188 ErrCounter = CAN_TIMEOUT_DURATION;
\r
190 uint32 ir = CanBase[controller]->IR;
\r
194 uint32 sr = CanBase[controller]->SR;
\r
195 /* WakeUp Pending */
\r
196 if(sr & 0x00000200) {
\r
197 /* Set Init Bit, so that Controller is in Stop state */
\r
198 CanBase[controller]->CTL |= 0x1;
\r
199 // EcuM_CheckWakeUp(ControllerConfig[0].WakeupSrc);
\r
203 if(sr & 0x00000080) {
\r
204 Can_SetControllerMode(controller, CAN_T_STOP); // CANIF272
\r
205 //CanIf_ControllerBusOff(0); // Not implemented in Arctic Core
\r
213 /* Read Arbitration, Control and Data Bits and clear IntPnd and NewDat*/
\r
214 CanBase[controller]->IFx[IfRegId].COM = 0x003F0000 | MsgNr;
\r
216 /* Wait until Busy Flag is 0 */
\r
217 while(CanBase[controller]->IFx[IfRegId].COM & 0x8000)
\r
220 if(ErrCounter == 0)
\r
222 Dem_ReportErrorStatus(CAN_E_TIMEOUT, DEM_EVENT_STATUS_FAILED);
\r
223 ErrCounter = CAN_TIMEOUT_DURATION;
\r
228 /* Transmit Object */
\r
229 if(CanBase[controller]->IFx[IfRegId].ARB & 0x20000000)
\r
231 /* Reset TxRqst-Array Element */
\r
232 ControllerConfig[controller].TxPtr[MsgNr - 1] = 0;
\r
233 /* A Message was successfully transmitted */
\r
234 CanIf_TxConfirmation(ControllerConfig[controller].PduPtr[MsgNr - 1].swPduHandle);
\r
236 /* Receive Object */
\r
240 if(CanBase[controller]->IFx[IfRegId].ARB & 0x40000000)
\r
242 /* Bring Id to standardized format (MSB marks extended Id) */
\r
243 MsgId = (CanBase[controller]->IFx[IfRegId].ARB & 0x1FFFFFFF) | 0x80000000;
\r
248 /* Bring Id to standardized format (MSB marks extended Id) */
\r
249 MsgId = (CanBase[controller]->IFx[IfRegId].ARB & 0x1FFC0000) >> 18;
\r
252 MsgDlc = CanBase[controller]->IFx[IfRegId].MC & 0x000F;
\r
257 /* Let SduPtr point to Shadow Buffer */
\r
258 SduPtr = RxShadowBuf[controller];
\r
260 /* Copy Message Data to Shadow Buffer */
\r
261 for(DataByteIndex = 0; DataByteIndex < MsgDlc; DataByteIndex++)
\r
263 SduPtr[DataByteIndex] = CanBase[controller]->IFx[IfRegId].DATx[ElementIndex[DataByteIndex]];
\r
265 /* Indicate successful Reception */
\r
266 const Can_HardwareObjectType *hoh = Can_FindRxHoh(controller, MsgNr);
\r
267 CanIf_RxIndication(hoh->CanObjectId, MsgId, MsgDlc, SduPtr);
\r
271 //Can_EnableControllerInterrupts(0);
\r
274 void Can1_InterruptHandler() {
\r
275 Can_InterruptHandler(DCAN1);
\r
278 void Can2_InterruptHandler() {
\r
279 Can_InterruptHandler(DCAN2);
\r
282 void Can3_InterruptHandler() {
\r
283 Can_InterruptHandler(DCAN3);
\r
286 uint32 Can_CalculateBTR(uint8 Controller) {
\r
288 uint32 clock = McuE_GetPeripheralClock(PERIPHERAL_CLOCK_CAN);
\r
289 uint32 tq1 = CanControllerConfigData[Controller].CanControllerPropSeg + CanControllerConfigData[Controller].CanControllerSeg1;
\r
290 uint32 tq2 = CanControllerConfigData[Controller].CanControllerSeg2;
\r
291 uint32 ntq = tq1 + tq2 + 1 + 1 + 1;
\r
292 uint32 brp = clock / (CanControllerConfigData[Controller].CanControllerBaudRate * 1000 * ntq) - 1;
\r
294 uint32 retVal = (brp | (tq1 << 8) | (tq2 << 12));
\r
299 void Can_Init(const Can_ConfigType *Config)
\r
306 /* DET Error Check */
\r
307 #if(CAN_DEV_ERROR_DETECT == STD_ON)
\r
308 if(ModuleState != CAN_UNINIT)
\r
310 Det_ReportError(CAN_MODULE_ID, CAN_INSTANCE, 0, CAN_E_TRANSITION);
\r
315 Det_ReportError(CAN_MODULE_ID, CAN_INSTANCE, 0, CAN_E_PARAM_POINTER);
\r
320 // TODO This should be used instead of other variables in the Can_Lcfg file.
\r
321 CurConfig = Config;
\r
323 for(Controller = 0; Controller < CAN_ARC_CTRL_CONFIG_CNT; Controller++)
\r
325 ErrCounter = CAN_TIMEOUT_DURATION;
\r
327 /* Init, IE, AutomaticRetransmission, ConfChangeEnable, ABO Off,Parity On, SIE and EIE depending on ControllerConfig */
\r
328 #if(CAN_WAKEUP_SUPPORT == STD_ON)
\r
329 CanBase[Controller]->CTL = 0x02001643;// | (CanControllerConfigData[Controller].CanWakeupProcessing >> 8) | (CanControllerConfigData[Controller].CanBusOffProcessing >> 7);
\r
331 CanBase[Controller]->CTL = 0x00001643;// | (CanControllerConfigData[Controller].CanWakeupProcessing >> 8) | (CanControllerConfigData[Controller].CanBusOffProcessing >> 7);
\r
333 /* LEC 7, TxOk, RxOk, PER */
\r
334 CanBase[Controller]->SR = 0x0000011F;
\r
336 /* Test Mode only for Development time: Silent Loopback */
\r
337 //CanBase[Controller]->CTL |= 0x00000080;
\r
338 //CanBase[Controller]->TR = 0x00000018;
\r
341 // Basic message object initialization
\r
342 for(MsgNr = 0; MsgNr < ControllerConfig[Controller].MaxBoxes; MsgNr++) {
\r
343 /* Initialize the Arrays for Transmit and Cancellation handling */
\r
344 *(ControllerConfig[Controller].CancelPtr + MsgNr) = 0;
\r
345 *(ControllerConfig[Controller].TxPtr + MsgNr) = 0;
\r
347 /* Wait until Busy Flag is 0 */
\r
348 while(CanBase[Controller]->IFx[IfRegId].COM & 0x00008000)
\r
351 if(ErrCounter == 0)
\r
353 Dem_ReportErrorStatus(CAN_E_TIMEOUT, DEM_EVENT_STATUS_FAILED);
\r
354 ErrCounter = CAN_TIMEOUT_DURATION;
\r
359 // Initialize all message objects for this controller to invalid state.
\r
361 CanBase[Controller]->IFx[IfRegId].ARB = 0x00000000;
\r
362 /* Start writing Arbitration Bits */
\r
363 CanBase[Controller]->IFx[IfRegId].COM = 0x00A80000 | (MsgNr + 1);
\r
365 /* Use IFx[0] and IFx[1] alternating */
\r
370 /* Configure the HOHs for this controller. */
\r
371 const Can_HardwareObjectType* hoh;
\r
372 hoh = CanControllerConfigData[Controller].Can_Arc_Hoh;
\r
376 uint64 mbMask = hoh->Can_Arc_MbMask;
\r
378 uint32 nProcessedMb = 0;
\r
380 // For every message object in this hoh
\r
381 for(; mbMask != 0; mbMask >>= 1) {
\r
383 if (!(mbMask & 1)) {
\r
384 // This message object is not part of this hoh.
\r
389 // Check if this is the last message box for this hoh.
\r
390 if((mbMask != 1) &&
\r
391 (hoh->CanObjectType == CAN_OBJECT_TYPE_RECEIVE)) {
\r
392 /* EndOfBlock Bit will not be set */
\r
397 /* EndOfBlock Bit will be set */
\r
401 /* DLC=8, Use Mask only for receive, Set RxIE/TxIE depending on pre-config settings, Eob */
\r
402 CanBase[Controller]->IFx[IfRegId].MC = 0x00001008 | CanControllerConfigData[Controller].CanRxProcessing | (CanControllerConfigData[Controller].CanTxProcessing << 1) | Eob & ~(hoh->CanObjectType >> 17);
\r
404 if(hoh->CanIdType == CAN_ID_TYPE_STANDARD) /* Standard Identifiers */
\r
406 /* Only Standard-Ids are accepted, Set Mask */
\r
407 CanBase[Controller]->IFx[IfRegId].MASK = 0x80000000 | ((*(hoh->CanFilterMaskRef)) & 0x1FFFFFFF);
\r
408 /* Message valid, Id, Direction */
\r
409 CanBase[Controller]->IFx[IfRegId].ARB = 0x80000000 | ((hoh->CanIdValue & 0x7FF) << 18) | hoh->CanObjectType;
\r
411 else if(hoh->CanIdType == CAN_ID_TYPE_EXTENDED) /* Extended Identifiers */
\r
413 /* Only Extended-Ids are accepted, Set Mask */
\r
414 CanBase[Controller]->IFx[IfRegId].MASK = 0x80000000 | ((*(hoh->CanFilterMaskRef)) & 0x1FFFFFFF);
\r
415 /* Message valid, Id, Direction */
\r
416 CanBase[Controller]->IFx[IfRegId].ARB = 0xC0000000 | (hoh->CanIdValue & 0x1FFFFFFF) | hoh->CanObjectType;
\r
418 else /* Mixed Identifiers */
\r
420 /* Standard- and Mixed-Ids are accepted, Set Mask */
\r
421 CanBase[Controller]->IFx[IfRegId].MASK = 0x00000000 | ((*(hoh->CanFilterMaskRef)) & 0x1FFFFFF);
\r
422 /* Message valid, Id, Direction */
\r
423 CanBase[Controller]->IFx[IfRegId].ARB = 0xC0000000 | (hoh->CanIdValue & 0x1FFFFFF) | hoh->CanObjectType;
\r
425 /* Start writing Mask, Arb, Control and Id bits */
\r
426 CanBase[Controller]->IFx[IfRegId].COM = 0x00F80000 | mbNr;
\r
428 /* Use IFx[0] and IFx[1] alternating */
\r
432 } while (!hoh->Can_Arc_EOL);
\r
435 /* Set Bit Timing Register */
\r
436 CanBase[Controller]->BTR = Can_CalculateBTR(Controller);
\r
438 /* Reset CCE Bit */
\r
439 CanBase[Controller]->CTL &= ~0x00000040;
\r
441 #if(CAN_DEV_ERROR_DETECT == STD_ON)
\r
442 /* Switch Controller State to CANIF_CS_STOPPED */
\r
443 ControllerMode[Controller] = CANIF_CS_STOPPED;
\r
446 // Install interrupt handlers
\r
448 if (CanControllerConfigData[Controller].CanControllerId == DCAN1) {
\r
449 tid = Os_Arc_CreateIsr(Can1_InterruptHandler, 2 ,"DCAN1Level0");
\r
450 Irq_AttachIsr2(tid, NULL, 16);
\r
452 tid = Os_Arc_CreateIsr(Can1_InterruptHandler, 2, "DCAN1Level1");
\r
453 Irq_AttachIsr2(tid, NULL, 29);
\r
455 } else if (CanControllerConfigData[Controller].CanControllerId == DCAN2) {
\r
456 tid = Os_Arc_CreateIsr(Can2_InterruptHandler, 2 ,"DCAN2Level0");
\r
457 Irq_AttachIsr2(tid, NULL, 35);
\r
459 tid = Os_Arc_CreateIsr(Can2_InterruptHandler, 2, "DCAN2Level1");
\r
460 Irq_AttachIsr2(tid, NULL, 42);
\r
462 } else if (CanControllerConfigData[Controller].CanControllerId == DCAN3) {
\r
463 tid = Os_Arc_CreateIsr(Can3_InterruptHandler, 2 ,"DCAN3Level0");
\r
464 Irq_AttachIsr2(tid, NULL, 45);
\r
466 tid = Os_Arc_CreateIsr(Can3_InterruptHandler, 2, "DCAN3Level1");
\r
467 Irq_AttachIsr2(tid, NULL, 55);
\r
472 #if(CAN_DEV_ERROR_DETECT == STD_ON)
\r
473 /* Switch Module State to CAN_READY */
\r
474 ModuleState = CAN_READY;
\r
483 void Can_InitController(uint8 Controller, const Can_ControllerConfigType* Config)
\r
488 #if(CAN_DEV_ERROR_DETECT == STD_ON)
\r
491 Det_ReportError(CAN_MODULE_ID, CAN_INSTANCE, 2, CAN_E_PARAM_POINTER);
\r
494 if(ModuleState == CAN_UNINIT)
\r
496 Det_ReportError(CAN_MODULE_ID, CAN_INSTANCE, 2, CAN_E_UNINIT);
\r
499 if(Controller >= CAN_ARC_CTRL_CONFIG_CNT)
\r
501 Det_ReportError(CAN_MODULE_ID, CAN_INSTANCE, 2, CAN_E_PARAM_CONTROLLER);
\r
504 if(ControllerMode[Controller] != CANIF_CS_STOPPED)
\r
506 Det_ReportError(CAN_MODULE_ID, CAN_INSTANCE, 2, CAN_E_TRANSITION);
\r
511 ErrCounter = CAN_TIMEOUT_DURATION;
\r
513 //for(MsgNr = 0; MsgNr < ControllerConfig[Controller].MessageBoxCount; MsgNr++)
\r
514 const Can_HardwareObjectType* hoh;
\r
515 hoh = CanControllerConfigData[Controller].Can_Arc_Hoh;
\r
516 uint64 mbMask = hoh->Can_Arc_MbMask;
\r
517 uint32 nProcessedMb = 0;
\r
520 // For every message object in this hoh
\r
521 for(; mbMask != 0; mbMask >>= 1) {
\r
522 if (!(mbMask & 1)) {
\r
523 // This message object is not part of this hoh.
\r
529 /* Wait until Busy Flag is 0 */
\r
530 while(CanBase[Controller]->IFx[IfRegId].COM & 0x00008000)
\r
533 if(ErrCounter == 0)
\r
535 Dem_ReportErrorStatus(CAN_E_TIMEOUT, DEM_EVENT_STATUS_FAILED);
\r
536 ErrCounter = CAN_TIMEOUT_DURATION;
\r
540 /* Read actual MaskRegister value of MessageObject */
\r
541 CanBase[Controller]->IFx[IfRegId].COM = 0x004C0000 | (MsgNr);
\r
543 /* Wait until Busy Flag is 0 */
\r
544 while(CanBase[Controller]->IFx[IfRegId].COM & 0x00008000)
\r
547 if(ErrCounter == 0)
\r
549 Dem_ReportErrorStatus(CAN_E_TIMEOUT, DEM_EVENT_STATUS_FAILED);
\r
550 ErrCounter = CAN_TIMEOUT_DURATION;
\r
554 CanBase[Controller]->IFx[IfRegId].MASK &= 0xD0000000;
\r
556 CanBase[Controller]->IFx[IfRegId].MASK |= (*(hoh->CanFilterMaskRef)) & 0x1FFFFFFF;
\r
557 /* Write new Mask to MaskRegister */
\r
558 CanBase[Controller]->IFx[IfRegId].COM = 0x00C80000 | (MsgNr);
\r
563 /* Wait until Busy Flag is 0 */
\r
564 while(CanBase[Controller]->IFx[IfRegId].COM & 0x00008000)
\r
567 if(ErrCounter == 0)
\r
569 Dem_ReportErrorStatus(CAN_E_TIMEOUT, DEM_EVENT_STATUS_FAILED);
\r
570 ErrCounter = CAN_TIMEOUT_DURATION;
\r
574 /* Set CCE Bit to allow access to BitTiming Register (Init already set, in mode "stopped") */
\r
575 CanBase[Controller]->CTL |= 0x00000040;
\r
576 /* Set Bit Timing Register */
\r
577 CanBase[Controller]->BTR = Can_CalculateBTR(Controller);
\r
578 /* Clear CCE Bit */
\r
579 CanBase[Controller]->CTL &= ~0x00000040;
\r
584 Can_ReturnType Can_SetControllerMode(uint8 Controller, Can_StateTransitionType Transition)
\r
586 Can_ReturnType Status = CAN_OK;
\r
587 uint32 ErrCounter = CAN_TIMEOUT_DURATION;
\r
590 #if(CAN_DEV_ERROR_DETECT == STD_ON)
\r
591 if(ModuleState == CAN_UNINIT)
\r
593 Det_ReportError(CAN_MODULE_ID, CAN_INSTANCE, 3, CAN_E_UNINIT);
\r
596 if(Controller >= CAN_ARC_CTRL_CONFIG_CNT)
\r
598 Det_ReportError(CAN_MODULE_ID, CAN_INSTANCE, 3, CAN_E_PARAM_CONTROLLER);
\r
601 if(((Transition == CAN_T_START ) && (ControllerMode[Controller] != CANIF_CS_STOPPED)) ||
\r
602 ((Transition == CAN_T_STOP ) && (ControllerMode[Controller] != CANIF_CS_STARTED)) ||
\r
603 ((Transition == CAN_T_SLEEP ) && (ControllerMode[Controller] != CANIF_CS_STOPPED)) ||
\r
604 ((Transition == CAN_T_WAKEUP) && (ControllerMode[Controller] != CANIF_CS_SLEEP )))
\r
606 Det_ReportError(CAN_MODULE_ID, CAN_INSTANCE, 3, CAN_E_TRANSITION);
\r
614 /* Clear Init Bit */
\r
615 CanBase[Controller]->CTL &= ~0x00000001;
\r
616 /* Clear Status Register */
\r
617 CanBase[Controller]->SR = 0x0000011F;
\r
619 ControllerMode[Controller] = CANIF_CS_STARTED;
\r
620 Can_EnableControllerInterrupts(Controller);
\r
625 CanBase[Controller]->CTL |= 0x00000001;
\r
626 ControllerMode[Controller] = CANIF_CS_STOPPED;
\r
627 Can_DisableControllerInterrupts(Controller);
\r
632 CanBase[Controller]->CTL |= 0x01000000;
\r
633 /* Save actual Register status */
\r
634 RegBuf = CanBase[Controller]->CTL;
\r
635 /* Disable Status Interrupts and WUBA */
\r
636 CanBase[Controller]->CTL &= ~0x02000004;
\r
637 /* Wait until Local Power Down Mode acknowledged */
\r
638 while(!(CanBase[Controller]->SR & 0x00000400))
\r
640 /* Check if a WakeUp occurs */
\r
641 if(CanBase[Controller]->SR & 0x00000200)
\r
643 Status = CAN_NOT_OK;
\r
647 if(ErrCounter == 0)
\r
649 Dem_ReportErrorStatus(CAN_E_TIMEOUT, DEM_EVENT_STATUS_FAILED);
\r
650 ErrCounter = CAN_TIMEOUT_DURATION;
\r
651 Status = CAN_NOT_OK;
\r
655 /* Reset Control Register */
\r
656 CanBase[Controller]->CTL = RegBuf;
\r
657 ControllerMode[Controller] = CANIF_CS_SLEEP;
\r
661 /* Clear PDR Bit */
\r
662 CanBase[Controller]->CTL &= ~0x01000000;
\r
663 ControllerMode[Controller] = CANIF_CS_STOPPED;
\r
667 #if(CAN_DEV_ERROR_DETECT == STD_ON)
\r
668 /* Invalid Transition */
\r
669 Det_ReportError(CAN_MODULE_ID, CAN_INSTANCE, 3, CAN_E_TRANSITION);
\r
679 void Can_DisableControllerInterrupts(uint8 Controller)
\r
681 #if(CAN_DEV_ERROR_DETECT == STD_ON)
\r
682 if(ModuleState == CAN_UNINIT)
\r
684 Det_ReportError(CAN_MODULE_ID, CAN_INSTANCE, 4, CAN_E_UNINIT);
\r
687 if(Controller >= CAN_ARC_CTRL_CONFIG_CNT)
\r
689 Det_ReportError(CAN_MODULE_ID, CAN_INSTANCE, 4, CAN_E_PARAM_CONTROLLER);
\r
694 CanBase[Controller]->CTL &= ~0x00000002;
\r
695 /* Increment Disable Counter */
\r
696 IntDisableCount[Controller]++;
\r
699 void Can_EnableControllerInterrupts(uint8 Controller)
\r
701 #if(CAN_DEV_ERROR_DETECT == STD_ON)
\r
702 if(ModuleState == CAN_UNINIT)
\r
704 Det_ReportError(CAN_MODULE_ID, CAN_INSTANCE, 5, CAN_E_UNINIT);
\r
707 if(Controller >= CAN_ARC_CTRL_CONFIG_CNT)
\r
709 Det_ReportError(CAN_MODULE_ID, CAN_INSTANCE, 5, CAN_E_PARAM_CONTROLLER);
\r
713 if(IntDisableCount[Controller] > 0)
\r
715 if(IntDisableCount[Controller] == 1)
\r
718 CanBase[Controller]->CTL |= 0x00000002;
\r
720 IntDisableCount[Controller]--;
\r
725 void Can_Cbk_CheckWakeup(uint8 Controller)
\r
727 /* TODO not supported yet.
\r
728 #if(CAN_DEV_ERROR_DETECT == STD_ON)
\r
729 if(Controller >= CAN_ARC_CTRL_CONFIG_CNT)
\r
731 Det_ReportError(CAN_MODULE_ID, CAN_INSTANCE, 0x0B, CAN_E_PARAM_CONTROLLER);
\r
735 // Check WakeUpPending
\r
736 if(CanBase[Controller]->SR & 0x00000200)
\r
748 Can_ReturnType Can_Write(Can_Arc_HTHType Hth, Can_PduType *PduInfo)
\r
751 uint8 ControllerId;
\r
753 uint32 ArbRegValue;
\r
754 uint8 DataByteIndex;
\r
756 Can_PduType *CurPduArrayPtr;
\r
757 uint8 *CurCancelRqstPtr;
\r
758 uint8 *CurTxRqstPtr;
\r
760 CurSduPtr = PduInfo->sdu;
\r
761 ErrCounter = CAN_TIMEOUT_DURATION;
\r
763 /* DET Error Check */
\r
764 #if(CAN_DEV_ERROR_DETECT == STD_ON)
\r
765 if(PduInfo == NULL || PduInfo->sdu == NULL)
\r
767 Det_ReportError(CAN_MODULE_ID, CAN_INSTANCE, 6, CAN_E_PARAM_POINTER);
\r
770 if(ModuleState == CAN_UNINIT)
\r
772 Det_ReportError(CAN_MODULE_ID, CAN_INSTANCE, 6, CAN_E_UNINIT);
\r
775 if(PduInfo->length > 8)
\r
777 Det_ReportError(CAN_MODULE_ID, CAN_INSTANCE, 6, CAN_E_PARAM_DLC);
\r
778 return CAN_NOT_OK;
\r
782 ControllerId = Can_FindControllerId(Hth);
\r
784 const Can_HardwareObjectType *hoh = Can_FindTxHoh(Hth);
\r
786 #if(CAN_DEV_ERROR_DETECT == STD_ON)
\r
787 if(hoh->CanObjectType != CAN_OBJECT_TYPE_TRANSMIT)
\r
789 Det_ReportError(CAN_MODULE_ID, CAN_INSTANCE, 6, CAN_E_PARAM_HANDLE);
\r
793 uint64 mbMask = hoh->Can_Arc_MbMask;
\r
795 for(; mbMask != 0; mbMask >>= 1) {
\r
796 if (!(mbMask & 1)) {
\r
797 continue; // This message object is not part of this hoh.
\r
799 // Just use the first message object.
\r
803 CurPduArrayPtr = ControllerConfig[ControllerId].PduPtr + (MsgNr - 1);
\r
804 CurCancelRqstPtr = ControllerConfig[ControllerId].CancelPtr + (MsgNr - 1);
\r
805 CurTxRqstPtr = ControllerConfig[ControllerId].TxPtr + (MsgNr - 1);
\r
807 /* Bring Id Value to appropriate format and set ArbRegValue */
\r
808 if(PduInfo->id & 0x80000000)
\r
810 /* MsgVal, Ext, Transmit, Extended Id */
\r
811 ArbRegValue = 0xD0000000 | (PduInfo->id & 0x1FFFFFFF);
\r
815 /* MsgVal, Std, Transmit, Standard Id */
\r
816 ArbRegValue = 0xA0000000 | ((PduInfo->id & 0x7FF) << 18);
\r
819 /* Check if TxRqst Bit of MsgObject is set */
\r
820 if(CanBase[ControllerId]->TRx[MsgNr >> 5] & (1 << (MsgNr & 0x1F)))
\r
825 /* Wait until Busy Flag is 0 */
\r
826 while(CanBase[ControllerId]->IFx[IfRegId].COM & 0x00008000)
\r
829 if(ErrCounter == 0)
\r
831 Dem_ReportErrorStatus(CAN_E_TIMEOUT, DEM_EVENT_STATUS_FAILED);
\r
832 ErrCounter = CAN_TIMEOUT_DURATION;
\r
837 /* Set NewDat, TxIE (dep on ControllerConfig), TxRqst, EoB and DLC */
\r
838 CanBase[ControllerId]->IFx[IfRegId].MC = 0x00000180 | (0x000F & PduInfo->length) | (CanControllerConfigData[ControllerId].CanTxProcessing << 1);
\r
840 /* Set ArbitrationRegister */
\r
841 CanBase[ControllerId]->IFx[IfRegId].ARB = ArbRegValue;
\r
843 /* Set Databytes */
\r
844 for(DataByteIndex = 0; DataByteIndex < PduInfo->length; DataByteIndex++)
\r
846 CanBase[ControllerId]->IFx[IfRegId].DATx[ElementIndex[DataByteIndex]] = *CurSduPtr++;
\r
849 /* Start transmission to MessageRAM */
\r
850 CanBase[ControllerId]->IFx[IfRegId].COM = 0x00BF0000 | MsgNr;
\r
852 /* Save the PduInfo in PduArray, so that messages can be identified later */
\r
853 *CurPduArrayPtr = *PduInfo;
\r
854 /* TxRqstArray-Elements are used to identifiy transmitted objects in polling mode */
\r
863 void Can_MainFunction_Write()
\r
868 void Can_MainFunction_Read()
\r
873 void Can_MainFunction_BusOff()
\r
878 void Can_MainFunction_Wakeup()
\r