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
25 #ifndef USE_CAN_STUB
\r
26 #include "mpc55xx.h"
\r
29 #include "CanIf_Cbk.h"
\r
31 #if defined(USE_DEM)
\r
37 #if defined(USE_KERNEL)
\r
44 /* CONFIGURATION NOTES
\r
45 * ------------------------------------------------------------------
\r
46 * - CanHandleType must be CAN_ARC_HANDLE_TYPE_BASIC
\r
47 * i.e. CanHandleType=CAN_ARC_HANDLE_TYPE_FULL NOT supported
\r
48 * i.e CanIdValue is NOT supported
\r
49 * - All CanXXXProcessing must be CAN_ARC_PROCESS_TYPE_INTERRUPT
\r
50 * ie CAN_ARC_PROCESS_TYPE_POLLED not supported
\r
51 * - To select the Mailboxes to use in the CAN controller use Can_Arc_MbMask
\r
52 * - HOH's for Tx are global and Rx are for each controller
\r
53 * - CanControllerTimeQuanta is NOT used. The other CanControllerXXX selects
\r
54 * the proper time-quanta
\r
55 * - Can_Arc_MbMask for Tx HOH must NOT overlap Can_Arc_MbMask for Rx.
\r
56 * - ONLY global mask is supported( NOT 14,15 and individual )
\r
57 * - Numbering the CanObjectId for Tx:
\r
58 * To do this correctly there are a number of things that are good to know
\r
59 * 1. HTH's have unique numbers.
\r
60 * 2. One HTH/HRH is maped to one HOH
\r
61 * 3. The extension Can_Arc_MbMask binds FULL CAN boxes together.
\r
66 * ---------------------
\r
71 * 17 | The use of Can_Arc_MbMask=0x000f0000 binds these to HTH 16
\r
72 * 18 | ( bits 16 to 19 set here )
\r
80 * C - Controller number
\r
84 /* IMPLEMENTATION NOTES
\r
85 * -----------------------------------------------
\r
86 * - A HOH us unique for a controller( not a config-set )
\r
87 * - Hrh's are numbered for each controller from 0
\r
88 * - HOH is numbered for each controller in sequences of 0-31
\r
89 * ( since we have 6 controllers and Hth is only uint8( See Can_Write() proto )
\r
90 * - loopback in HW NOT supported
\r
91 * - 32 of 64 boxes supported ( limited by Hth type )
\r
92 * - Fifo in HW NOT supported
\r
96 * -----------------------------------------------
\r
97 * - Can Hardware unit - One or multiple Can controllers of the same type.
\r
98 * - Hrh - HOH with receive definitions
\r
99 * - Hth - HOH with transmit definitions
\r
104 * ------------------------------------------------------------------
\r
105 * This controller should really be called FlexCan+ or something because
\r
106 * it's enhanced with:
\r
107 * - A RX Fifo !!!!! ( yep, it's fantastic ;) )
\r
108 * - A better matching process. From 25.4.4
\r
109 * "By programming more than one MB with the same ID, received messages will
\r
110 * be queued into the MBs. The CPU can examine the time stamp field of the
\r
111 * MBs to determine the order in which the messages arrived."
\r
113 * Soo, now it seems that Freescale have finally done something right.
\r
116 //-------------------------------------------------------------------
\r
118 // Number of mailboxes used for each controller ( power of 2 only )
\r
119 // ( It's NOT supported to set this to 64 )
\r
120 #define MAX_NUM_OF_MAILBOXES 32
\r
122 #if defined(CFG_MPC5567)
\r
123 #define GET_CONTROLLER(_controller) \
\r
124 ((struct FLEXCAN2_tag *)(0xFFFC0000 + 0x4000*(_controller)))
\r
126 #define GET_CONTROLLER(_controller) \
\r
127 ((struct FLEXCAN_tag *)(0xFFFC0000 + 0x4000*(_controller)))
\r
130 #define GET_CONTROLLER_CONFIG(_controller) \
\r
131 &Can_Global.config->CanConfigSet->CanController[(_controller)]
\r
133 #define GET_CALLBACKS() \
\r
134 (Can_Global.config->CanConfigSet->CanCallbacks)
\r
136 #define GET_PRIVATE_DATA(_controller) \
\r
137 &CanUnit[_controller]
\r
139 #define GET_CONTROLLER_CNT() (CAN_CONTROLLER_CNT)
\r
141 //-------------------------------------------------------------------
\r
143 #if ( CAN_DEV_ERROR_DETECT == STD_ON )
\r
144 #define VALIDATE(_exp,_api,_err ) \
\r
146 Det_ReportError(MODULE_ID_CAN,0,_api,_err); \
\r
147 return CAN_NOT_OK; \
\r
150 #define VALIDATE_NO_RV(_exp,_api,_err ) \
\r
152 Det_ReportError(MODULE_ID_CAN,0,_api,_err); \
\r
156 #define DET_REPORTERROR(_x,_y,_z,_q) Det_ReportError(_x, _y, _z, _q)
\r
158 #define VALIDATE(_exp,_api,_err )
\r
159 #define VALIDATE_NO_RV(_exp,_api,_err )
\r
160 #define DET_REPORTERROR(_x,_y,_z,_q)
\r
163 #if defined(USE_DEM)
\r
164 #define VALIDATE_DEM_NO_RV(_exp,_err ) \
\r
166 Dem_ReportErrorStatus(_err, DEM_EVENT_STATUS_FAILED); \
\r
170 #define VALIDATE_DEM_NO_RV(_exp,_err )
\r
173 //-------------------------------------------------------------------
\r
175 // Message box status defines
\r
176 #define MB_TX_ONCE 0xc
\r
177 #define MB_INACTIVE 0x8
\r
179 #define MB_ABORT 0x9
\r
181 //-------------------------------------------------------------------
\r
186 } Can_DriverStateType;
\r
192 vuint32_t TWRNINT:1;
\r
193 vuint32_t RWRNINT:1;
\r
194 vuint32_t BIT1ERR:1;
\r
195 vuint32_t BIT0ERR:1;
\r
196 vuint32_t ACKERR:1;
\r
197 vuint32_t CRCERR:1;
\r
198 vuint32_t FRMERR:1;
\r
199 vuint32_t STFERR:1;
\r
204 vuint32_t FLTCONF:2;
\r
206 vuint32_t BOFFINT:1;
\r
207 vuint32_t ERRINT:1;
\r
208 vuint32_t WAKINT:1;
\r
210 } ESRType; /* Error and Status Register */
\r
212 #if defined(CFG_MPC5567)
\r
213 typedef struct FLEXCAN2_tag flexcan_t;
\r
215 typedef struct FLEXCAN_tag flexcan_t;
\r
218 // Mapping between HRH and Controller//HOH
\r
219 typedef struct Can_Arc_ObjectHOHMapStruct
\r
221 uint32 HxHRef; // Reference to HRH or HTH
\r
222 CanControllerIdType CanControllerRef; // Reference to controller
\r
223 const Can_HardwareObjectType* CanHOHRef; // Reference to HOH.
\r
224 } Can_Arc_ObjectHOHMapType;
\r
226 /* Type for holding global information used by the driver */
\r
228 Can_DriverStateType initRun;
\r
231 const Can_ConfigType *config;
\r
233 // One bit for each channel that is configured.
\r
234 // Used to determine if validity of a channel
\r
236 // 0 - NOT configured
\r
238 // Maps the a channel id to a configured channel id
\r
239 uint8 channelMap[CAN_CONTROLLER_CNT];
\r
241 // This is a map that maps the HTH:s with the controller and Hoh. It is built
\r
242 // during Can_Init and is used to make things faster during a transmit.
\r
243 Can_Arc_ObjectHOHMapType CanHTHMap[NUM_OF_HTHS];
\r
247 Can_GlobalType Can_Global =
\r
249 .initRun = CAN_UNINIT,
\r
253 /* Type for holding information about each controller */
\r
255 CanIf_ControllerModeType state;
\r
257 // Interrupt masks that is for all Mb's in this controller
\r
258 uint32 Can_Arc_RxMbMask;
\r
259 uint32 Can_Arc_TxMbMask;
\r
261 // Used at IFLG in controller at startup
\r
265 Can_Arc_StatisticsType stats;
\r
267 // Data stored for Txconfirmation callbacks to CanIf
\r
268 PduIdType swPduHandles[MAX_NUM_OF_MAILBOXES];
\r
272 #if defined(CFG_MPC5567)
\r
273 Can_UnitType CanUnit[CAN_CONTROLLER_CNT] =
\r
276 .state = CANIF_CS_UNINIT,
\r
278 .state = CANIF_CS_UNINIT,
\r
280 .state = CANIF_CS_UNINIT,
\r
282 .state = CANIF_CS_UNINIT,
\r
284 .state = CANIF_CS_UNINIT,
\r
287 #elif defined(CFG_MPC5606S)
\r
288 Can_UnitType CanUnit[CAN_CONTROLLER_CNT] ={
\r
290 .state = CANIF_CS_UNINIT,
\r
292 .state = CANIF_CS_UNINIT,
\r
296 Can_UnitType CanUnit[CAN_CONTROLLER_CNT] =
\r
299 .state = CANIF_CS_UNINIT,
\r
301 .state = CANIF_CS_UNINIT,
\r
303 .state = CANIF_CS_UNINIT,
\r
305 .state = CANIF_CS_UNINIT,
\r
307 .state = CANIF_CS_UNINIT,
\r
309 .state = CANIF_CS_UNINIT,
\r
314 //-------------------------------------------------------------------
\r
316 //-------------------------------------------------------------------
\r
318 * Function that finds the Hoh( HardwareObjectHandle ) from a Hth
\r
319 * A HTH may connect to one or several HOH's. Just find the first one.
\r
321 * @param hth The transmit handle
\r
322 * @returns Ptr to the Hoh
\r
324 static const Can_HardwareObjectType * Can_FindHoh( Can_Arc_HTHType hth , uint32* controller)
\r
326 const Can_HardwareObjectType *hohObj;
\r
327 const Can_Arc_ObjectHOHMapType *map;
\r
328 const Can_ControllerConfigType *canHwConfig;
\r
330 map = &Can_Global.CanHTHMap[hth];
\r
332 // Verify that this is the correct map
\r
333 if (map->HxHRef != hth)
\r
335 DET_REPORTERROR(MODULE_ID_CAN, 0, 0x6, CAN_E_PARAM_HANDLE);
\r
338 canHwConfig= GET_CONTROLLER_CONFIG(Can_Global.channelMap[map->CanControllerRef]);
\r
340 hohObj = map->CanHOHRef;
\r
342 // Verify that this is the correct Hoh type
\r
343 if ( hohObj->CanObjectType == CAN_OBJECT_TYPE_TRANSMIT)
\r
345 *controller = map->CanControllerRef;
\r
349 DET_REPORTERROR(MODULE_ID_CAN, 0, 0x6, CAN_E_PARAM_HANDLE);
\r
354 //-------------------------------------------------------------------
\r
356 static void Can_Isr( int unit );
\r
357 static void Can_Err( int unit );
\r
358 static void Can_BusOff( int unit );
\r
360 void Can_A_Isr( void ) { Can_Isr(CAN_CTRL_A); }
\r
361 void Can_B_Isr( void ) { Can_Isr(CAN_CTRL_B); }
\r
362 #if !defined(CFG_MPC5606S)
\r
363 void Can_C_Isr( void ) { Can_Isr(CAN_CTRL_C); }
\r
364 void Can_D_Isr( void ) { Can_Isr(CAN_CTRL_D); }
\r
365 void Can_E_Isr( void ) { Can_Isr(CAN_CTRL_E); }
\r
366 #if defined(CFG_MPC5567)
\r
368 void Can_F_Isr( void ) { Can_Isr(CAN_CTRL_F); }
\r
372 void Can_A_Err( void ) { Can_Err(CAN_CTRL_A); }
\r
373 void Can_B_Err( void ) { Can_Err(CAN_CTRL_B); }
\r
374 #if !defined(CFG_MPC5606S)
\r
375 void Can_C_Err( void ) { Can_Err(CAN_CTRL_C); }
\r
376 void Can_D_Err( void ) { Can_Err(CAN_CTRL_D); }
\r
377 void Can_E_Err( void ) { Can_Err(CAN_CTRL_E); }
\r
378 #if defined(CFG_MPC5567)
\r
380 void Can_F_Err( void ) { Can_Err(CAN_CTRL_F); }
\r
384 void Can_A_BusOff( void ) { Can_BusOff(CAN_CTRL_A); }
\r
385 void Can_B_BusOff( void ) { Can_BusOff(CAN_CTRL_B); }
\r
386 #if !defined(CFG_MPC5606S)
\r
387 void Can_C_BusOff( void ) { Can_BusOff(CAN_CTRL_C); }
\r
388 void Can_D_BusOff( void ) { Can_BusOff(CAN_CTRL_D); }
\r
389 void Can_E_BusOff( void ) { Can_BusOff(CAN_CTRL_E); }
\r
390 #if defined(CFG_MPC5567)
\r
392 void Can_F_BusOff( void ) { Can_BusOff(CAN_CTRL_F); }
\r
395 //-------------------------------------------------------------------
\r
399 * Hardware error ISR for CAN
\r
401 * @param unit CAN controller number( from 0 )
\r
404 static void Can_Err( int unit ) {
\r
405 flexcan_t *canHw = GET_CONTROLLER(unit);
\r
406 Can_Arc_ErrorType err;
\r
410 esr.R = canHw->ESR.R;
\r
412 err.B.ACKERR = esr.B.ACKERR;
\r
413 err.B.BIT0ERR = esr.B.BIT0ERR;
\r
414 err.B.BIT1ERR = esr.B.BIT1ERR;
\r
415 err.B.CRCERR = esr.B.CRCERR;
\r
416 err.B.FRMERR = esr.B.FRMERR;
\r
417 err.B.STFERR = esr.B.STFERR;
\r
418 err.B.RXWRN = esr.B.RXWRN;
\r
419 err.B.TXWRN = esr.B.TXWRN;
\r
421 if (GET_CALLBACKS()->Arc_Error != NULL)
\r
423 GET_CALLBACKS()->Arc_Error(unit, err );
\r
426 canHw->ESR.B.ERRINT = 1;
\r
430 // Uses 25.4.5.1 Transmission Abort Mechanism
\r
431 static void Can_AbortTx( flexcan_t *canHw, Can_UnitType *canUnit ) {
\r
435 // Find our Tx boxes.
\r
436 mbMask = canUnit->Can_Arc_TxMbMask;
\r
438 // Loop over the Mb's set to abort
\r
439 for (; mbMask; mbMask&=~(1<<mbNr)) {
\r
440 mbNr = ilog2(mbMask);
\r
442 canHw->BUF[mbNr].CS.B.CODE = MB_ABORT;
\r
445 if( canHw->BUF[mbNr].CS.B.CODE != MB_ABORT ) {
\r
448 // it's not sent... or being sent.
\r
449 // Just wait for it
\r
451 while( canHw->IFRL.R == (1<<mbNr) )
\r
460 // Ack tx interrupts
\r
461 canHw->IFRL.R = canUnit->Can_Arc_TxMbMask;
\r
462 canUnit->iflagStart = canUnit->Can_Arc_TxMbMask;
\r
465 //-------------------------------------------------------------------
\r
468 * BussOff ISR for CAN
\r
470 * @param unit CAN controller number( from 0 )
\r
472 static void Can_BusOff( int unit ) {
\r
473 flexcan_t *canHw = GET_CONTROLLER(unit);
\r
474 Can_UnitType *canUnit = GET_PRIVATE_DATA(unit);
\r
475 Can_Arc_ErrorType err;
\r
478 if ( canHw->ESR.B.TWRNINT )
\r
480 err.B.TXWRN = canHw->ESR.B.TXWRN;
\r
481 canUnit->stats.txErrorCnt++;
\r
482 canHw->ESR.B.TWRNINT = 1;
\r
485 if ( canHw->ESR.B.RWRNINT )
\r
487 err.B.RXWRN = canHw->ESR.B.RXWRN;
\r
488 canUnit->stats.rxErrorCnt++;
\r
489 canHw->ESR.B.RWRNINT = 1;
\r
494 if (GET_CALLBACKS()->Arc_Error != NULL)
\r
496 GET_CALLBACKS()->Arc_Error( unit, err );
\r
500 if( canHw->ESR.B.BOFFINT ) {
\r
502 canUnit->stats.boffCnt++;
\r
503 if (GET_CALLBACKS()->ControllerBusOff != NULL)
\r
505 GET_CALLBACKS()->ControllerBusOff(unit);
\r
507 Can_SetControllerMode(unit, CAN_T_STOP); // CANIF272
\r
509 canHw->ESR.B.BOFFINT = 1;
\r
511 Can_AbortTx( canHw, canUnit ); // CANIF273
\r
515 //-------------------------------------------------------------------
\r
518 * ISR for CAN. Normal Rx/Tx operation
\r
520 * @param unit CAN controller number( from 0 )
\r
522 static void Can_Isr(int unit) {
\r
524 flexcan_t *canHw= GET_CONTROLLER(unit);
\r
525 const Can_ControllerConfigType *canHwConfig= GET_CONTROLLER_CONFIG(Can_Global.channelMap[unit]);
\r
526 uint32 iFlagLow = canHw->IFRL.R;
\r
527 Can_UnitType *canUnit = GET_PRIVATE_DATA(unit);
\r
529 // Read interrupt flags to seeTxConfirmation what interrupt triggered the interrupt
\r
530 if (iFlagLow & canHw->IMRL.R) {
\r
533 #if defined(CFG_MPC5516) || defined(CFG_MPC5517) || defined(CFG_MPC5606S)
\r
535 // FIFO code NOT tested
\r
536 if (canHw->MCR.B.FEN) {
\r
539 if (iFlagLow & (1<<7)) {
\r
540 canUnit->stats.fifoOverflow++;
\r
541 canHw->IFRL.B.BUF07I = 1;
\r
545 if (iFlagLow & (1<<6)) {
\r
546 canUnit->stats.fifoWarning++;
\r
547 canHw->IFRL.B.BUF06I = 1;
\r
550 // Pop fifo "realtime"
\r
551 while (canHw->IFRL.B.BUF05I) {
\r
553 // TODO MAHI: Must read the entire data-buffer to unlock??
\r
554 if (GET_CALLBACKS()->RxIndication != NULL)
\r
556 GET_CALLBACKS()->RxIndication((-1), canHw->BUF[0].ID.B.EXT_ID,
\r
557 canHw->BUF[0].CS.B.LENGTH, (uint8 *)&canHw->BUF[0].DATA.W[0] );
\r
559 // Clear the interrupt
\r
560 canHw->IFRL.B.BUF05I = 1;
\r
565 const Can_HardwareObjectType *hohObj;
\r
572 // Loop over all the Hoh's
\r
576 hohObj= canHwConfig->Can_Arc_Hoh;
\r
581 mbMask = hohObj->Can_Arc_MbMask & iFlagLow;
\r
583 if (hohObj->CanObjectType == CAN_OBJECT_TYPE_RECEIVE)
\r
585 // Loop over the Mb's for this Hoh
\r
586 for (; mbMask; mbMask&=~(1<<mbNr)) {
\r
587 mbNr = ilog2(mbMask);
\r
589 // Do the necessary dummy reads to keep controller happy
\r
590 data = canHw->BUF[mbNr].CS.R;
\r
591 data = canHw->BUF[mbNr].DATA.W[0];
\r
593 // According to autosar MSB shuould be set if extended
\r
594 if (hohObj->CanIdType == CAN_ID_TYPE_EXTENDED) {
\r
595 id = canHw->BUF[mbNr].ID.R;
\r
598 id = canHw->BUF[mbNr].ID.B.STD_ID;
\r
601 if (GET_CALLBACKS()->RxIndication != NULL)
\r
603 GET_CALLBACKS()->RxIndication(hohObj->CanObjectId,
\r
605 canHw->BUF[mbNr].CS.B.LENGTH,
\r
606 (uint8 *)&canHw->BUF[mbNr].DATA.W[0] );
\r
608 // Increment statistics
\r
609 canUnit->stats.rxSuccessCnt++;
\r
611 // unlock MB (dummy read timer)
\r
612 (void)canHw->TIMER.R;
\r
615 canHw->IFRL.R = (1<<mbNr);
\r
618 } while ( !hohObj->Can_Arc_EOL);
\r
621 hohObj= canHwConfig->Can_Arc_Hoh;
\r
626 if (hohObj->CanObjectType == CAN_OBJECT_TYPE_TRANSMIT)
\r
628 mbMask = hohObj->Can_Arc_MbMask & iFlagLow;
\r
630 // Loop over the Mb's for this Hoh
\r
631 for (; mbMask; mbMask&=~(1<<mbNr)) {
\r
632 mbNr = ilog2(mbMask);
\r
634 if (GET_CALLBACKS()->TxConfirmation != NULL)
\r
636 GET_CALLBACKS()->TxConfirmation(canUnit->swPduHandles[mbNr]);
\r
638 canUnit->swPduHandles[mbNr] = 0; // Is this really necessary ??
\r
641 canUnit->iflagStart |= (1<<mbNr);
\r
642 canHw->IFRL.R = (1<<mbNr);
\r
645 } while ( !hohObj->Can_Arc_EOL);
\r
646 #if defined(CFG_MPC5516) || defined(CFG_MPC5517) || defined(CFG_MPC5606S)
\r
650 // Note! Over 32 boxes is not implemented
\r
651 // Other reasons that we end up here
\r
652 // - Interupt on a masked box
\r
655 if (canHwConfig->Can_Arc_Fifo) {
\r
658 * Do not enable RxFIFO. See [Freescale Device Errata MPC5510ACE, Rev. 10 APR 2009, errata ID: 14593].
\r
662 * NOT tested at all
\r
664 while (canHw->IFRL.B.BUF05I) {
\r
666 // TODO MAHI: Must read the entire data-buffer to unlock??
\r
667 if (GET_CALLBACKS()->RxIndication != NULL)
\r
669 GET_CALLBACKS()->RxIndication((-1), canHw->BUF[0].ID.B.EXT_ID,
\r
670 canHw->BUF[0].CS.B.LENGTH, (uint8 *)&canHw->BUF[0].DATA.W[0] );
\r
672 // Increment statistics
\r
673 canUnit->stats.rxSuccessCnt++;
\r
675 // Clear the interrupt
\r
676 canHw->IFRL.B.BUF05I = 1;
\r
681 //-------------------------------------------------------------------
\r
683 #if defined(USE_KERNEL)
\r
684 #define INSTALL_HANDLERS( _can_name,_boff,_err,_start,_stop) \
\r
687 tid = Os_Arc_CreateIsr(_can_name ## _BusOff,2/*prio*/,"Can"); \
\r
688 Irq_AttachIsr2(tid, NULL, (IrqType) _boff); \
\r
689 tid = Os_Arc_CreateIsr(_can_name ## _Err,2/*prio*/,"Can"); \
\r
690 Irq_AttachIsr2(tid, NULL, (IrqType) _err); \
\r
691 for(i=_start;i<=_stop;i++) { \
\r
692 tid = Os_Arc_CreateIsr(_can_name ## _Isr,2/*prio*/,"Can"); \
\r
693 Irq_AttachIsr2(tid, NULL, (IrqType) i); \
\r
697 #define INSTALL_HANDLERS( _can_name,_boff,_err,_start,_stop) \
\r
698 Irq_InstallVector(_can_name ## _BusOff, _boff, 1, CPU_Z1); \
\r
699 Irq_InstallVector(_can_name ## _Err, _err, 1, CPU_Z1); \
\r
700 for(i=_start;i<=_stop;i++) { \
\r
701 Irq_InstallVector(_can_name ## _Isr, i, 1, CPU_Z1); \
\r
705 // This initiates ALL can controllers
\r
706 void Can_Init( const Can_ConfigType *config ) {
\r
707 Can_UnitType *canUnit;
\r
708 const Can_ControllerConfigType *canHwConfig;
\r
712 VALIDATE_NO_RV( (Can_Global.initRun == CAN_UNINIT), 0x0, CAN_E_TRANSITION );
\r
713 VALIDATE_NO_RV( (config != NULL ), 0x0, CAN_E_PARAM_POINTER );
\r
716 Can_Global.config = config;
\r
717 Can_Global.initRun = CAN_READY;
\r
720 for (int configId=0; configId < CAN_ARC_CTRL_CONFIG_CNT; configId++) {
\r
721 canHwConfig = GET_CONTROLLER_CONFIG(configId);
\r
722 ctlrId = canHwConfig->CanControllerId;
\r
724 // Assign the configuration channel used later..
\r
725 Can_Global.channelMap[canHwConfig->CanControllerId] = configId;
\r
726 Can_Global.configured |= (1<<ctlrId);
\r
728 canUnit = GET_PRIVATE_DATA(ctlrId);
\r
729 canUnit->state = CANIF_CS_STOPPED;
\r
731 canUnit->lock_cnt = 0;
\r
734 memset(&canUnit->stats, 0, sizeof(Can_Arc_StatisticsType));
\r
736 Can_InitController(ctlrId, canHwConfig);
\r
738 // Loop through all Hoh:s and map them into the HTHMap
\r
739 const Can_HardwareObjectType* hoh;
\r
740 hoh = canHwConfig->Can_Arc_Hoh;
\r
746 if (hoh->CanObjectType == CAN_OBJECT_TYPE_TRANSMIT)
\r
748 Can_Global.CanHTHMap[hoh->CanObjectId].CanControllerRef = canHwConfig->CanControllerId;
\r
749 Can_Global.CanHTHMap[hoh->CanObjectId].CanHOHRef = hoh;
\r
750 Can_Global.CanHTHMap[hoh->CanObjectId].HxHRef = hoh->CanObjectId;
\r
752 } while (!hoh->Can_Arc_EOL);
\r
755 // Could install handlers depending on HW objects to trap more errors
\r
756 // in configuration
\r
757 #if defined(CFG_MPC5567)
\r
758 switch( canHwConfig->CanControllerId ) {
\r
760 INSTALL_HANDLERS(Can_A, FLEXCAN_A_ESR_BOFF_INT, FLEXCAN_A_ESR_ERR_INT, FLEXCAN_A_IFLAG1_BUF0I, FLEXCAN_A_IFLAG1_BUF31_16I); break;
\r
762 INSTALL_HANDLERS(Can_B, FLEXCAN_B_ESR_BOFF_INT, FLEXCAN_B_ESR_ERR_INT, FLEXCAN_B_IFLAG1_BUF0I, FLEXCAN_B_IFLAG1_BUF31_16I); break;
\r
764 INSTALL_HANDLERS(Can_C, FLEXCAN_C_ESR_BOFF_INT, FLEXCAN_C_ESR_ERR_INT, FLEXCAN_C_IFLAG1_BUF0I, FLEXCAN_C_IFLAG1_BUF31_16I); break;
\r
766 INSTALL_HANDLERS(Can_D, FLEXCAN_D_ESR_BOFF_INT, FLEXCAN_D_ESR_ERR_INT, FLEXCAN_D_IFLAG1_BUF0I, FLEXCAN_D_IFLAG1_BUF31_16I); break;
\r
768 INSTALL_HANDLERS(Can_E, FLEXCAN_E_ESR_BOFF_INT, FLEXCAN_E_ESR_ERR_INT, FLEXCAN_E_IFLAG1_BUF0I, FLEXCAN_E_IFLAG1_BUF31_16I); break;
\r
772 #elif defined(CFG_MPC5606S)
\r
773 switch( canHwConfig->CanControllerId )
\r
776 INSTALL_HANDLERS(Can_A, FLEXCAN_0_ESR_BOFF_INT, FLEXCAN_0_ESR_ERR_INT, FLEXCAN_0_BUF_00_03, FLEXCAN_0_BUF_32_63);
\r
779 INSTALL_HANDLERS(Can_B, FLEXCAN_1_ESR_BOFF_INT, FLEXCAN_1_ESR_ERR_INT, FLEXCAN_1_BUF_00_03, FLEXCAN_1_BUF_32_63);
\r
785 switch( canHwConfig->CanControllerId ) {
\r
787 INSTALL_HANDLERS(Can_A, FLEXCAN_A_ESR_BOFF_INT, FLEXCAN_A_ESR_ERR_INT, FLEXCAN_A_IFLAG1_BUF0I, FLEXCAN_A_IFLAG1_BUF31_16I); break;
\r
789 INSTALL_HANDLERS(Can_B, FLEXCAN_B_ESR_BOFF_INT, FLEXCAN_B_ESR_ERR_INT, FLEXCAN_B_IFLAG1_BUF0I, FLEXCAN_B_IFLAG1_BUF31_16I); break;
\r
791 INSTALL_HANDLERS(Can_C, FLEXCAN_C_ESR_BOFF_INT, FLEXCAN_C_ESR_ERR_INT, FLEXCAN_C_IFLAG1_BUF0I, FLEXCAN_C_IFLAG1_BUF31_16I); break;
\r
793 INSTALL_HANDLERS(Can_D, FLEXCAN_D_ESR_BOFF_INT, FLEXCAN_D_ESR_ERR_INT, FLEXCAN_D_IFLAG1_BUF0I, FLEXCAN_D_IFLAG1_BUF31_16I); break;
\r
795 INSTALL_HANDLERS(Can_E, FLEXCAN_E_ESR_BOFF_INT, FLEXCAN_E_ESR_ERR_INT, FLEXCAN_E_IFLAG1_BUF0I, FLEXCAN_E_IFLAG1_BUF31_16I); break;
\r
797 INSTALL_HANDLERS(Can_F, FLEXCAN_F_ESR_BOFF_INT, FLEXCAN_F_ESR_ERR_INT, FLEXCAN_F_IFLAG1_BUF0I, FLEXCAN_F_IFLAG1_BUF31_16I); break;
\r
806 // Unitialize the module
\r
809 Can_UnitType *canUnit;
\r
810 const Can_ControllerConfigType *canHwConfig;
\r
813 for (int configId=0; configId < CAN_ARC_CTRL_CONFIG_CNT; configId++) {
\r
814 canHwConfig = GET_CONTROLLER_CONFIG(configId);
\r
815 ctlrId = canHwConfig->CanControllerId;
\r
817 canUnit = GET_PRIVATE_DATA(ctlrId);
\r
818 canUnit->state = CANIF_CS_UNINIT;
\r
820 Can_DisableControllerInterrupts(ctlrId);
\r
822 canUnit->lock_cnt = 0;
\r
825 memset(&canUnit->stats, 0, sizeof(Can_Arc_StatisticsType));
\r
828 Can_Global.config = NULL;
\r
829 Can_Global.initRun = CAN_UNINIT;
\r
834 void Can_InitController( uint8 controller, const Can_ControllerConfigType *config) {
\r
842 Can_UnitType *canUnit;
\r
843 uint8 cId = controller;
\r
844 const Can_ControllerConfigType *canHwConfig;
\r
845 const Can_HardwareObjectType *hohObj;
\r
847 VALIDATE_NO_RV( (Can_Global.initRun == CAN_READY), 0x2, CAN_E_UNINIT );
\r
848 VALIDATE_NO_RV( (config != NULL ), 0x2,CAN_E_PARAM_POINTER);
\r
849 VALIDATE_NO_RV( (controller < GET_CONTROLLER_CNT()), 0x2, CAN_E_PARAM_CONTROLLER );
\r
851 canUnit = GET_PRIVATE_DATA(controller);
\r
853 VALIDATE_NO_RV( (canUnit->state==CANIF_CS_STOPPED), 0x2, CAN_E_TRANSITION );
\r
855 canHw = GET_CONTROLLER(cId);
\r
856 canHwConfig = GET_CONTROLLER_CONFIG(Can_Global.channelMap[cId]);
\r
858 // Start this baby up
\r
859 canHw->MCR.B.MDIS = 0;
\r
861 // Wait for it to reset
\r
862 if( !SIMULATOR() ) {
\r
863 // Make a reset so we have a known state
\r
864 //canHw->MCR.B.SOFTRST = 1; /* commented out for step-in debug mode */
\r
865 //while( canHw->MCR.B.SOFTRST == 1);
\r
866 // Freeze to write all mem mapped registers ( see 25.4.8.1 )
\r
867 canHw->MCR.B.FRZ = 1;
\r
868 //while( canHw->MCR.B.FRZACK == 0);
\r
871 #if defined(CFG_MPC5516) || defined(CFG_MPC5517) || defined(CFG_MPC5606S)
\r
873 // FIFO implemenation not tested
\r
874 if( config->Can_Arc_Fifo ) {
\r
875 canHw->MCR.B.FEN = 1; // Enable FIFO
\r
876 canHw->MCR.B.IDAM = 0; // We want extended id's to match with
\r
878 canHw->MCR.B.BCC = 1; // Enable all nice features
\r
880 /* Use Fsys derivate */
\r
881 canHw->CR.B.CLKSRC = 1;
\r
882 canHw->MCR.B.MAXMB = MAX_NUM_OF_MAILBOXES - 1;
\r
884 /* Disable selfreception */
\r
885 canHw->MCR.B.SRXDIS = !config->Can_Arc_Loopback;
\r
887 // Clock calucation
\r
888 // -------------------------------------------------------------------
\r
890 // * 1 TQ = Sclk period( also called SCK )
\r
891 // * Ftq = Fcanclk / ( PRESDIV + 1 ) = Sclk
\r
892 // ( Fcanclk can come from crystal or from the peripheral dividers )
\r
895 // TQ = 1/Ftq = (PRESDIV+1)/Fcanclk --> PRESDIV = (TQ * Fcanclk - 1 )
\r
896 // TQ is between 8 and 25
\r
898 // Calculate the number of timequanta's
\r
899 // From "Protocol Timing"( chap. 25.4.7.4 )
\r
900 tq1 = ( config->CanControllerPropSeg + config->CanControllerSeg1 + 2);
\r
901 tq2 = (config->CanControllerSeg2 + 1);
\r
902 tq = 1 + tq1 + tq2;
\r
904 // Check TQ limitations..
\r
905 VALIDATE_DEM_NO_RV(( (tq1>=4) && (tq1<=16)), CAN_E_TIMEOUT );
\r
906 VALIDATE_DEM_NO_RV(( (tq2>=2) && (tq2<=8)), CAN_E_TIMEOUT );
\r
907 VALIDATE_DEM_NO_RV(( (tq>8) && (tq<25 )), CAN_E_TIMEOUT );
\r
909 // Assume we're using the peripheral clock instead of the crystal.
\r
910 clock = McuE_GetPeripheralClock( (McuE_PeriperalClock_t) config->CanCpuClockRef );
\r
912 canHw->CR.B.PRESDIV = clock/(config->CanControllerBaudRate*1000*tq) - 1;
\r
913 canHw->CR.B.PROPSEG = config->CanControllerPropSeg;
\r
914 canHw->CR.B.PSEG1 = config->CanControllerSeg1;
\r
915 canHw->CR.B.PSEG2 = config->CanControllerSeg2;
\r
916 canHw->CR.B.SMP = 1; // 3 samples better than 1 ??
\r
917 canHw->CR.B.LPB = config->Can_Arc_Loopback;
\r
918 canHw->CR.B.BOFFREC = 1; // Disable bus off recovery
\r
920 SIU.PSMI[0].R = 0x00;
\r
921 SIU.PSMI[1].R = 0x00;
\r
923 #if defined(CFG_MPC5516) || defined(CFG_MPC5517) || defined(CFG_MPC5606S)
\r
924 // Check if we use individual masks. If so accept anything(=0) for now
\r
925 if( canHw->MCR.B.BCC ) {
\r
926 i = (config->Can_Arc_Fifo ? 8 : 0 );
\r
928 canHw->RXIMR[i].R = 0;
\r
932 #if defined(CFG_MPC5567)
\r
933 // Enable individual Rx ID masking and the reception queue features.
\r
934 canHw->MCR.B.MBFEN = 1;
\r
937 if( config->Can_Arc_Fifo ) {
\r
938 // Clear ID's in FIFO also, MUST set extended bit here
\r
939 uint32_t *fifoId = (uint32_t*)(((uint8_t *)canHw)+0xe0);
\r
940 for(int k=0;k<8;k++) {
\r
941 fifoId[k] = 0x40000000; // accept extended frames
\r
945 // Mark all slots as inactive( depending on fifo )
\r
946 i = (config->Can_Arc_Fifo ? 8 : 0 );
\r
947 for(; i < 63; i++) {
\r
948 //canHw->BUF[i].CS.B.CODE = 0;
\r
949 canHw->BUF[i].CS.R = 0;
\r
950 canHw->BUF[i].ID.R = 0;
\r
954 /* Build a global interrupt/mb mask for all Hoh's */
\r
957 Can_FilterMaskType mask = 0xffffffff;
\r
960 hohObj = canHwConfig->Can_Arc_Hoh;
\r
965 mbMask = hohObj->Can_Arc_MbMask;
\r
968 if (hohObj->CanObjectType == CAN_OBJECT_TYPE_RECEIVE)
\r
970 for(;mbMask;mbMask&=~(1<<mbNr)) {
\r
971 mbNr = ilog2(mbMask);
\r
972 canHw->BUF[mbNr].CS.B.CODE = MB_RX;
\r
973 if ( hohObj->CanIdType == CAN_ID_TYPE_EXTENDED )
\r
975 canHw->BUF[mbNr].CS.B.IDE = 1;
\r
976 #if defined(CFG_MPC5567)
\r
977 canHw->RXIMR[mbNr].B.MI = *hohObj->CanFilterMaskRef;
\r
979 canHw->BUF[mbNr].ID.R = *hohObj->CanFilterMaskRef; // Write 29-bit MB IDs
\r
984 canHw->BUF[mbNr].CS.B.IDE = 0;
\r
985 #if defined(CFG_MPC5567)
\r
986 canHw->RXIMR[mbNr].B.MI = *hohObj->CanFilterMaskRef;
\r
988 canHw->BUF[mbNr].ID.B.STD_ID = *hohObj->CanFilterMaskRef;
\r
993 // Add to global mask
\r
994 canUnit->Can_Arc_RxMbMask |= hohObj->Can_Arc_MbMask;
\r
995 if( hohObj->CanFilterMaskRef != NULL ) {
\r
996 mask &= *hohObj->CanFilterMaskRef;
\r
1001 canUnit->Can_Arc_TxMbMask |= hohObj->Can_Arc_MbMask;
\r
1003 } while( !hohObj->Can_Arc_EOL );
\r
1005 #if defined(CFM_MPC5567)
\r
1007 // Set global mask
\r
1008 canHw->RXGMASK.R = mask;
\r
1010 canHw->RX14MASK.R = 0;
\r
1011 canHw->RX15MASK.R = 0;
\r
1015 canUnit->iflagStart = canUnit->Can_Arc_TxMbMask;
\r
1017 canUnit->state = CANIF_CS_STOPPED;
\r
1018 Can_EnableControllerInterrupts(cId);
\r
1024 Can_ReturnType Can_SetControllerMode( uint8 controller, Can_StateTransitionType transition ) {
\r
1026 Can_ReturnType rv = CAN_OK;
\r
1027 VALIDATE( (controller < GET_CONTROLLER_CNT()), 0x3, CAN_E_PARAM_CONTROLLER );
\r
1029 Can_UnitType *canUnit = GET_PRIVATE_DATA(controller);
\r
1031 VALIDATE( (canUnit->state!=CANIF_CS_UNINIT), 0x3, CAN_E_UNINIT );
\r
1032 canHw = GET_CONTROLLER(controller);
\r
1034 switch(transition )
\r
1037 canHw->MCR.B.FRZ = 0;
\r
1038 canHw->MCR.B.HALT = 0;
\r
1039 canUnit->state = CANIF_CS_STARTED;
\r
1040 imask_t state = McuE_EnterCriticalSection();
\r
1041 if (canUnit->lock_cnt == 0) // REQ CAN196
\r
1043 Can_EnableControllerInterrupts(controller);
\r
1045 McuE_ExitCriticalSection(state);
\r
1047 case CAN_T_WAKEUP: //CAN267
\r
1048 case CAN_T_SLEEP: //CAN258, CAN290
\r
1049 // Should be reported to DEM but DET is the next best
\r
1050 VALIDATE(canUnit->state == CANIF_CS_STOPPED, 0x3, CAN_E_TRANSITION);
\r
1053 canHw->MCR.B.FRZ = 1;
\r
1054 canHw->MCR.B.HALT = 1;
\r
1055 canUnit->state = CANIF_CS_STOPPED;
\r
1056 Can_AbortTx( canHw, canUnit ); // CANIF282
\r
1059 // Should be reported to DEM but DET is the next best
\r
1060 VALIDATE(canUnit->state == CANIF_CS_STOPPED, 0x3, CAN_E_TRANSITION);
\r
1067 void Can_DisableControllerInterrupts( uint8 controller )
\r
1069 Can_UnitType *canUnit;
\r
1072 VALIDATE_NO_RV( (controller < GET_CONTROLLER_CNT()), 0x4, CAN_E_PARAM_CONTROLLER );
\r
1074 canUnit = GET_PRIVATE_DATA(controller);
\r
1076 VALIDATE_NO_RV( (canUnit->state!=CANIF_CS_UNINIT), 0x4, CAN_E_UNINIT );
\r
1078 imask_t state = McuE_EnterCriticalSection();
\r
1079 if(canUnit->lock_cnt > 0 )
\r
1081 // Interrupts already disabled
\r
1082 canUnit->lock_cnt++;
\r
1083 McuE_ExitCriticalSection(state);
\r
1086 canUnit->lock_cnt++;
\r
1087 McuE_ExitCriticalSection(state);
\r
1089 /* Don't try to be intelligent, turn everything off */
\r
1090 canHw = GET_CONTROLLER(controller);
\r
1092 /* Turn off the interrupt mailboxes */
\r
1093 canHw->IMRH.R = 0;
\r
1094 canHw->IMRL.R = 0;
\r
1096 /* Turn off the bus off/tx warning/rx warning and error */
\r
1097 canHw->MCR.B.WRNEN = 0; /* Disable warning int */
\r
1098 canHw->CR.B.ERRMSK = 0; /* Disable error interrupt */
\r
1099 canHw->CR.B.BOFFMSK = 0; /* Disable bus-off interrupt */
\r
1100 canHw->CR.B.TWRNMSK = 0; /* Disable Tx warning */
\r
1101 canHw->CR.B.RWRNMSK = 0; /* Disable Rx warning */
\r
1104 void Can_EnableControllerInterrupts( uint8 controller ) {
\r
1105 Can_UnitType *canUnit;
\r
1107 const Can_ControllerConfigType *canHwConfig;
\r
1108 VALIDATE_NO_RV( (controller < GET_CONTROLLER_CNT()), 0x5, CAN_E_PARAM_CONTROLLER );
\r
1110 canUnit = GET_PRIVATE_DATA(controller);
\r
1112 VALIDATE_NO_RV( (canUnit->state!=CANIF_CS_UNINIT), 0x5, CAN_E_UNINIT );
\r
1114 imask_t state = McuE_EnterCriticalSection();
\r
1115 if( canUnit->lock_cnt > 1 )
\r
1117 // IRQ should still be disabled so just decrement counter
\r
1118 canUnit->lock_cnt--;
\r
1119 McuE_ExitCriticalSection(state);
\r
1121 } else if (canUnit->lock_cnt == 1)
\r
1123 canUnit->lock_cnt = 0;
\r
1125 McuE_ExitCriticalSection(state);
\r
1127 canHw = GET_CONTROLLER(controller);
\r
1129 canHwConfig = GET_CONTROLLER_CONFIG(Can_Global.channelMap[controller]);
\r
1131 canHw->IMRH.R = 0;
\r
1132 canHw->IMRL.R = 0;
\r
1134 if( canHwConfig->CanRxProcessing == CAN_ARC_PROCESS_TYPE_INTERRUPT ) {
\r
1135 /* Turn on the interrupt mailboxes */
\r
1136 canHw->IMRL.R = canUnit->Can_Arc_RxMbMask;
\r
1139 if( canHwConfig->CanTxProcessing == CAN_ARC_PROCESS_TYPE_INTERRUPT ) {
\r
1140 /* Turn on the interrupt mailboxes */
\r
1141 canHw->IMRL.R |= canUnit->Can_Arc_TxMbMask;
\r
1144 // BusOff here represents all errors and warnings
\r
1145 if( canHwConfig->CanBusOffProcessing == CAN_ARC_PROCESS_TYPE_INTERRUPT ) {
\r
1146 canHw->MCR.B.WRNEN = 1; /* Turn On warning int */
\r
1148 canHw->CR.B.ERRMSK = 1; /* Enable error interrupt */
\r
1149 canHw->CR.B.BOFFMSK = 1; /* Enable bus-off interrupt */
\r
1150 canHw->CR.B.TWRNMSK = 1; /* Enable Tx warning */
\r
1151 canHw->CR.B.RWRNMSK = 1; /* Enable Rx warning */
\r
1157 Can_ReturnType Can_Write( Can_Arc_HTHType hth, Can_PduType *pduInfo ) {
\r
1160 Can_ReturnType rv = CAN_OK;
\r
1163 const Can_HardwareObjectType *hohObj;
\r
1164 uint32 controller;
\r
1167 VALIDATE( (Can_Global.initRun == CAN_READY), 0x6, CAN_E_UNINIT );
\r
1168 VALIDATE( (pduInfo != NULL), 0x6, CAN_E_PARAM_POINTER );
\r
1169 VALIDATE( (pduInfo->length <= 8), 0x6, CAN_E_PARAM_DLC );
\r
1170 VALIDATE( (hth < NUM_OF_HTHS ), 0x6, CAN_E_PARAM_HANDLE );
\r
1172 hohObj = Can_FindHoh(hth, &controller);
\r
1173 if (hohObj == NULL)
\r
1174 return CAN_NOT_OK;
\r
1176 Can_UnitType *canUnit = GET_PRIVATE_DATA(controller);
\r
1178 canHw = GET_CONTROLLER(controller);
\r
1179 oldMsr = McuE_EnterCriticalSection();
\r
1180 iflag = canHw->IFRL.R & canUnit->Can_Arc_TxMbMask;
\r
1182 // check for any free box
\r
1183 // Normally we would just use the iflag to get the free box
\r
1184 // but that does not work the first time( iflag == 0 ) so we
\r
1185 // create one( iflagStart )
\r
1186 if( iflag | canUnit->iflagStart ) {
\r
1187 mbNr = ilog2((iflag | canUnit->iflagStart)); // find mb number
\r
1189 canHw->IFRL.R = (1<<mbNr);
\r
1190 canUnit->iflagStart &= ~(1<<mbNr);
\r
1192 // Setup message box type
\r
1193 if( hohObj->CanIdType == CAN_ID_TYPE_EXTENDED ) {
\r
1194 canHw->BUF[mbNr].CS.B.IDE = 1;
\r
1195 } else if ( hohObj->CanIdType == CAN_ID_TYPE_STANDARD ) {
\r
1196 canHw->BUF[mbNr].CS.B.IDE = 0;
\r
1198 // No support for mixed in this processor
\r
1203 canHw->BUF[mbNr].CS.B.CODE = MB_INACTIVE; // Hold the transmit buffer inactive
\r
1204 if( hohObj->CanIdType == CAN_ID_TYPE_EXTENDED ) {
\r
1205 canHw->BUF[mbNr].ID.R = pduInfo->id; // Write 29-bit MB IDs
\r
1207 assert( !(pduInfo->id & 0xfffff800) );
\r
1208 canHw->BUF[mbNr].ID.B.STD_ID = pduInfo->id;
\r
1211 #if defined(CFG_MPC5516) || defined(CFG_MPC5517) || defined(CFG_MPC5606S)
\r
1212 canHw->BUF[mbNr].ID.B.PRIO = 1; // Set Local Priority
\r
1215 memset(&canHw->BUF[mbNr].DATA, 0, 8);
\r
1216 memcpy(&canHw->BUF[mbNr].DATA, pduInfo->sdu, pduInfo->length);
\r
1218 canHw->BUF[mbNr].CS.B.SRR = 1;
\r
1219 canHw->BUF[mbNr].CS.B.RTR = 0;
\r
1221 canHw->BUF[mbNr].CS.B.LENGTH = pduInfo->length;
\r
1222 canHw->BUF[mbNr].CS.B.CODE = MB_TX_ONCE; // Write tx once code
\r
1223 timer = canHw->TIMER.R; // Unlock Message buffers
\r
1225 canUnit->stats.txSuccessCnt++;
\r
1227 // Store pdu handle in unit to be used by TxConfirmation
\r
1228 canUnit->swPduHandles[mbNr] = pduInfo->swPduHandle;
\r
1233 McuE_ExitCriticalSection(oldMsr);
\r
1238 void Can_MainFunction_Read( void ) {
\r
1240 /* NOT SUPPORTED */
\r
1243 void Can_MainFunction_BusOff( void ) {
\r
1244 /* Bus-off polling events */
\r
1246 /* NOT SUPPORTED */
\r
1249 void Can_MainFunction_Wakeup( void ) {
\r
1250 /* Wakeup polling events */
\r
1252 /* NOT SUPPORTED */
\r
1257 * Get send/receive/error statistics for a controller
\r
1259 * @param controller The controller
\r
1260 * @param stats Pointer to data to copy statistics to
\r
1263 void Can_Arc_GetStatistics( uint8 controller, Can_Arc_StatisticsType *stats)
\r
1265 Can_UnitType *canUnit = GET_PRIVATE_DATA(controller);
\r
1266 *stats = canUnit->stats;
\r
1271 #else // Stub all functions for use in simulator environment
\r
1273 #include "debug.h"
\r
1275 void Can_Init( const Can_ConfigType *Config )
\r
1277 // Do initial configuration of layer here
\r
1280 void Can_InitController( uint8 controller, const Can_ControllerConfigType *config)
\r
1282 // Do initialisation of controller here.
\r
1285 Can_ReturnType Can_SetControllerMode( uint8 Controller, Can_StateTransitionType transition )
\r
1287 // Turn on off controller here depending on transition
\r
1291 Can_ReturnType Can_Write( Can_Arc_HTHType hth, Can_PduType *pduInfo )
\r
1293 // Write to mailbox on controller here.
\r
1294 DEBUG(DEBUG_MEDIUM, "Can_Write(stub): Received data ");
\r
1295 for (int i = 0; i < pduInfo->length; i++) {
\r
1296 DEBUG(DEBUG_MEDIUM, "%d ", pduInfo->sdu[i]);
\r
1298 DEBUG(DEBUG_MEDIUM, "\n");
\r
1303 extern void CanIf_RxIndication(uint8 Hrh, Can_IdType CanId, uint8 CanDlc, const uint8 *CanSduPtr);
\r
1304 Can_ReturnType Can_ReceiveAFrame()
\r
1306 // This function is not part of autosar but needed to feed the stack with data
\r
1307 // from the mailboxes. Normally this is an interrup but probably not in the PCAN case.
\r
1308 uint8 CanSduData[] = {1,2,1,0,0,0,0,0};
\r
1309 CanIf_RxIndication(CAN_HRH_A_1, 3, 8, CanSduData);
\r
1314 void Can_DisableControllerInterrupts( uint8 controller )
\r
1318 void Can_EnableControllerInterrupts( uint8 controller )
\r
1323 // Hth - for Flexcan, the hardware message box number... .We don't care
\r
1324 void Can_Cbk_CheckWakeup( uint8 controller ){}
\r
1326 void Can_MainFunction_Write( void ){}
\r
1327 void Can_MainFunction_Read( void ){}
\r
1328 void Can_MainFunction_BusOff( void ){}
\r
1329 void Can_MainFunction_Wakeup( void ){}
\r
1331 void Can_Arc_GetStatistics( uint8 controller, Can_Arc_StatisticsType * stat){}
\r