]> git.sur5r.net Git - freertos/blob - Demo/CORTEX_STM32F103_IAR/STM32F10xFWLib/src/stm32f10x_can.c
Start to re-arrange files to include FreeRTOS+ in main download.
[freertos] / Demo / CORTEX_STM32F103_IAR / STM32F10xFWLib / src / stm32f10x_can.c
1 /******************** (C) COPYRIGHT 2007 STMicroelectronics ********************\r
2 * File Name          : stm32f10x_can.c\r
3 * Author             : MCD Application Team\r
4 * Date First Issued  : 09/29/2006\r
5 * Description        : This file provides all the CAN firmware functions.\r
6 ********************************************************************************\r
7 * History:\r
8 * 04/02/2007: V0.2\r
9 * 02/05/2007: V0.1\r
10 * 09/29/2006: V0.01\r
11 ********************************************************************************\r
12 * THE PRESENT SOFTWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS\r
13 * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.\r
14 * AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,\r
15 * INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE\r
16 * CONTENT OF SUCH SOFTWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING\r
17 * INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.\r
18 *******************************************************************************/\r
19 \r
20 /* Includes ------------------------------------------------------------------*/\r
21 #include "stm32f10x_can.h"\r
22 #include "stm32f10x_rcc.h"\r
23 \r
24 /* Private typedef -----------------------------------------------------------*/\r
25 \r
26 /* Private define ------------------------------------------------------------*/\r
27 /* CAN Master Control Register bits */\r
28 #define CAN_MCR_INRQ     ((u32)0x00000001) /* Initialization request */\r
29 #define CAN_MCR_SLEEP    ((u32)0x00000002) /* Sleep mode request */\r
30 #define CAN_MCR_TXFP     ((u32)0x00000004) /* Transmit FIFO priority */\r
31 #define CAN_MCR_RFLM     ((u32)0x00000008) /* Receive FIFO locked mode */\r
32 #define CAN_MCR_NART     ((u32)0x00000010) /* No automatic retransmission */\r
33 #define CAN_MCR_AWUM     ((u32)0x00000020) /* Automatic wake up mode */\r
34 #define CAN_MCR_ABOM     ((u32)0x00000040) /* Automatic bus-off management */\r
35 #define CAN_MCR_TTCM     ((u32)0x00000080) /* time triggered communication */\r
36 \r
37 /* CAN Master Status Register bits */\r
38 #define CAN_MSR_INAK     ((u32)0x00000001)    /* Initialization acknowledge */\r
39 #define CAN_MSR_WKUI     ((u32)0x00000008)    /* Wake-up interrupt */\r
40 #define CAN_MSR_SLAKI    ((u32)0x00000010)    /* Sleep acknowledge interrupt */\r
41 \r
42 /* CAN Transmit Status Register bits */\r
43 #define CAN_TSR_RQCP0    ((u32)0x00000001)    /* Request completed mailbox0 */\r
44 #define CAN_TSR_TXOK0    ((u32)0x00000002)    /* Transmission OK of mailbox0 */\r
45 #define CAN_TSR_ABRQ0    ((u32)0x00000080)    /* Abort request for mailbox0 */\r
46 #define CAN_TSR_RQCP1    ((u32)0x00000100)    /* Request completed mailbox1 */\r
47 #define CAN_TSR_TXOK1    ((u32)0x00000200)    /* Transmission OK of mailbox1 */\r
48 #define CAN_TSR_ABRQ1    ((u32)0x00008000)    /* Abort request for mailbox1 */\r
49 #define CAN_TSR_RQCP2    ((u32)0x00010000)    /* Request completed mailbox2 */\r
50 #define CAN_TSR_TXOK2    ((u32)0x00020000)    /* Transmission OK of mailbox2 */\r
51 #define CAN_TSR_ABRQ2    ((u32)0x00800000)    /* Abort request for mailbox2 */\r
52 #define CAN_TSR_TME0     ((u32)0x04000000)    /* Transmit mailbox 0 empty */\r
53 #define CAN_TSR_TME1     ((u32)0x08000000)    /* Transmit mailbox 1 empty */\r
54 #define CAN_TSR_TME2     ((u32)0x10000000)    /* Transmit mailbox 2 empty */\r
55 \r
56 /* CAN Receive FIFO 0 Register bits */\r
57 #define CAN_RF0R_FULL0   ((u32)0x00000008)    /* FIFO 0 full */\r
58 #define CAN_RF0R_FOVR0   ((u32)0x00000010)    /* FIFO 0 overrun */\r
59 #define CAN_RF0R_RFOM0   ((u32)0x00000020)    /* Release FIFO 0 output mailbox */\r
60 \r
61 /* CAN Receive FIFO 1 Register bits */\r
62 #define CAN_RF1R_FULL1   ((u32)0x00000008)    /* FIFO 1 full */\r
63 #define CAN_RF1R_FOVR1   ((u32)0x00000010)    /* FIFO 1 overrun */\r
64 #define CAN_RF1R_RFOM1   ((u32)0x00000020)    /* Release FIFO 1 output mailbox */\r
65 \r
66 /* CAN Error Status Register bits */\r
67 #define CAN_ESR_EWGF     ((u32)0x00000001)    /* Error warning flag */\r
68 #define CAN_ESR_EPVF     ((u32)0x00000002)    /* Error passive flag */\r
69 #define CAN_ESR_BOFF     ((u32)0x00000004)    /* Bus-off flag */\r
70 \r
71 /* CAN Mailbox Transmit Request */\r
72 #define CAN_TMIDxR_TXRQ    ((u32)0x00000001) /* Transmit mailbox request */\r
73 \r
74 /* CAN Filter Master Register bits */\r
75 #define CAN_FMR_FINIT ((u32)0x00000001) /* Filter init mode */\r
76 \r
77 \r
78 /* Private macro -------------------------------------------------------------*/\r
79 /* Private variables ---------------------------------------------------------*/\r
80 /* Private function prototypes -----------------------------------------------*/\r
81 static ITStatus CheckITStatus(u32 CAN_Reg, u32 It_Bit);\r
82 \r
83 /* Private functions ---------------------------------------------------------*/\r
84 /*******************************************************************************\r
85 * Function Name  : CAN_DeInit\r
86 * Description    : Deinitializes the CAN peripheral registers to their default\r
87 *                  reset values.\r
88 * Input          : None.\r
89 * Output         : None.\r
90 * Return         : None.\r
91 *******************************************************************************/\r
92 void CAN_DeInit(void)\r
93 {\r
94   /* Enable CAN reset state */\r
95   RCC_APB1PeriphResetCmd(RCC_APB1Periph_CAN, ENABLE);\r
96   /* Release CAN from reset state */\r
97   RCC_APB1PeriphResetCmd(RCC_APB1Periph_CAN, DISABLE);\r
98 }\r
99 \r
100 /*******************************************************************************\r
101 * Function Name  : CAN_Init\r
102 * Description    : Initializes the CAN peripheral according to the specified\r
103 *                  parameters in the CAN_InitStruct.\r
104 * Input          : CAN_InitStruct: pointer to a CAN_InitTypeDef structure that\r
105                    contains the configuration information for the CAN peripheral.\r
106 * Output         : None.\r
107 * Return         : Constant indicates initialization succeed which will be \r
108 *                  CANINITFAILED or CANINITOK.\r
109 *******************************************************************************/\r
110 u8 CAN_Init(CAN_InitTypeDef* CAN_InitStruct)\r
111 {\r
112   u8 InitStatus = 0;\r
113 \r
114   /* Check the parameters */\r
115   assert(IS_FUNCTIONAL_STATE(CAN_InitStruct->CAN_TTCM));\r
116   assert(IS_FUNCTIONAL_STATE(CAN_InitStruct->CAN_ABOM));\r
117   assert(IS_FUNCTIONAL_STATE(CAN_InitStruct->CAN_AWUM));\r
118   assert(IS_FUNCTIONAL_STATE(CAN_InitStruct->CAN_NART));\r
119   assert(IS_FUNCTIONAL_STATE(CAN_InitStruct->CAN_RFLM));\r
120   assert(IS_FUNCTIONAL_STATE(CAN_InitStruct->CAN_TXFP));\r
121   assert(IS_CAN_MODE(CAN_InitStruct->CAN_Mode));\r
122   assert(IS_CAN_SJW(CAN_InitStruct->CAN_SJW));\r
123   assert(IS_CAN_BS1(CAN_InitStruct->CAN_BS1));\r
124   assert(IS_CAN_BS2(CAN_InitStruct->CAN_BS2));\r
125   assert(IS_CAN_CLOCK(CAN_InitStruct->CAN_Clock));\r
126   assert(IS_CAN_PRESCALER(CAN_InitStruct->CAN_Prescaler));\r
127 \r
128   /* Request initialisation */\r
129   CAN->MCR = CAN_MCR_INRQ;\r
130 \r
131   /* ...and check acknowledged */\r
132   if ((CAN->MSR & CAN_MSR_INAK) == 0)\r
133   {\r
134     InitStatus = CANINITFAILED;\r
135   }\r
136   else\r
137   {\r
138     /* Set the time triggered communication mode */\r
139     if (CAN_InitStruct->CAN_TTCM == ENABLE)\r
140     {\r
141       CAN->MCR |= CAN_MCR_TTCM;\r
142     }\r
143     else\r
144     {\r
145       CAN->MCR &= ~CAN_MCR_TTCM;\r
146     }\r
147 \r
148     /* Set the automatic bus-off management */\r
149     if (CAN_InitStruct->CAN_ABOM == ENABLE)\r
150     {\r
151       CAN->MCR |= CAN_MCR_ABOM;\r
152     }\r
153     else\r
154     {\r
155       CAN->MCR &= ~CAN_MCR_ABOM;\r
156     }\r
157 \r
158     /* Set the automatic wake-up mode */\r
159     if (CAN_InitStruct->CAN_AWUM == ENABLE)\r
160     {\r
161       CAN->MCR |= CAN_MCR_AWUM;\r
162     }\r
163     else\r
164     {\r
165       CAN->MCR &= ~CAN_MCR_AWUM;\r
166     }\r
167 \r
168     /* Set the no automatic retransmission */\r
169     if (CAN_InitStruct->CAN_NART == ENABLE)\r
170     {\r
171       CAN->MCR |= CAN_MCR_NART;\r
172     }\r
173     else\r
174     {\r
175       CAN->MCR &= ~CAN_MCR_NART;\r
176     }\r
177 \r
178     /* Set the receive FIFO locked mode */\r
179     if (CAN_InitStruct->CAN_RFLM == ENABLE)\r
180     {\r
181       CAN->MCR |= CAN_MCR_RFLM;\r
182     }\r
183     else\r
184     {\r
185       CAN->MCR &= ~CAN_MCR_RFLM;\r
186     }\r
187 \r
188     /* Set the transmit FIFO priority */\r
189     if (CAN_InitStruct->CAN_TXFP == ENABLE)\r
190     {\r
191       CAN->MCR |= CAN_MCR_TXFP;\r
192     }\r
193     else\r
194     {\r
195       CAN->MCR &= ~CAN_MCR_TXFP;\r
196     }\r
197 \r
198     /* Set the bit timing register */\r
199     CAN->BTR = (u32)((u32)CAN_InitStruct->CAN_Mode << 30) | ((u32)CAN_InitStruct->CAN_SJW << 24) |\r
200                ((u32)CAN_InitStruct->CAN_BS1 << 16) | ((u32)CAN_InitStruct->CAN_BS2 << 20) |\r
201                ((u32)CAN_InitStruct->CAN_Clock << 15) | ((u32)CAN_InitStruct->CAN_Prescaler - 1);\r
202 \r
203     InitStatus = CANINITOK;\r
204 \r
205     /* Request leave initialisation */\r
206     CAN->MCR &= ~CAN_MCR_INRQ;\r
207 \r
208     /* ...and check acknowledged */\r
209     if ((CAN->MSR & CAN_MSR_INAK) != CAN_MSR_INAK)\r
210     {\r
211       InitStatus = CANINITFAILED;\r
212     }\r
213   }\r
214 \r
215   /* At this step, return the status of initialization */\r
216   return InitStatus;\r
217 }\r
218 \r
219 /*******************************************************************************\r
220 * Function Name  : CAN_FilterInit\r
221 * Description    : Initializes the CAN peripheral according to the specified\r
222 *                  parameters in the CAN_FilterInitStruct.\r
223 * Input          : CAN_FilterInitStruct: pointer to a CAN_FilterInitTypeDef\r
224 *                  structure that contains the configuration information.\r
225 * Output         : None.\r
226 * Return         : None.\r
227 *******************************************************************************/\r
228 void CAN_FilterInit(CAN_FilterInitTypeDef* CAN_FilterInitStruct)\r
229 {\r
230   u16 FilterNumber_BitPos = 0;\r
231 \r
232   /* Check the parameters */\r
233   assert(IS_CAN_FILTER_NUMBER(CAN_FilterInitStruct->CAN_FilterNumber));\r
234   assert(IS_CAN_FILTER_MODE(CAN_FilterInitStruct->CAN_FilterMode));\r
235   assert(IS_CAN_FILTER_SCALE(CAN_FilterInitStruct->CAN_FilterScale));\r
236   assert(IS_CAN_FILTER_FIFO(CAN_FilterInitStruct->CAN_FilterFIFOAssignment));\r
237   assert(IS_FUNCTIONAL_STATE(CAN_FilterInitStruct->CAN_FilterActivation));\r
238 \r
239   FilterNumber_BitPos = (u16)((u16)0x0001 << ((u16)CAN_FilterInitStruct->CAN_FilterNumber));\r
240 \r
241   /* Initialisation mode for the filter */\r
242   CAN->FMR |= CAN_FMR_FINIT;\r
243 \r
244   /* Filter Deactivation */\r
245   CAN->FA0R &= ~(u32)FilterNumber_BitPos;\r
246 \r
247   /* Filter Scale */\r
248   if (CAN_FilterInitStruct->CAN_FilterScale == CAN_FilterScale_16bit)\r
249   {\r
250     /* 16-bit scale for the filter */\r
251     CAN->FS0R &= ~(u32)FilterNumber_BitPos;\r
252 \r
253     /* First 16-bit identifier and First 16-bit mask */\r
254     /* Or First 16-bit identifier and Second 16-bit identifier */\r
255     CAN->sFilterRegister[CAN_FilterInitStruct->CAN_FilterNumber].FR0 = ((u32)((u32)0x0000FFFF & CAN_FilterInitStruct->CAN_FilterMaskIdLow) << 16) |\r
256         ((u32)0x0000FFFF & CAN_FilterInitStruct->CAN_FilterIdLow);\r
257 \r
258     /* Second 16-bit identifier and Second 16-bit mask */\r
259     /* Or Third 16-bit identifier and Fourth 16-bit identifier */\r
260     CAN->sFilterRegister[CAN_FilterInitStruct->CAN_FilterNumber].FR1 = ((u32)((u32)0x0000FFFF & CAN_FilterInitStruct->CAN_FilterMaskIdHigh) << 16) |\r
261         ((u32)0x0000FFFF & CAN_FilterInitStruct->CAN_FilterIdHigh);\r
262   }\r
263   if (CAN_FilterInitStruct->CAN_FilterScale == CAN_FilterScale_32bit)\r
264   {\r
265     /* 32-bit scale for the filter */\r
266     CAN->FS0R |= FilterNumber_BitPos;\r
267 \r
268     /* 32-bit identifier or First 32-bit identifier */\r
269     CAN->sFilterRegister[CAN_FilterInitStruct->CAN_FilterNumber].FR0 = ((u32)((u32)0x0000FFFF & CAN_FilterInitStruct->CAN_FilterIdHigh) << 16) |\r
270         ((u32)0x0000FFFF & CAN_FilterInitStruct->CAN_FilterIdLow);\r
271 \r
272     /* 32-bit mask or Second 32-bit identifier */\r
273     CAN->sFilterRegister[CAN_FilterInitStruct->CAN_FilterNumber].FR1 = ((u32)((u32)0x0000FFFF & CAN_FilterInitStruct->CAN_FilterMaskIdHigh) << 16) |\r
274         ((u32)0x0000FFFF & CAN_FilterInitStruct->CAN_FilterMaskIdLow);\r
275 \r
276   }\r
277 \r
278   /* Filter Mode */\r
279   if (CAN_FilterInitStruct->CAN_FilterMode == CAN_FilterMode_IdMask)\r
280   {\r
281     /*Id/Mask mode for the filter*/\r
282     CAN->FM0R &= ~(u32)FilterNumber_BitPos;\r
283   }\r
284   else /* CAN_FilterInitStruct->CAN_FilterMode == CAN_FilterMode_IdList */\r
285   {\r
286     /*Identifier list mode for the filter*/\r
287     CAN->FM0R |= (u32)FilterNumber_BitPos;\r
288   }\r
289 \r
290   /* Filter FIFO assignment */\r
291   if (CAN_FilterInitStruct->CAN_FilterFIFOAssignment == CAN_FilterFIFO0)\r
292   {\r
293     /* FIFO 0 assignation for the filter */\r
294     CAN->FFA0R &= ~(u32)FilterNumber_BitPos;\r
295   }\r
296   if (CAN_FilterInitStruct->CAN_FilterFIFOAssignment == CAN_FilterFIFO1)\r
297   {\r
298     /* FIFO 1 assignation for the filter */\r
299     CAN->FFA0R |= (u32)FilterNumber_BitPos;\r
300   }\r
301   \r
302   /* Filter activation */\r
303   if (CAN_FilterInitStruct->CAN_FilterActivation == ENABLE)\r
304   {\r
305     CAN->FA0R |= FilterNumber_BitPos;\r
306   }\r
307 \r
308   /* Leave the initialisation mode for the filter */\r
309   CAN->FMR &= ~CAN_FMR_FINIT;\r
310 }\r
311 \r
312 /*******************************************************************************\r
313 * Function Name  : CAN_StructInit\r
314 * Description    : Fills each CAN_InitStruct member with its default value.\r
315 * Input          : CAN_InitStruct: pointer to a CAN_InitTypeDef structure which\r
316 *                  will be initialized.\r
317 * Output         : None.\r
318 * Return         : None.\r
319 *******************************************************************************/\r
320 void CAN_StructInit(CAN_InitTypeDef* CAN_InitStruct)\r
321 {\r
322   /* Reset CAN init structure parameters values */\r
323 \r
324   /* Initialize the time triggered communication mode */\r
325   CAN_InitStruct->CAN_TTCM = DISABLE;\r
326 \r
327   /* Initialize the automatic bus-off management */\r
328   CAN_InitStruct->CAN_ABOM = DISABLE;\r
329 \r
330   /* Initialize the automatic wake-up mode */\r
331   CAN_InitStruct->CAN_AWUM = DISABLE;\r
332 \r
333   /* Initialize the no automatic retransmission */\r
334   CAN_InitStruct->CAN_NART = DISABLE;\r
335 \r
336   /* Initialize the receive FIFO locked mode */\r
337   CAN_InitStruct->CAN_RFLM = DISABLE;\r
338 \r
339   /* Initialize the transmit FIFO priority */\r
340   CAN_InitStruct->CAN_TXFP = DISABLE;\r
341 \r
342   /* Initialize the CAN_Mode member */\r
343   CAN_InitStruct->CAN_Mode = CAN_Mode_Normal;\r
344 \r
345   /* Initialize the CAN_SJW member */\r
346   CAN_InitStruct->CAN_SJW = CAN_SJW_0tq;\r
347 \r
348   /* Initialize the CAN_BS1 member */\r
349   CAN_InitStruct->CAN_BS1 = CAN_BS1_4tq;\r
350 \r
351   /* Initialize the CAN_BS2 member */\r
352   CAN_InitStruct->CAN_BS2 = CAN_BS2_3tq;\r
353 \r
354   /* Initialize the CAN_Clock member */\r
355   CAN_InitStruct->CAN_Clock = CAN_Clock_APB;\r
356 \r
357   /* Initialize the CAN_Prescaler member */\r
358   CAN_InitStruct->CAN_Prescaler = 1;\r
359 }\r
360 \r
361 /*******************************************************************************\r
362 * Function Name  : CAN_ITConfig\r
363 * Description    : Enables or disables the CAN interrupts.\r
364 * Input          : - CAN_IT: specifies the CAN interrupt sources to be enabled or\r
365 *                    disabled.\r
366 *                  - NewState: new state of the CAN interrupts.\r
367 *                    This parameter can be: ENABLE or DISABLE.\r
368 * Output         : None.\r
369 * Return         : None.\r
370 *******************************************************************************/\r
371 void CAN_ITConfig(u32 CAN_IT, FunctionalState NewState)\r
372 {\r
373   /* Check the parameters */\r
374   assert(IS_CAN_IT(CAN_IT));\r
375   assert(IS_FUNCTIONAL_STATE(NewState));\r
376 \r
377   if (NewState != DISABLE)\r
378   {\r
379     /* Enable the selected CAN interrupt */\r
380     CAN->IER |= CAN_IT;\r
381   }\r
382   else\r
383   {\r
384     /* Disable the selected CAN interrupt */\r
385     CAN->IER &= ~CAN_IT;\r
386   }\r
387 }\r
388 \r
389 /*******************************************************************************\r
390 * Function Name  : CAN_Transmit\r
391 * Description    : Initiates the transmission of a message.\r
392 * Input          : TxMessage: pointer to a structure which contains CAN Id, CAN\r
393 *                  DLC and CAN datas.\r
394 * Output         : None.\r
395 * Return         : The number of the mailbox that is used for transmission\r
396 *                  or CAN_NO_MB if there is no empty mailbox.\r
397 *******************************************************************************/\r
398 u8 CAN_Transmit(CanTxMsg* TxMessage)\r
399 {\r
400   u8 TransmitMailbox = 0;\r
401 \r
402   /* Check the parameters */\r
403   assert(IS_CAN_STDID(TxMessage->StdId));\r
404   assert(IS_CAN_EXTID(TxMessage->StdId));\r
405   assert(IS_CAN_IDTYPE(TxMessage->IDE));\r
406   assert(IS_CAN_RTR(TxMessage->RTR));\r
407   assert(IS_CAN_DLC(TxMessage->DLC));\r
408 \r
409   /* Select one empty transmit mailbox */\r
410   if ((CAN->TSR&CAN_TSR_TME0) == CAN_TSR_TME0)\r
411   {\r
412     TransmitMailbox = 0;\r
413   }\r
414   else if ((CAN->TSR&CAN_TSR_TME1) == CAN_TSR_TME1)\r
415   {\r
416     TransmitMailbox = 1;\r
417   }\r
418   else if ((CAN->TSR&CAN_TSR_TME2) == CAN_TSR_TME2)\r
419   {\r
420     TransmitMailbox = 2;\r
421   }\r
422   else\r
423   {\r
424     TransmitMailbox = CAN_NO_MB;\r
425   }\r
426 \r
427   if (TransmitMailbox != CAN_NO_MB)\r
428   {\r
429     /* Set up the Id */\r
430     TxMessage->StdId &= (u32)0x000007FF;\r
431     TxMessage->StdId = TxMessage->StdId << 21;\r
432     TxMessage->ExtId &= (u32)0x0003FFFF;\r
433     TxMessage->ExtId <<= 3;\r
434 \r
435     CAN->sTxMailBox[TransmitMailbox].TIR &= CAN_TMIDxR_TXRQ;\r
436     CAN->sTxMailBox[TransmitMailbox].TIR |= (TxMessage->StdId | TxMessage->ExtId |\r
437                                             TxMessage->IDE | TxMessage->RTR);\r
438 \r
439     /* Set up the DLC */\r
440     TxMessage->DLC &= (u8)0x0000000F;\r
441     CAN->sTxMailBox[TransmitMailbox].TDTR &= (u32)0xFFFFFFF0;\r
442     CAN->sTxMailBox[TransmitMailbox].TDTR |= TxMessage->DLC;\r
443 \r
444     /* Set up the data field */\r
445     CAN->sTxMailBox[TransmitMailbox].TDLR = (((u32)TxMessage->Data[3] << 24) | ((u32)TxMessage->Data[2] << 16) |\r
446                                             ((u32)TxMessage->Data[1] << 8) | ((u32)TxMessage->Data[0]));\r
447     CAN->sTxMailBox[TransmitMailbox].TDHR = (((u32)TxMessage->Data[7] << 24) | ((u32)TxMessage->Data[6] << 16) |\r
448                                             ((u32)TxMessage->Data[5] << 8) | ((u32)TxMessage->Data[4]));\r
449 \r
450     /* Request transmission */\r
451     CAN->sTxMailBox[TransmitMailbox].TIR |= CAN_TMIDxR_TXRQ;\r
452   }\r
453 \r
454   return TransmitMailbox;\r
455 }\r
456 \r
457 /*******************************************************************************\r
458 * Function Name  : CAN_TransmitStatus\r
459 * Description    : Check the transmission of a message.\r
460 * Input          : TransmitMailbox: the number of the mailbox that is used for\r
461 *                  transmission.\r
462 * Output         : None.\r
463 * Return         : CANTXOK if the CAN driver transmits the message, CANTXFAILED\r
464 *                  in an other case.\r
465 *******************************************************************************/\r
466 u32 CAN_TransmitStatus(u8 TransmitMailbox)\r
467 {\r
468   /* RQCP, TXOK and TME bits */\r
469   u32 State = 0;\r
470 \r
471   /* Check the parameters */\r
472   assert(IS_CAN_TRANSMITMAILBOX(TransmitMailbox));\r
473 \r
474   switch (TransmitMailbox)\r
475   {\r
476     case (0): State |= ((CAN->TSR & CAN_TSR_RQCP0) << 2);\r
477       State |= ((CAN->TSR & CAN_TSR_TXOK0) >> 0);\r
478       State |= ((CAN->TSR & CAN_TSR_TME0) >> 26);\r
479       break;\r
480     case (1): State |= ((CAN->TSR & CAN_TSR_RQCP1) >> 6);\r
481       State |= ((CAN->TSR & CAN_TSR_TXOK1) >> 8);\r
482       State |= ((CAN->TSR & CAN_TSR_TME1) >> 27);\r
483       break;\r
484     case (2): State |= ((CAN->TSR & CAN_TSR_RQCP2) >> 14);\r
485       State |= ((CAN->TSR & CAN_TSR_TXOK2) >> 16);\r
486       State |= ((CAN->TSR & CAN_TSR_TME2) >> 28);\r
487       break;\r
488     default:\r
489       State = CANTXFAILED;\r
490       break;\r
491   }\r
492 \r
493   switch (State)\r
494   {\r
495       /* transmit pending  */\r
496     case (0x0): State = CANTXPENDING;\r
497       break;\r
498       /* transmit failed  */\r
499     case (0x5): State = CANTXFAILED;\r
500       break;\r
501       /* transmit succedeed  */\r
502     case (0x7): State = CANTXOK;\r
503       break;\r
504     default:\r
505       State = CANTXFAILED;\r
506       break;\r
507   }\r
508 \r
509   return State;\r
510 }\r
511 \r
512 /*******************************************************************************\r
513 * Function Name  : CAN_CancelTransmit\r
514 * Description    : Cancels a transmit request.\r
515 * Input          : Mailbox number.\r
516 * Output         : None.\r
517 * Return         : None.\r
518 *******************************************************************************/\r
519 void CAN_CancelTransmit(u8 Mailbox)\r
520 {\r
521   /* Check the parameters */\r
522   assert(IS_CAN_TRANSMITMAILBOX(Mailbox));\r
523 \r
524   /* abort transmission */\r
525   switch (Mailbox)\r
526   {\r
527     case (0): CAN->TSR |= CAN_TSR_ABRQ0;\r
528       break;\r
529     case (1): CAN->TSR |= CAN_TSR_ABRQ1;\r
530       break;\r
531     case (2): CAN->TSR |= CAN_TSR_ABRQ2;\r
532       break;\r
533     default:\r
534       break;\r
535   }\r
536 }\r
537 \r
538 /*******************************************************************************\r
539 * Function Name  : CAN_FIFORelease\r
540 * Description    : Release a FIFO.\r
541 * Input          : FIFONumber: FIFO to release, CAN_FIFO0 or CAN_FIFO1.\r
542 * Output         : None.\r
543 * Return         : None.\r
544 *******************************************************************************/\r
545 void CAN_FIFORelease(u8 FIFONumber)\r
546 {\r
547   /* Check the parameters */\r
548   assert(IS_CAN_FIFO(FIFONumber));\r
549 \r
550   /* Release FIFO0 */\r
551   if (FIFONumber == CAN_FIFO0)\r
552   {\r
553     CAN->RF0R = CAN_RF0R_RFOM0;\r
554   }\r
555   /* Release FIFO1 */\r
556   else /* FIFONumber == CAN_FIFO1 */\r
557   {\r
558     CAN->RF1R = CAN_RF1R_RFOM1;\r
559   }\r
560 }\r
561 \r
562 /*******************************************************************************\r
563 * Function Name  : CAN_MessagePending\r
564 * Description    : Return the number of pending messages.\r
565 * Input          : FIFONumber: Receive FIFO number, CAN_FIFO0 or CAN_FIFO1.\r
566 * Output         : None.\r
567 * Return         : NbMessage which is the number of pending message.\r
568 *******************************************************************************/\r
569 u8 CAN_MessagePending(u8 FIFONumber)\r
570 {\r
571   u8 MessagePending=0;\r
572 \r
573   /* Check the parameters */\r
574   assert(IS_CAN_FIFO(FIFONumber));\r
575 \r
576   if (FIFONumber == CAN_FIFO0)\r
577   {\r
578     MessagePending = (u8)(CAN->RF0R&(u32)0x03);\r
579   }\r
580   else if (FIFONumber == CAN_FIFO1)\r
581   {\r
582     MessagePending = (u8)(CAN->RF1R&(u32)0x03);\r
583   }\r
584   else\r
585   {\r
586     MessagePending = 0;\r
587   }\r
588   return MessagePending;\r
589 }\r
590 \r
591 /*******************************************************************************\r
592 * Function Name  : CAN_Receive\r
593 * Description    : Receives a message.\r
594 * Input          : FIFONumber: Receive FIFO number, CAN_FIFO0 or CAN_FIFO1.\r
595 * Output         : RxMessage: pointer to a structure which contains CAN Id,\r
596 *                  CAN DLC, CAN datas and FMI number.\r
597 * Return         : None.\r
598 *******************************************************************************/\r
599 void CAN_Receive(u8 FIFONumber, CanRxMsg* RxMessage)\r
600 {\r
601   /* Check the parameters */\r
602   assert(IS_CAN_FIFO(FIFONumber));\r
603 \r
604   /* Get the Id */\r
605   RxMessage->StdId = (u32)0x000007FF & (CAN->sFIFOMailBox[FIFONumber].RIR >> 21);\r
606   RxMessage->ExtId = (u32)0x0003FFFF & (CAN->sFIFOMailBox[FIFONumber].RIR >> 3);\r
607 \r
608   RxMessage->IDE = (u32)0x00000004 & CAN->sFIFOMailBox[FIFONumber].RIR;\r
609   RxMessage->RTR = (u32)0x00000002 & CAN->sFIFOMailBox[FIFONumber].RIR;\r
610 \r
611   /* Get the DLC */\r
612   RxMessage->DLC = (u32)0x0000000F & CAN->sFIFOMailBox[FIFONumber].RDTR;\r
613 \r
614   /* Get the FMI */\r
615   RxMessage->FMI = (u32)0x000000FF & (CAN->sFIFOMailBox[FIFONumber].RDTR >> 8);\r
616 \r
617   /* Get the data field */\r
618   RxMessage->Data[0] = (u32)0x000000FF & CAN->sFIFOMailBox[FIFONumber].RDLR;\r
619   RxMessage->Data[1] = (u32)0x000000FF & (CAN->sFIFOMailBox[FIFONumber].RDLR >> 8);\r
620   RxMessage->Data[2] = (u32)0x000000FF & (CAN->sFIFOMailBox[FIFONumber].RDLR >> 16);\r
621   RxMessage->Data[3] = (u32)0x000000FF & (CAN->sFIFOMailBox[FIFONumber].RDLR >> 24);\r
622 \r
623   RxMessage->Data[4] = (u32)0x000000FF & CAN->sFIFOMailBox[FIFONumber].RDHR;\r
624   RxMessage->Data[5] = (u32)0x000000FF & (CAN->sFIFOMailBox[FIFONumber].RDHR >> 8);\r
625   RxMessage->Data[6] = (u32)0x000000FF & (CAN->sFIFOMailBox[FIFONumber].RDHR >> 16);\r
626   RxMessage->Data[7] = (u32)0x000000FF & (CAN->sFIFOMailBox[FIFONumber].RDHR >> 24);\r
627 \r
628   /* Release the FIFO */\r
629   CAN_FIFORelease(FIFONumber);\r
630 }\r
631 \r
632 /*******************************************************************************\r
633 * Function Name  : CAN_Sleep\r
634 * Description    : Enters the low power mode.\r
635 * Input          : None.\r
636 * Output         : None.\r
637 * Return         : CANSLEEPOK if sleep entered, CANSLEEPFAILED in an other case.\r
638 *******************************************************************************/\r
639 u8 CAN_Sleep(void)\r
640 {\r
641   u8 SleepStatus = 0;\r
642 \r
643   /* Sleep mode entering request */\r
644   CAN->MCR |= CAN_MCR_SLEEP;\r
645   SleepStatus = CANSLEEPOK;\r
646 \r
647   /* Sleep mode status */\r
648   if ((CAN->MCR&CAN_MCR_SLEEP) == 0)\r
649   {\r
650     /* Sleep mode not entered */\r
651     SleepStatus = CANSLEEPFAILED;\r
652   }\r
653 \r
654   /* At this step, sleep mode status */\r
655   return SleepStatus;\r
656 }\r
657 \r
658 /*******************************************************************************\r
659 * Function Name  : CAN_WakeUp\r
660 * Description    : Wakes the CAN up.\r
661 * Input          : None.\r
662 * Output         : None.\r
663 * Return         : CANWAKEUPOK if sleep mode left, CANWAKEUPFAILED in an other\r
664 *                  case.\r
665 *******************************************************************************/\r
666 u8 CAN_WakeUp(void)\r
667 {\r
668   u8 WakeUpStatus = 0;\r
669 \r
670   /* Wake up request */\r
671   CAN->MCR &= ~CAN_MCR_SLEEP;\r
672   WakeUpStatus = CANWAKEUPFAILED;\r
673 \r
674   /* Sleep mode status */\r
675   if ((CAN->MCR&CAN_MCR_SLEEP) == 0)\r
676   {\r
677     /* Sleep mode exited */\r
678     WakeUpStatus = CANWAKEUPOK;\r
679   }\r
680 \r
681   /* At this step, sleep mode status */\r
682   return WakeUpStatus;\r
683 }\r
684 \r
685 /*******************************************************************************\r
686 * Function Name  : CAN_GetFlagStatus\r
687 * Description    : Checks whether the CAN flag is set or not.\r
688 * Input          : CAN_FLAG: specifies the flag to check.\r
689 * Output         : None.\r
690 * Return         : The new state of CAN_FLAG (SET or RESET).\r
691 *******************************************************************************/\r
692 FlagStatus CAN_GetFlagStatus(u32 CAN_FLAG)\r
693 {\r
694   FlagStatus bitstatus = RESET;\r
695 \r
696   /* Check the parameters */\r
697   assert(IS_CAN_FLAG(CAN_FLAG));\r
698 \r
699   /* Check the status of the specified CAN flag */\r
700   if ((CAN->ESR & CAN_FLAG) != (u32)RESET)\r
701   {\r
702     /* CAN_FLAG is set */\r
703     bitstatus = SET;\r
704   }\r
705   else\r
706   {\r
707     /* CAN_FLAG is reset */\r
708     bitstatus = RESET;\r
709   }\r
710   /* Return the CAN_FLAG status */\r
711   return  bitstatus;\r
712 }\r
713 \r
714 /*******************************************************************************\r
715 * Function Name  : CAN_ClearFlag\r
716 * Description    : Clears the CAN's pending flags.\r
717 * Input          : CAN_FLAG: specifies the flag to clear.\r
718 * Output         : None.\r
719 * Return         : None.\r
720 *******************************************************************************/\r
721 void CAN_ClearFlag(u32 CAN_FLAG)\r
722 {\r
723   /* Check the parameters */\r
724   assert(IS_CAN_FLAG(CAN_FLAG));\r
725 \r
726   /* Clear the selected CAN flags */\r
727   CAN->ESR &= ~CAN_FLAG;\r
728 }\r
729 \r
730 /*******************************************************************************\r
731 * Function Name  : CAN_GetITStatus\r
732 * Description    : Checks whether the CAN interrupt has occurred or not.\r
733 * Input          : CAN_IT: specifies the CAN interrupt source to check.\r
734 * Output         : None.\r
735 * Return         : The new state of CAN_IT (SET or RESET).\r
736 *******************************************************************************/\r
737 ITStatus CAN_GetITStatus(u32 CAN_IT)\r
738 {\r
739   ITStatus pendingbitstatus = RESET;\r
740 \r
741   /* Check the parameters */\r
742   assert(IS_CAN_IT(CAN_IT));\r
743 \r
744   switch (CAN_IT)\r
745   {\r
746     case CAN_IT_RQCP0:\r
747       pendingbitstatus = CheckITStatus(CAN->TSR, CAN_TSR_RQCP0);\r
748       break;\r
749     case CAN_IT_RQCP1:\r
750       pendingbitstatus = CheckITStatus(CAN->TSR, CAN_TSR_RQCP1);\r
751       break;\r
752     case CAN_IT_RQCP2:\r
753       pendingbitstatus = CheckITStatus(CAN->TSR, CAN_TSR_RQCP2);\r
754       break;\r
755     case CAN_IT_FF0:\r
756       pendingbitstatus = CheckITStatus(CAN->RF0R, CAN_RF0R_FULL0);\r
757       break;\r
758     case CAN_IT_FOV0:\r
759       pendingbitstatus = CheckITStatus(CAN->RF0R, CAN_RF0R_FOVR0);\r
760       break;\r
761     case CAN_IT_FF1:\r
762       pendingbitstatus = CheckITStatus(CAN->RF1R, CAN_RF1R_FULL1);\r
763       break;\r
764     case CAN_IT_FOV1:\r
765       pendingbitstatus = CheckITStatus(CAN->RF1R, CAN_RF1R_FOVR1);\r
766       break;\r
767     case CAN_IT_EWG:\r
768       pendingbitstatus = CheckITStatus(CAN->ESR, CAN_ESR_EWGF);\r
769       break;\r
770     case CAN_IT_EPV:\r
771       pendingbitstatus = CheckITStatus(CAN->ESR, CAN_ESR_EPVF);\r
772       break;\r
773     case CAN_IT_BOF:\r
774       pendingbitstatus = CheckITStatus(CAN->ESR, CAN_ESR_BOFF);\r
775       break;\r
776     case CAN_IT_SLK:\r
777       pendingbitstatus = CheckITStatus(CAN->MSR, CAN_MSR_SLAKI);\r
778       break;\r
779     case CAN_IT_WKU:\r
780       pendingbitstatus = CheckITStatus(CAN->MSR, CAN_MSR_WKUI);\r
781       break;\r
782 \r
783     default :\r
784       pendingbitstatus = RESET;\r
785       break;\r
786   }\r
787 \r
788   /* Return the CAN_IT status */\r
789   return  pendingbitstatus;\r
790 }\r
791 \r
792 /*******************************************************************************\r
793 * Function Name  : CAN_ClearITPendingBit\r
794 * Description    : Clears the CAN\92s interrupt pending bits.\r
795 * Input          : CAN_IT: specifies the interrupt pending bit to clear.\r
796 * Output         : None.\r
797 * Return         : None.\r
798 *******************************************************************************/\r
799 void CAN_ClearITPendingBit(u32 CAN_IT)\r
800 {\r
801   /* Check the parameters */\r
802   assert(IS_CAN_IT(CAN_IT));\r
803 \r
804   switch (CAN_IT)\r
805   {\r
806     case CAN_IT_RQCP0:\r
807       CAN->TSR = CAN_TSR_RQCP0; /* rc_w1*/\r
808       break;\r
809     case CAN_IT_RQCP1:\r
810       CAN->TSR = CAN_TSR_RQCP1; /* rc_w1*/\r
811       break;\r
812     case CAN_IT_RQCP2:\r
813       CAN->TSR = CAN_TSR_RQCP2; /* rc_w1*/\r
814       break;\r
815     case CAN_IT_FF0:\r
816       CAN->RF0R = CAN_RF0R_FULL0; /* rc_w1*/\r
817       break;\r
818     case CAN_IT_FOV0:\r
819       CAN->RF0R = CAN_RF0R_FOVR0; /* rc_w1*/\r
820       break;\r
821     case CAN_IT_FF1:\r
822       CAN->RF1R = CAN_RF1R_FULL1; /* rc_w1*/\r
823       break;\r
824     case CAN_IT_FOV1:\r
825       CAN->RF1R = CAN_RF1R_FOVR1; /* rc_w1*/\r
826       break;\r
827     case CAN_IT_EWG:\r
828       CAN->ESR &= ~ CAN_ESR_EWGF; /* rw */\r
829       break;\r
830     case CAN_IT_EPV:\r
831       CAN->ESR &= ~ CAN_ESR_EPVF; /* rw */\r
832       break;\r
833     case CAN_IT_BOF:\r
834       CAN->ESR &= ~ CAN_ESR_BOFF; /* rw */\r
835       break;\r
836     case CAN_IT_WKU:\r
837       CAN->MSR = CAN_MSR_WKUI;  /* rc_w1*/\r
838       break;\r
839     case CAN_IT_SLK:\r
840       CAN->MSR = CAN_MSR_SLAKI;  /* rc_w1*/\r
841       break;\r
842     default :\r
843       break;\r
844   }\r
845 }\r
846 \r
847 /*******************************************************************************\r
848 * Function Name  : CheckITStatus\r
849 * Description    : Checks whether the CAN interrupt has occurred or not.\r
850 * Input          : CAN_Reg: specifies the CAN interrupt register to check.\r
851 *                  It_Bit: specifies the interrupt source bit to check.\r
852 * Output         : None.\r
853 * Return         : The new state of the CAN Interrupt (SET or RESET).\r
854 *******************************************************************************/\r
855 static ITStatus CheckITStatus(u32 CAN_Reg, u32 It_Bit)\r
856 {\r
857   ITStatus pendingbitstatus = RESET;\r
858 \r
859   if ((CAN_Reg & It_Bit) != (u32)RESET)\r
860   {\r
861     /* CAN_IT is set */\r
862     pendingbitstatus = SET;\r
863   }\r
864   else\r
865   {\r
866     /* CAN_IT is reset */\r
867     pendingbitstatus = RESET;\r
868   }\r
869 \r
870   return pendingbitstatus;\r
871 }\r
872 \r
873 /******************* (C) COPYRIGHT 2007 STMicroelectronics *****END OF FILE****/\r