1 /* ----------------------------------------------------------------------------
\r
2 * SAM Software Package License
\r
3 * ----------------------------------------------------------------------------
\r
4 * Copyright (c) 2012, Atmel Corporation
\r
6 * All rights reserved.
\r
8 * Redistribution and use in source and binary forms, with or without
\r
9 * modification, are permitted provided that the following conditions are met:
\r
11 * - Redistributions of source code must retain the above copyright notice,
\r
12 * this list of conditions and the disclaimer below.
\r
14 * Atmel's name may not be used to endorse or promote products derived from
\r
15 * this software without specific prior written permission.
\r
17 * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
\r
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
\r
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
\r
20 * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
\r
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
\r
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
\r
23 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
\r
24 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
\r
25 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
\r
26 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\r
27 * ----------------------------------------------------------------------------
\r
31 * Implements functions for Controller Area Network (CAN)
\r
32 * peripheral operations.
\r
34 /** \addtogroup can_module
\r
37 /*----------------------------------------------------------------------------
\r
39 *----------------------------------------------------------------------------*/
\r
45 #if defined(REG_CAN0_MR) || defined(REG_CAN_MR)
\r
47 /* ----------- CAN_MR Operations --------------- */
\r
49 * \brief Set CAN Mode Register (CAN_MR)
\r
50 * \param pCan Pointer to Can instance.
\r
51 * \param dwMr Mode register settings.
\r
53 void CAN_ConfigureMode(Can *pCan, uint32_t dwMr)
\r
55 pCan->CAN_MR = dwMr;
\r
59 * \brief CAN Controller Enable/Disable
\r
60 * \param pCan Pointer to Can instance.
\r
61 * \param bEnDis 1 to enable and 0 to disable.
\r
63 void CAN_Enable(Can *pCan, uint8_t bEnDis)
\r
65 if (bEnDis) pCan->CAN_MR |= CAN_MR_CANEN;
\r
66 else pCan->CAN_MR &= ~CAN_MR_CANEN;
\r
70 * \brief CAN Low Power Mode Enable/Disable
\r
71 * \param pCan Pointer to Can instance.
\r
72 * \param bEnDis 1 to enable and 0 to disable.
\r
74 void CAN_EnableLowPower(Can *pCan, uint8_t bEnDis)
\r
76 if (bEnDis) pCan->CAN_MR |= CAN_MR_LPM;
\r
77 else pCan->CAN_MR &= ~CAN_MR_LPM;
\r
81 * \brief CAN Autobaud/Listen mode
\r
82 * \param pCan Pointer to Can instance.
\r
83 * \param bEnDis 1 to enable and 0 to disable.
\r
85 void CAN_EnableAutobaud(Can *pCan, uint8_t bEnDis)
\r
87 if (bEnDis) pCan->CAN_MR |= CAN_MR_ABM;
\r
88 else pCan->CAN_MR &= ~CAN_MR_ABM;
\r
92 * \brief CAN Overload Frame Enable/Disable
\r
93 * \param pCan Pointer to Can instance.
\r
94 * \param bEnDis 1 to enable and 0 to disable.
\r
96 void CAN_EnableOverloadFrame(Can *pCan, uint8_t bEnDis)
\r
98 if (bEnDis) pCan->CAN_MR |= CAN_MR_OVL;
\r
99 else pCan->CAN_MR &= ~CAN_MR_OVL;
\r
103 * \brief CAN Timestamp capture mode (@EOF/@SOF).
\r
104 * \param pCan Pointer to Can instance.
\r
105 * \param bEofSof 1 for EOF/0 for SOF.
\r
107 void CAN_EnableTimeStampEof(Can *pCan, uint8_t bEofSof)
\r
109 if (bEofSof) pCan->CAN_MR |= CAN_MR_TEOF;
\r
110 else pCan->CAN_MR &= ~CAN_MR_TEOF;
\r
114 * \brief CAN Time Triggered Mode Enable/Disable
\r
115 * \param pCan Pointer to Can instance.
\r
116 * \param bEnDis Enable/Disable Time Trigger Mode.
\r
118 void CAN_EnableTimeTriggerMode(Can *pCan, uint8_t bEnDis)
\r
120 if (bEnDis) pCan->CAN_MR |= CAN_MR_TTM;
\r
121 else pCan->CAN_MR &= ~CAN_MR_TTM;
\r
125 * \brief CAN Timer Freeze Enable/Disable
\r
126 * \param pCan Pointer to Can instance.
\r
127 * \param bEnDis Enable/Disable Timer Freeze.
\r
129 void CAN_EnableTimerFreeze(Can *pCan, uint8_t bEnDis)
\r
131 if (bEnDis) pCan->CAN_MR |= CAN_MR_TIMFRZ;
\r
132 else pCan->CAN_MR &= ~CAN_MR_TIMFRZ;
\r
136 * \brief CAN Repeat Disable/Enable.
\r
137 * \param pCan Pointer to Can instance.
\r
138 * \param bEnDis Disable/Enable Repeat.
\r
140 void CAN_DisableRepeat(Can *pCan, uint8_t bDisEn)
\r
142 if (bDisEn) pCan->CAN_MR |= CAN_MR_DRPT;
\r
143 else pCan->CAN_MR &= ~CAN_MR_DRPT;
\r
146 /* ---------- Interrupt settings ------------- */
\r
149 * \brief CAN Interrupts Enable
\r
150 * \param pCan Pointer to Can instance.
\r
151 * \param dwSources Interrupt sources bits.
\r
153 void CAN_EnableIt(Can *pCan, uint32_t dwSources)
\r
155 pCan->CAN_IER = dwSources;
\r
159 * \brief CAN Interrupts Disable
\r
160 * \param pCan Pointer to Can instance.
\r
161 * \param dwSources Interrupt sources bits.
\r
163 void CAN_DisableIt(Can *pCan, uint32_t dwSources)
\r
165 pCan->CAN_IDR = dwSources;
\r
169 * \brief Return CAN Interrupts Masks
\r
170 * \param pCan Pointer to Can instance.
\r
172 uint32_t CAN_GetItMask(Can *pCan)
\r
174 return pCan->CAN_IMR;
\r
178 * \brief Return CAN Statuses
\r
179 * \param pCan Pointer to Can instance.
\r
181 uint32_t CAN_GetStatus(Can *pCan)
\r
183 return pCan->CAN_SR;
\r
187 * \brief Calculate and configure the baudrate
\r
188 * \param pCan Pointer to Can instance.
\r
189 * \param dwBaudrate Baudrate value (kB/s)
\r
190 * allowed: 100, 800, 500, 250, 125, 50, 25, 10
\r
191 * \param dwMck MCK.
\r
192 * \return 1 in success, otherwise return 0.
\r
194 uint8_t CAN_CalcBaudrate(Can *pCan, uint32_t dwBaudrate, uint32_t dwMck)
\r
196 uint32_t BRP, PROPAG, PHASE1, PHASE2, SJW;
\r
200 uint32_t id = ID_CAN0;
\r
202 if ((uint32_t)pCan == (uint32_t)CAN0) id = ID_CAN0;
\r
203 else if ((uint32_t)pCan == (uint32_t)CAN1) id = ID_CAN1;
\r
204 maxClock = PMC_SetPeriMaxClock(id, dwMck);
\r
206 if (dwBaudrate >= 1000) TQ = 8;
\r
208 BRP = (maxClock / (dwBaudrate * 1000 * TQ)) - 1;
\r
214 Delay Bus Driver - 50ns
\r
215 Delay Receiver - 30ns
\r
216 Delay Bus Line (20m) - 110ns */
\r
217 if ( (TQ * dwBaudrate * 2 * (50+30+110)/1000000) >= 1 )
\r
218 PROPAG = (TQ * dwBaudrate * 2 * (50+30+110)/1000000) - 1;
\r
221 t1t2 = TQ - 1 - (PROPAG + 1);
\r
223 if ( (t1t2 & 0x01) == 0x01 ) {
\r
224 PHASE1 = ((t1t2 - 1) / 2) - 1;
\r
225 PHASE2 = PHASE1 + 1;
\r
228 PHASE1 = ((t1t2) / 2) - 1;
\r
232 if ( 1 > (4/(PHASE1 + 1)) ) SJW = 3;
\r
235 if ( (PROPAG + PHASE1 + PHASE2) != (uint32_t)(TQ - 4) ) {
\r
239 pCan->CAN_BR = CAN_BR_PHASE2(PHASE2)
\r
240 | CAN_BR_PHASE1(PHASE1)
\r
241 | CAN_BR_PROPAG(PROPAG)
\r
249 * \brief Set CAN baudrate register
\r
250 * \param pCan Pointer to Can instance.
\r
251 * \param dwBr Setting value for CAN_BR.
\r
253 void CAN_ConfigureBaudrate(Can *pCan, uint32_t dwBr)
\r
255 pCan->CAN_BR = dwBr;
\r
259 * \brief Set CAN Sampling Mode
\r
260 * \param pCan Pointer to Can instance.
\r
261 * \param bAvg3 Sample 3 times/sample once at sample point.
\r
263 void CAN_SetSamplingMode(Can *pCan, uint8_t bAvg3)
\r
265 if (bAvg3) pCan->CAN_BR |= CAN_BR_SMP;
\r
266 else pCan->CAN_BR &= ~CAN_BR_SMP;
\r
270 * \brief Return CAN Timer Register
\r
271 * \param pCan Pointer to Can instance.
\r
273 uint32_t CAN_GetTimer(Can *pCan)
\r
275 return pCan->CAN_TIM;
\r
279 * \brief Return CAN TimeStamp Register
\r
280 * \param pCan Pointer to Can instance.
\r
282 uint32_t CAN_GetTimestamp(Can *pCan)
\r
284 return pCan->CAN_TIMESTP;
\r
288 * \brief Return Error Count (TEC << 16) + REC
\r
289 * \param pCan Pointer to Can instance.
\r
291 uint32_t CAN_GetErrorCount(Can *pCan)
\r
293 return pCan->CAN_ECR;
\r
297 * \brief Return Receive Error Count
\r
298 * \param pCan Pointer to Can instance.
\r
300 uint32_t CAN_GetRxErrorCount(Can *pCan)
\r
302 return (pCan->CAN_ECR & CAN_ECR_REC_Msk) >> CAN_ECR_REC_Pos;
\r
306 * \brief Return Transmit Error Count
\r
307 * \param pCan Pointer to Can instance.
\r
309 uint32_t CAN_GetTxErrorCount(Can *pCan)
\r
311 return (pCan->CAN_ECR & CAN_ECR_TEC_Msk) >> CAN_ECR_TEC_Pos;
\r
315 * \brief Set Transfer Command Register to initialize transfer requests.
\r
316 * \param pCan Pointer to Can instance.
\r
317 * \param dwRequests Transfer Command Requests.
\r
319 void CAN_Command(Can *pCan, uint32_t dwRequests)
\r
321 pCan->CAN_TCR = dwRequests;
\r
325 * \brief Resets CAN internal timer counter.
\r
326 * \param pCan Pointer to Can instance.
\r
328 void CAN_ResetTimer(Can *pCan)
\r
330 pCan->CAN_TCR = CAN_TCR_TIMRST;
\r
334 * \brief Request transfer on mailbox.
\r
335 * \param pCan Pointer to Can instance.
\r
336 * \param bMb Mailbox number.
\r
338 void CAN_Tx(Can *pCan, uint8_t bMb)
\r
340 pCan->CAN_TCR = CAN_TCR_MB0 << bMb;
\r
344 * \brief Abort transfer on several mailboxes.
\r
345 * \param pCan Pointer to Can instance.
\r
346 * \param dwAborts Abort requests.
\r
348 void CAN_Abort(Can *pCan, uint32_t dwAborts)
\r
350 pCan->CAN_ACR = dwAborts;
\r
354 * \brief Abort transfer on single mailbox.
\r
355 * \param pCan Pointer to Can instance.
\r
356 * \param bMb Mailbox number.
\r
358 void CAN_AbortMailbox(Can *pCan, uint8_t bMb)
\r
360 pCan->CAN_ACR = CAN_ACR_MB0 << bMb;
\r
364 * \brief Configure CAN Message Mode (_MMRx)
\r
365 * \param pCan Pointer to Can instance.
\r
366 * \param bMb Mailbox number.
\r
367 * \param dwMr Mode settings.
\r
369 void CAN_ConfigureMessageMode(Can *pCan, uint8_t bMb, uint32_t dwMr)
\r
371 pCan->CAN_MB[bMb].CAN_MMR = dwMr;
\r
375 * \brief Return CAN Message Mode (_MMRx)
\r
376 * \param pCan Pointer to Can instance.
\r
377 * \param bMb Mailbox number.
\r
379 uint32_t CAN_GetMessageMode(Can *pCan, uint8_t bMb)
\r
381 return pCan->CAN_MB[bMb].CAN_MMR;
\r
385 * \brief Set Mailbox Timemark for Time Triggered Mode.
\r
386 * \param pCan Pointer to Can instance.
\r
387 * \param bMb Mailbox number.
\r
388 * \param bTimemarks Mailbox timemarks.
\r
390 void CAN_SetTimemark(Can *pCan, uint8_t bMb, uint8_t bTimemarks)
\r
392 uint32_t dwMmr = (pCan->CAN_MB[bMb].CAN_MMR) & (~0xFFu);
\r
393 pCan->CAN_MB[bMb].CAN_MMR = dwMmr | ((bTimemarks << 0) & 0xFF);
\r
397 * \brief Set Mailbox Priority.
\r
398 * \param pCan Pointer to Can instance.
\r
399 * \param bMb Mailbox number.
\r
400 * \param bPriority Mailbox Priority.
\r
402 void CAN_SetPriority(Can *pCan, uint8_t bMb, uint8_t bPriority)
\r
404 uint32_t dwMmr = (pCan->CAN_MB[bMb].CAN_MMR & ~CAN_MMR_PRIOR_Msk);
\r
405 pCan->CAN_MB[bMb].CAN_MMR = dwMmr | CAN_MMR_PRIOR(bPriority);
\r
409 * \brief Set Mailbox Object Type.
\r
410 * \param pCan Pointer to Can instance.
\r
411 * \param bMb Mailbox number.
\r
412 * \param bType Mailbox Object Type.
\r
414 void CAN_SetObjectType(Can *pCan, uint8_t bMb, uint8_t bType)
\r
416 uint32_t dwMr = (pCan->CAN_MB[bMb].CAN_MMR & CAN_MMR_MOT_Msk) >> CAN_MMR_MOT_Pos;
\r
417 pCan->CAN_MB[bMb].CAN_MMR |= dwMr | ((bType << CAN_MMR_MOT_Pos) & CAN_MMR_MOT_Msk);
\r
421 * \brief Configure CAN Message Acceptance Mask (_MAMx)
\r
422 * \param pCan Pointer to Can instance.
\r
423 * \param bMb Mailbox number.
\r
424 * \param dwMam The setting value for _MAMx.
\r
426 void CAN_ConfigureMessageAcceptanceMask(Can *pCan, uint8_t bMb, uint32_t dwMAM)
\r
428 pCan->CAN_MB[bMb].CAN_MAM = dwMAM;
\r
432 * \brief Return CAN Message Acceptance Mask (_MAMx)
\r
433 * \param pCan Pointer to Can instance.
\r
434 * \param bMb Mailbox number.
\r
436 uint32_t CAN_GetMessageAcceptanceMask(Can *pCan, uint8_t bMb)
\r
438 return pCan->CAN_MB[bMb].CAN_MAM;
\r
442 * \brief Configure Identifier Version in CAN Message Acceptance Mask (_MAMx)
\r
443 * \param pCan Pointer to Can instance.
\r
444 * \param bMb Mailbox number.
\r
445 * \param bIdCfg IDvA and IDvB/IDvA only Identify.
\r
447 void CAN_ConfigureIdentifierMask(Can *pCan, uint8_t bMb, uint8_t bIdCfg)
\r
449 if (bIdCfg) pCan->CAN_MB[bMb].CAN_MAM |= CAN_MAM_MIDE;
\r
450 else pCan->CAN_MB[bMb].CAN_MAM &= ~CAN_MAM_MIDE;
\r
454 * \brief Set Identifier for standard frame mode (MIDvA) mask
\r
455 * \param pCan Pointer to Can instance.
\r
456 * \param bMb Mailbox number.
\r
457 * \param dwMIDvA Identifier for standard frame mode.
\r
459 void CAN_SetMIDvAMask(Can *pCan, uint8_t bMb, uint32_t dwIDvA)
\r
461 uint32_t dwMam = pCan->CAN_MB[bMb].CAN_MAM & CAN_MAM_MIDvA_Msk;
\r
462 pCan->CAN_MB[bMb].CAN_MAM = dwMam | CAN_MAM_MIDvA(dwIDvA);
\r
466 * \brief Set Complementary bits for identifier in extended frame mode (MIDvB) mask
\r
467 * \param pCan Pointer to Can instance.
\r
468 * \param bMb Mailbox number.
\r
469 * \param dwMIDvB Identifier for extended frame mode.
\r
471 void CAN_SetMIDvBMask(Can *pCan, uint8_t bMb, uint32_t dwIDvA)
\r
473 uint32_t dwMam = pCan->CAN_MB[bMb].CAN_MAM & CAN_MAM_MIDvB_Msk;
\r
474 pCan->CAN_MB[bMb].CAN_MAM = dwMam | CAN_MAM_MIDvB(dwIDvA);
\r
478 * \brief Configure CAN Message ID (_MIDx)
\r
479 * \param pCan Pointer to Can instance.
\r
480 * \param bMb Mailbox number.
\r
481 * \param dwMID The setting value for _MIDx.
\r
483 void CAN_ConfigureMessageID(Can *pCan, uint8_t bMb, uint32_t dwMID)
\r
485 pCan->CAN_MB[bMb].CAN_MID = dwMID;
\r
489 * \brief Return CAN Message ID (_MIDx)
\r
490 * \param pCan Pointer to Can instance.
\r
491 * \param bMb Mailbox number.
\r
493 uint32_t CAN_GetMessageID(Can *pCan, uint8_t bMb)
\r
495 return pCan->CAN_MB[bMb].CAN_MID;
\r
499 * \brief Configure Identifier Version in CAN Message ID register (_MIDx)
\r
500 * \param pCan Pointer to Can instance.
\r
501 * \param bMb Mailbox number.
\r
502 * \param bIdVer 2.0 Part B/2.0 Part A.
\r
504 void CAN_ConfigureIdVer(Can *pCan, uint8_t bMb, uint8_t bIdVer)
\r
506 uint32_t dwMid = pCan->CAN_MB[bMb].CAN_MID & CAN_MID_MIDE;
\r
507 pCan->CAN_MB[bMb].CAN_MID = dwMid | (bIdVer ? CAN_MID_MIDE : 0);
\r
511 * \brief Set Identifier for standard frame mode (MIDvA) value
\r
512 * \param pCan Pointer to Can instance.
\r
513 * \param bMb Mailbox number.
\r
514 * \param dwMIDvA Identifier for standard frame mode.
\r
516 void CAN_SetMIDvA(Can *pCan, uint8_t bMb, uint32_t dwIDvA)
\r
518 uint32_t dwMam = pCan->CAN_MB[bMb].CAN_MID & CAN_MID_MIDvA_Msk;
\r
519 pCan->CAN_MB[bMb].CAN_MID = dwMam | CAN_MID_MIDvA(dwIDvA);
\r
523 * \brief Set Complementary bits for identifier in extended frame mode (MIDvB) value
\r
524 * \param pCan Pointer to Can instance.
\r
525 * \param bMb Mailbox number.
\r
526 * \param dwMIDvB Identifier for extended frame mode.
\r
528 void CAN_SetMIDvB(Can *pCan, uint8_t bMb, uint32_t dwIDvA)
\r
530 uint32_t dwMam = pCan->CAN_MB[bMb].CAN_MID & CAN_MID_MIDvB_Msk;
\r
531 pCan->CAN_MB[bMb].CAN_MID = dwMam | CAN_MID_MIDvB(dwIDvA);
\r
535 * \brief Return CAN Message Family ID (Masked ID)
\r
536 * \param pCan Pointer to Can instance.
\r
537 * \param bMb Mailbox number.
\r
539 uint32_t CAN_GetFamilyID(Can *pCan, uint8_t bMb)
\r
541 return pCan->CAN_MB[bMb].CAN_MFID;
\r
545 * \brief Return CAN Message Status
\r
546 * \param pCan Pointer to Can instance.
\r
547 * \param bMb Mailbox number.
\r
549 uint32_t CAN_GetMessageStatus(Can *pCan, uint8_t bMb)
\r
551 return pCan->CAN_MB[bMb].CAN_MSR;
\r
555 * \brief Return CAN Message Data Low
\r
556 * \param pCan Pointer to Can instance.
\r
557 * \param bMb Mailbox number.
\r
559 uint32_t CAN_GetMessageDataL(Can *pCan, uint8_t bMb)
\r
561 return pCan->CAN_MB[bMb].CAN_MDL;
\r
565 * \brief Set CAN Message Data Low
\r
566 * \param pCan Pointer to Can instance.
\r
567 * \param bMb Mailbox number.
\r
568 * \param dwL Data Low Value.
\r
570 void CAN_SetMessageDataL(Can *pCan, uint8_t bMb, uint32_t dwL)
\r
572 pCan->CAN_MB[bMb].CAN_MDL = dwL;
\r
576 * \brief Set CAN Message Data High
\r
577 * \param pCan Pointer to Can instance.
\r
578 * \param bMb Mailbox number.
\r
579 * \param dwH Data High Value.
\r
581 void CAN_SetMessageDataH(Can *pCan, uint8_t bMb, uint32_t dwH)
\r
583 pCan->CAN_MB[bMb].CAN_MDH = dwH;
\r
587 * \brief Return CAN Message Data High
\r
588 * \param pCan Pointer to Can instance.
\r
589 * \param bMb Mailbox number.
\r
591 uint32_t CAN_GetMessageDataH(Can *pCan, uint8_t bMb)
\r
593 return pCan->CAN_MB[bMb].CAN_MDH;
\r
597 * \brief Copy DW array to CAN Message Data.
\r
598 * \param pCan Pointer to Can instance.
\r
599 * \param bMb Mailbox number.
\r
600 * \param pDwData Pointer to a buffer for data.
\r
602 void CAN_SetMessage(Can *pCan, uint8_t bMb, uint32_t *pDwData)
\r
604 pCan->CAN_MB[bMb].CAN_MDL = pDwData[0];
\r
605 pCan->CAN_MB[bMb].CAN_MDH = pDwData[1];
\r
609 * \brief Copy CAN Message Data to DW array.
\r
610 * \param pCan Pointer to Can instance.
\r
611 * \param bMb Mailbox number.
\r
612 * \param pDwData Pointer to a buffer for data.
\r
614 void CAN_GetMessage(Can *pCan, uint8_t bMb, uint32_t *pDwData)
\r
616 pDwData[0] = pCan->CAN_MB[bMb].CAN_MDL;
\r
617 pDwData[1] = pCan->CAN_MB[bMb].CAN_MDH;
\r
621 * \brief Set CAN Message Data in u64
\r
622 * \param pCan Pointer to Can instance.
\r
623 * \param bMb Mailbox number.
\r
625 void CAN_SetMessageData64(Can *pCan, uint8_t bMb, uint64_t u64)
\r
627 pCan->CAN_MB[bMb].CAN_MDL = (uint32_t)u64;
\r
628 pCan->CAN_MB[bMb].CAN_MDH = (u64 >> 32);
\r
632 * \brief Return CAN Message Data in u64
\r
633 * \param pCan Pointer to Can instance.
\r
634 * \param bMb Mailbox number.
\r
636 uint64_t CAN_GetMessageData64(Can *pCan, uint8_t bMb)
\r
638 uint64_t ddwMd = (uint64_t)pCan->CAN_MB[bMb].CAN_MDH << 32;
\r
639 ddwMd += pCan->CAN_MB[bMb].CAN_MDL;
\r
644 * \brief Set CAN Message Control Register (_MCRx).
\r
645 * \param pCan Pointer to Can instance.
\r
646 * \param bMb Mailbox number.
\r
647 * \param dwCtrl Control value.
\r
649 void CAN_MessageControl(Can *pCan, uint8_t bMb, uint32_t dwCtrl)
\r
651 pCan->CAN_MB[bMb].CAN_MCR = dwCtrl;
\r
655 * \brief Start remote frame.
\r
656 * \param pCan Pointer to Can instance.
\r
657 * \param bMb Mailbox number.
\r
659 void CAN_MessageRemote(Can *pCan, uint8_t bMb)
\r
661 pCan->CAN_MB[bMb].CAN_MCR = CAN_MCR_MRTR;
\r
665 * \brief Abort transmission.
\r
666 * \param pCan Pointer to Can instance.
\r
667 * \param bMb Mailbox number.
\r
669 void CAN_MessageAbort(Can *pCan, uint8_t bMb)
\r
671 pCan->CAN_MB[bMb].CAN_MCR = CAN_MCR_MACR;
\r
675 * \brief Start transmission.
\r
676 * \param pCan Pointer to Can instance.
\r
677 * \param bMb Mailbox number.
\r
678 * \param bLen Message length.
\r
680 void CAN_MessageTx(Can *pCan, uint8_t bMb, uint8_t bLen)
\r
682 pCan->CAN_MB[bMb].CAN_MCR = CAN_MCR_MTCR | CAN_MCR_MDLC(bLen);
\r
686 * \brief Start reception.
\r
687 * \param pCan Pointer to Can instance.
\r
688 * \param bMb Mailbox number.
\r
690 void CAN_MessageRx(Can *pCan, uint8_t bMb)
\r
692 pCan->CAN_MB[bMb].CAN_MCR = CAN_MCR_MTCR;
\r