]> git.sur5r.net Git - freertos/blob - Demo/ARM7_STR75x_GCC/STLibrary/src/75x_can.c
Start to re-arrange files to include FreeRTOS+ in main download.
[freertos] / Demo / ARM7_STR75x_GCC / STLibrary / src / 75x_can.c
1 /******************** (C) COPYRIGHT 2006 STMicroelectronics ********************\r
2 * File Name          : 75x_can.c\r
3 * Author             : MCD Application Team\r
4 * Date First Issued  : 03/10/2006\r
5 * Description        : This file provides all the CAN software functions.\r
6 ********************************************************************************\r
7 * History:\r
8 * 07/17/2006 : V1.0\r
9 * 03/10/2006 : V0.1\r
10 ********************************************************************************\r
11 * THE PRESENT SOFTWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS\r
12 * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.\r
13 * AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,\r
14 * INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE\r
15 * CONTENT OF SUCH SOFTWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING\r
16 * INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.\r
17 *******************************************************************************/\r
18 \r
19 /* Includes ------------------------------------------------------------------*/\r
20 #include "75x_can.h"\r
21 #include "75x_mrcc.h"\r
22 \r
23 /* Private typedef -----------------------------------------------------------*/\r
24 /* Private define ------------------------------------------------------------*/\r
25 /* Private macro -------------------------------------------------------------*/\r
26 /*----------------------------------------------------------------------------*/\r
27 /* Macro Name     : xxx_ID_MSK, xxx_ID_ARB                                    */\r
28 /* Description    : Form the Mask and Arbitration registers value to filter   */\r
29 /*                  a range of identifiers or a fixed identifier, for standard*/\r
30 /*                  and extended IDs                                          */\r
31 /*----------------------------------------------------------------------------*/\r
32 #define RANGE_ID_MSK(range_start, range_end)    (~((range_end) - (range_start)))\r
33 #define RANGE_ID_ARB(range_start, range_end)    ((range_start) & (range_end))\r
34 \r
35 #define FIXED_ID_MSK(id)        RANGE_ID_MSK((id), (id))\r
36 #define FIXED_ID_ARB(id)        RANGE_ID_ARB((id), (id))\r
37 \r
38 #define STD_RANGE_ID_MSK(range_start, range_end)        ((u16)((RANGE_ID_MSK((range_start), (range_end)) & 0x7FF) << 2))\r
39 #define STD_RANGE_ID_ARB(range_start, range_end)        ((u16)(RANGE_ID_ARB((range_start), (range_end)) << 2))\r
40 \r
41 #define STD_FIXED_ID_MSK(id)    ((u16)((FIXED_ID_MSK(id) & 0x7FF) << 2))\r
42 #define STD_FIXED_ID_ARB(id)    ((u16)(FIXED_ID_ARB(id) << 2))\r
43 \r
44 #define EXT_RANGE_ID_MSK_L(range_start, range_end)      ((u16)(RANGE_ID_MSK((range_start), (range_end)) >> 11))\r
45 #define EXT_RANGE_ID_MSK_H(range_start, range_end)      ((u16)(STD_RANGE_ID_MSK((range_start), (range_end)) | ((RANGE_ID_MSK((range_start), (range_end)) >> 27) & 0x03)))\r
46 #define EXT_RANGE_ID_ARB_L(range_start, range_end)      ((u16)(RANGE_ID_ARB((range_start), (range_end)) >> 11))\r
47 #define EXT_RANGE_ID_ARB_H(range_start, range_end)      ((u16)(STD_RANGE_ID_ARB((range_start), (range_end)) | ((RANGE_ID_ARB((range_start), (range_end)) >> 27) & 0x03)))\r
48 \r
49 #define EXT_FIXED_ID_MSK_L(id)  ((u16)(FIXED_ID_MSK(id) >> 11))\r
50 #define EXT_FIXED_ID_MSK_H(id)  ((u16)(STD_FIXED_ID_MSK(id) | ((FIXED_ID_MSK(id) >> 27) & 0x03)))\r
51 #define EXT_FIXED_ID_ARB_L(id)  ((u16)(FIXED_ID_ARB(id) >> 11))\r
52 #define EXT_FIXED_ID_ARB_H(id)  ((u16)(STD_FIXED_ID_ARB(id) | ((FIXED_ID_ARB(id) >> 27) & 0x03)))\r
53 \r
54 /* macro to format the timing register value from the timing parameters*/\r
55 #define CAN_TIMING(tseg1, tseg2, sjw, brp)      ((((tseg2-1) & 0x07) << 12) | (((tseg1-1) & 0x0F) << 8) | (((sjw-1) & 0x03) << 6) | ((brp-1) & 0x3F))\r
56 \r
57 /* Private variables ---------------------------------------------------------*/\r
58 /* array of pre-defined timing parameters for standard bitrates*/\r
59 u16 CanTimings[] = {       /* value   bitrate     NTQ  TSEG1  TSEG2  SJW  BRP */\r
60   CAN_TIMING(11, 4, 4, 5), /* 0x3AC4  100 kbit/s  16   11     4      4    5   */\r
61   CAN_TIMING(11, 4, 4, 4), /* 0x3AC3  125 kbit/s  16   11     4      4    4   */\r
62   CAN_TIMING( 4, 3, 3, 4), /* 0x2383  250 kbit/s   8    4     3      3    4   */\r
63   CAN_TIMING(13, 2, 1, 1), /* 0x1C00  500 kbit/s  16   13     2      1    1   */\r
64   CAN_TIMING( 4, 3, 1, 1), /* 0x2300  1 Mbit/s     8    4     3      1    1   */\r
65 };\r
66 \r
67 /* Private function prototypes -----------------------------------------------*/\r
68 static u32 GetFreeIF(void);\r
69 /* Private functions ---------------------------------------------------------*/\r
70 \r
71 /*******************************************************************************\r
72 * Function Name  : CAN_DeInit                                                \r
73 * Description    : Deinitializes the CAN peripheral registers to their default     \r
74 *                  reset values.                                     \r
75 * Input          : None                                                      \r
76 * Output         : None                                                      \r
77 * Return         : None                                                      \r
78 *******************************************************************************/\r
79 void CAN_DeInit (void)\r
80 {\r
81   /* Reset the CAN registers values*/\r
82   MRCC_PeripheralSWResetConfig(MRCC_Peripheral_CAN,ENABLE);\r
83   MRCC_PeripheralSWResetConfig(MRCC_Peripheral_CAN,DISABLE);\r
84 }\r
85 \r
86 /*******************************************************************************\r
87 * Function Name  : CAN_Init                                                  \r
88 * Description    : Initializes the CAN peripheral according to the specified \r
89 *                  parameters in the CAN_InitStruct.                                            \r
90 * Input          : CAN_InitStruct: pointer to a CAN_InitTypeDef structure that\r
91 *                  contains the configuration information for the CAN peripheral. \r
92 * Output         : None                                                      \r
93 * Return         : None                                                      \r
94 *******************************************************************************/\r
95 void CAN_Init(CAN_InitTypeDef* CAN_InitStruct)\r
96 {\r
97   CAN_EnterInitMode(CAN_CR_CCE | CAN_InitStruct->CAN_ConfigParameters);\r
98   CAN_SetBitrate(CAN_InitStruct->CAN_Bitrate);\r
99   CAN_LeaveInitMode();\r
100   CAN_LeaveTestMode();\r
101 }\r
102 \r
103 /*******************************************************************************\r
104 * Function Name  : CAN_StructInit                                       \r
105 * Description    : Fills each CAN_InitStruct member with its reset value.             \r
106 * Input          : CAN_InitStruct : pointer to a CAN_InitTypeDef structure which       \r
107 *                  will be initialized. \r
108 * Output         : None                  \r
109 * Return         : None.                                                      \r
110 *******************************************************************************/\r
111 void CAN_StructInit(CAN_InitTypeDef* CAN_InitStruct)\r
112 {\r
113 /* Reset CAN init structure parameters values */\r
114   CAN_InitStruct->CAN_ConfigParameters = 0x0;\r
115   CAN_InitStruct->CAN_Bitrate = 0x2301;\r
116 }\r
117 \r
118 /*******************************************************************************\r
119 * Function Name  : CAN_SetBitrate                                            \r
120 * Description    : Setups a standard CAN bitrate.                              \r
121 * Input          : bitrate: specifies the bit rate.                       \r
122 * Output         : None                                                      \r
123 * Return         : None                                                                         \r
124 *******************************************************************************/\r
125 void CAN_SetBitrate(u32 bitrate)\r
126 {\r
127   CAN->BTR = CanTimings[bitrate];  /* write the predefined timing value */\r
128   CAN->BRPR = 0;                     /* clear the Extended Baud Rate Prescaler */\r
129 }\r
130 \r
131 /*******************************************************************************\r
132 * Function Name  : CAN_SetTiming                                             \r
133 * Description    : Setups the CAN timing with specific parameters             \r
134 * Input          : - tseg1: specifies Time Segment before the sample point.\r
135 *                    This parameter must be a number between 1 and 16.       \r
136 *                  - tseg2: Time Segment after the sample point. This parameter \r
137 *                    must be a number between 1 and 8.        \r
138 *                  - sjw: Synchronisation Jump Width. This parameter must be                 \r
139 *                     a number between 1 and 4.\r
140 *                  - brp: Baud Rate Prescaler. This parameter must be a number\r
141 *                    between 1 and 1024.                                         \r
142 * Output         : None                                                      \r
143 * Return         : None                                                                       \r
144 *******************************************************************************/\r
145 void CAN_SetTiming(u32 tseg1, u32 tseg2, u32 sjw, u32 brp)\r
146 {\r
147   CAN->BTR = CAN_TIMING(tseg1, tseg2, sjw, brp);\r
148   CAN->BRPR = ((brp-1) >> 6) & 0x0F;\r
149 }\r
150 \r
151 /*******************************************************************************\r
152 * Function Name  : GetFreeIF                                             \r
153 * Description    : Searchs the first free message interface, starting from 0.  \r
154 * Input          : None                                                      \r
155 * Output         : None                                                      \r
156 * Return         : A free message interface number (0 or 1) if found, else 2 \r
157 *******************************************************************************/\r
158 static u32 GetFreeIF(void)\r
159 {\r
160   if ((CAN->sMsgObj[0].CRR & CAN_CRR_BUSY) == 0)\r
161     return 0;\r
162   else if ((CAN->sMsgObj[1].CRR & CAN_CRR_BUSY) == 0)\r
163     return 1;\r
164   else\r
165    return 2;\r
166 }\r
167 \r
168 /*******************************************************************************\r
169 * Function Name  : CAN_SetUnusedMsgObj                                       \r
170 * Description    : Configures the message object as unused                   \r
171 * Input          : msgobj: specifies the Message object number, from 0 to 31.                      \r
172 * Output         : None                                                      \r
173 * Return         : An ErrorStatus enumuration value:\r
174 *                         - SUCCESS: Interface to treat the message\r
175 *                         - ERROR: No interface found to treat the message\r
176 *******************************************************************************/\r
177 ErrorStatus CAN_SetUnusedMsgObj(u32 msgobj)\r
178 {\r
179   u32 msg_if=0;\r
180 \r
181   if ((msg_if = GetFreeIF()) == 2)\r
182   {\r
183     return ERROR;\r
184   }\r
185 \r
186   CAN->sMsgObj[msg_if].CMR = CAN_CMR_WRRD\r
187                            | CAN_CMR_MASK\r
188                            | CAN_CMR_ARB\r
189                            | CAN_CMR_CONTROL\r
190                            | CAN_CMR_DATAA\r
191                            | CAN_CMR_DATAB;\r
192 \r
193   CAN->sMsgObj[msg_if].M1R = 0;\r
194   CAN->sMsgObj[msg_if].M2R = 0;\r
195 \r
196   CAN->sMsgObj[msg_if].A1R = 0;\r
197   CAN->sMsgObj[msg_if].A2R = 0;\r
198 \r
199   CAN->sMsgObj[msg_if].MCR = 0;\r
200 \r
201   CAN->sMsgObj[msg_if].DA1R = 0;\r
202   CAN->sMsgObj[msg_if].DA2R = 0;\r
203   CAN->sMsgObj[msg_if].DB1R = 0;\r
204   CAN->sMsgObj[msg_if].DB2R = 0;\r
205 \r
206  CAN->sMsgObj[msg_if].CRR = 1 + msgobj;\r
207  \r
208  return SUCCESS;\r
209 }\r
210 \r
211 /*******************************************************************************\r
212 * Function Name  : CAN_SetTxMsgObj                                           \r
213 * Description    : Configures the message object as TX.                        \r
214 * Input          : - msgobj: specifies the Message object number, from 0 to 31.                      \r
215 *                  - idType: specifies the identifier type of the frames that\r
216 *                    will be transmitted using this message object.\r
217 *                    This parameter can be one of the following values:\r
218 *                          - CAN_STD_ID (standard ID, 11-bit)\r
219 *                          - CAN_EXT_ID (extended ID, 29-bit)                                \r
220 * Output         : None                                                      \r
221 * Return         : An ErrorStatus enumuration value:\r
222 *                         - SUCCESS: Interface to treat the message\r
223 *                         - ERROR: No interface found to treat the message\r
224 *******************************************************************************/\r
225 ErrorStatus CAN_SetTxMsgObj(u32 msgobj, u32 idType)\r
226 {\r
227   u32 msg_if=0;\r
228 \r
229   if ((msg_if = GetFreeIF()) == 2)\r
230   {\r
231     return ERROR;\r
232   }\r
233   \r
234   CAN->sMsgObj[msg_if].CMR = CAN_CMR_WRRD\r
235                            | CAN_CMR_MASK\r
236                            | CAN_CMR_ARB\r
237                            | CAN_CMR_CONTROL\r
238                            | CAN_CMR_DATAA\r
239                            | CAN_CMR_DATAB;\r
240 \r
241   CAN->sMsgObj[msg_if].M1R = 0;\r
242   CAN->sMsgObj[msg_if].A1R = 0;\r
243 \r
244   if (idType == CAN_STD_ID)\r
245   {\r
246     CAN->sMsgObj[msg_if].M2R = CAN_M2R_MDIR;\r
247     CAN->sMsgObj[msg_if].A2R = CAN_A2R_MSGVAL | CAN_A2R_DIR;\r
248   }\r
249   else\r
250   {\r
251     CAN->sMsgObj[msg_if].M2R = CAN_M2R_MDIR | CAN_M2R_MXTD;\r
252     CAN->sMsgObj[msg_if].A2R = CAN_A2R_MSGVAL | CAN_A2R_DIR | CAN_A2R_XTD;\r
253   }\r
254 \r
255   CAN->sMsgObj[msg_if].MCR = CAN_MCR_TXIE | CAN_MCR_EOB;\r
256 \r
257   CAN->sMsgObj[msg_if].DA1R = 0;\r
258   CAN->sMsgObj[msg_if].DA2R = 0;\r
259   CAN->sMsgObj[msg_if].DB1R = 0;\r
260   CAN->sMsgObj[msg_if].DB2R = 0;\r
261 \r
262   CAN->sMsgObj[msg_if].CRR = 1 + msgobj;\r
263   \r
264   return SUCCESS;\r
265 }\r
266 \r
267 /*******************************************************************************\r
268 * Function Name  : CAN_SetRxMsgObj                                           \r
269 * Description    : Configures the message object as RX.                        \r
270 * Input          : - msgobj: specifies the Message object number, from 0 to 31.                    \r
271 *                  - idType: specifies the identifier type of the frames that\r
272 *                    will be transmitted using this message object.\r
273 *                    This parameter can be one of the following values:\r
274 *                          - CAN_STD_ID (standard ID, 11-bit)\r
275 *                          - CAN_EXT_ID (extended ID, 29-bit)                               \r
276 *                  - idLow: specifies the low part of the identifier range used      \r
277 *                    for acceptance filtering.\r
278 *                  - idHigh: specifies the high part of the identifier range    \r
279 *                    used for acceptance filtering.\r
280 *                  - singleOrFifoLast: specifies the end-of-buffer indicator.\r
281 *                    This parameter can be one of the following values:\r
282 *                          - TRUE: for a single receive object or a FIFO receive\r
283 *                            object that is the last one of the FIFO. \r
284 *                          - FALSE: for a FIFO receive object that is not the \r
285 *                            last one. \r
286 * Output         : None                                                      \r
287 * Return         : An ErrorStatus enumuration value:\r
288 *                         - SUCCESS: Interface to treat the message\r
289 *                         - ERROR: No interface found to treat the message\r
290 *******************************************************************************/\r
291 ErrorStatus CAN_SetRxMsgObj(u32 msgobj, u32 idType, u32 idLow, u32 idHigh, bool singleOrFifoLast)\r
292 {\r
293   u32 msg_if=0;\r
294 \r
295   if ((msg_if = GetFreeIF()) == 2)\r
296   {\r
297     return ERROR;\r
298   }\r
299   \r
300   CAN->sMsgObj[msg_if].CMR = CAN_CMR_WRRD\r
301                            | CAN_CMR_MASK\r
302                            | CAN_CMR_ARB\r
303                            | CAN_CMR_CONTROL\r
304                            | CAN_CMR_DATAA\r
305                            | CAN_CMR_DATAB;\r
306 \r
307   if (idType == CAN_STD_ID)\r
308   {\r
309     CAN->sMsgObj[msg_if].M1R = 0;\r
310     CAN->sMsgObj[msg_if].M2R = STD_RANGE_ID_MSK(idLow, idHigh);\r
311 \r
312     CAN->sMsgObj[msg_if].A1R = 0;\r
313     CAN->sMsgObj[msg_if].A2R = CAN_A2R_MSGVAL | STD_RANGE_ID_ARB(idLow, idHigh);\r
314   }\r
315   else\r
316   {\r
317     CAN->sMsgObj[msg_if].M1R = EXT_RANGE_ID_MSK_L(idLow, idHigh);\r
318     CAN->sMsgObj[msg_if].M2R = CAN_M2R_MXTD | EXT_RANGE_ID_MSK_H(idLow, idHigh);\r
319 \r
320     CAN->sMsgObj[msg_if].A1R = EXT_RANGE_ID_ARB_L(idLow, idHigh);\r
321     CAN->sMsgObj[msg_if].A2R = CAN_A2R_MSGVAL | CAN_A2R_XTD | EXT_RANGE_ID_ARB_H(idLow, idHigh);\r
322   }\r
323 \r
324   CAN->sMsgObj[msg_if].MCR = CAN_MCR_RXIE | CAN_MCR_UMASK | (singleOrFifoLast ? CAN_MCR_EOB : 0);\r
325 \r
326   CAN->sMsgObj[msg_if].DA1R = 0;\r
327   CAN->sMsgObj[msg_if].DA2R = 0;\r
328   CAN->sMsgObj[msg_if].DB1R = 0;\r
329   CAN->sMsgObj[msg_if].DB2R = 0;\r
330 \r
331   CAN->sMsgObj[msg_if].CRR = 1 + msgobj;\r
332   \r
333   return SUCCESS;\r
334 }\r
335 \r
336 /*******************************************************************************\r
337 * Function Name  : CAN_InvalidateAllMsgObj                                    \r
338 * Description    : Configures all the message objects as unused.               \r
339 * Input          : None                                                      \r
340 * Output         : None                                                      \r
341 * Return         : None                                                      \r
342 *******************************************************************************/\r
343 void CAN_InvalidateAllMsgObj(void)\r
344 {\r
345   u32 i=0;\r
346   for (i = 0; i < 32; i++)\r
347     CAN_SetUnusedMsgObj(i);\r
348 }\r
349 \r
350 \r
351 /*******************************************************************************\r
352 * Function Name  : CAN_ReleaseMessage                                         \r
353 * Description    : Releases the message object                                \r
354 * Input          : - msgobj: specifies the Message object number, from 0 to 31.                     \r
355 * Output         : None                                                      \r
356 * Return         : An ErrorStatus enumuration value:\r
357 *                         - SUCCESS: Interface to treat the message\r
358 *                         - ERROR: No interface found to treat the message\r
359 *******************************************************************************/\r
360 ErrorStatus CAN_ReleaseMessage(u32 msgobj)\r
361 {\r
362   u32 msg_if=0;\r
363 \r
364   if ((msg_if = GetFreeIF()) == 2)\r
365   {\r
366     return ERROR;\r
367   }\r
368 \r
369   CAN->sMsgObj[msg_if].CMR = CAN_CMR_CLRINTPND | CAN_CMR_TXRQSTNEWDAT;\r
370   CAN->sMsgObj[msg_if].CRR = 1 + msgobj;\r
371   \r
372   return SUCCESS;\r
373 }\r
374 \r
375 /*******************************************************************************\r
376 * Function Name  : CAN_SendMessage                                           \r
377 * Description    : Start transmission of a message                           \r
378 * Input          : - msgobj: specifies the Message object number, from 0 to 31.                    \r
379 *                : - pCanMsg: pointer to the message structure containing data     \r
380 *                    to transmit.\r
381 * Output         : None                                                      \r
382 * Return         : An ErrorStatus enumuration value:\r
383 *                         - SUCCESS: Transmission OK\r
384 *                         - ERROR: No transmission\r
385 *******************************************************************************/\r
386 ErrorStatus CAN_SendMessage(u32 msgobj, canmsg* pCanMsg)\r
387 {\r
388   if (CAN->sMsgObj[0].CRR & CAN_CRR_BUSY)\r
389   {\r
390     return ERROR;                    \r
391   }\r
392 \r
393   CAN->SR &= ~CAN_SR_TXOK;\r
394 \r
395   /* read the Arbitration and Message Control*/\r
396   CAN->sMsgObj[0].CMR = CAN_CMR_ARB | CAN_CMR_CONTROL;\r
397 \r
398   CAN->sMsgObj[0].CRR = 1 + msgobj;\r
399 \r
400   if (CAN->sMsgObj[0].CRR & CAN_CRR_BUSY)\r
401   {\r
402     return ERROR;                    \r
403   }\r
404 \r
405   /* update the contents needed for transmission*/\r
406   CAN->sMsgObj[0].CMR = CAN_CMR_WRRD\r
407                       | CAN_CMR_ARB\r
408                       | CAN_CMR_CONTROL\r
409                       | CAN_CMR_DATAA\r
410                       | CAN_CMR_DATAB;\r
411 \r
412   if ((CAN->sMsgObj[0].A2R & CAN_A2R_XTD) == 0)\r
413   {\r
414     /* standard ID*/\r
415     CAN->sMsgObj[0].A1R = 0;\r
416     CAN->sMsgObj[0].A2R = (CAN->sMsgObj[0].A2R & 0xE000) | STD_FIXED_ID_ARB(pCanMsg->Id);\r
417   }\r
418   else\r
419   {\r
420     /* extended ID*/\r
421     CAN->sMsgObj[0].A1R = EXT_FIXED_ID_ARB_L(pCanMsg->Id);\r
422     CAN->sMsgObj[0].A2R = (CAN->sMsgObj[0].A2R & 0xE000) | EXT_FIXED_ID_ARB_H(pCanMsg->Id);\r
423   }\r
424 \r
425   CAN->sMsgObj[0].MCR = (CAN->sMsgObj[0].MCR & 0xFEF0) | CAN_MCR_NEWDAT | CAN_MCR_TXRQST | pCanMsg->Dlc;\r
426 \r
427   CAN->sMsgObj[0].DA1R = ((u16)pCanMsg->Data[1]<<8) | pCanMsg->Data[0];\r
428   CAN->sMsgObj[0].DA2R = ((u16)pCanMsg->Data[3]<<8) | pCanMsg->Data[2];\r
429   CAN->sMsgObj[0].DB1R = ((u16)pCanMsg->Data[5]<<8) | pCanMsg->Data[4];\r
430   CAN->sMsgObj[0].DB2R = ((u16)pCanMsg->Data[7]<<8) | pCanMsg->Data[6];\r
431 \r
432   CAN->sMsgObj[0].CRR = 1 + msgobj;\r
433 \r
434   return SUCCESS;\r
435 }\r
436 \r
437 /*******************************************************************************\r
438 * Function Name  : CAN_ReceiveMessage                                        \r
439 * Description    : Gets the message, if received.\r
440 * Input          : - msgobj: specifies the Message object number, from 0 to 31.                     \r
441 *                  - release: specifies the message release indicator.\r
442 *                    This parameter can be one of the following values:\r
443 *                          - TRUE: the message object is released when getting  \r
444 *                            the data.\r
445 *                          - FALSE: the message object is not released.\r
446 *                  - pCanMsg: pointer to the message structure where received   \r
447 *                    data is copied.\r
448 * Output         : None                                                      \r
449 * Return         : An ErrorStatus enumuration value:\r
450 *                         - SUCCESS: Reception OK\r
451 *                         - ERROR: No message pending\r
452 *******************************************************************************/\r
453 ErrorStatus CAN_ReceiveMessage(u32 msgobj, bool release, canmsg* pCanMsg)\r
454 {\r
455   if (!CAN_IsMessageWaiting(msgobj))\r
456   {\r
457     return ERROR;\r
458   }\r
459 \r
460   CAN->SR &= ~CAN_SR_RXOK;\r
461 \r
462   /* read the message contents*/\r
463   CAN->sMsgObj[1].CMR = CAN_CMR_MASK\r
464                       | CAN_CMR_ARB\r
465                       | CAN_CMR_CONTROL\r
466                       | CAN_CMR_CLRINTPND\r
467                       | (release ? CAN_CMR_TXRQSTNEWDAT : 0)\r
468                       | CAN_CMR_DATAA\r
469                       | CAN_CMR_DATAB;\r
470 \r
471   CAN->sMsgObj[1].CRR = 1 + msgobj;\r
472 \r
473   if (CAN->sMsgObj[1].CRR & CAN_CRR_BUSY)\r
474   {\r
475     return ERROR;                    \r
476   }\r
477   \r
478   if ((CAN->sMsgObj[1].A2R & CAN_A2R_XTD) == 0)\r
479   {\r
480     /* standard ID*/\r
481     pCanMsg->IdType = CAN_STD_ID;\r
482     pCanMsg->Id = (CAN->sMsgObj[1].A2R >> 2) & 0x07FF;\r
483   }\r
484   else\r
485   {\r
486     /* extended ID*/\r
487     pCanMsg->IdType = CAN_EXT_ID;\r
488     pCanMsg->Id  = ((CAN->sMsgObj[1].A2R >> 2) & 0x07FF); \r
489     pCanMsg->Id |= ((u32)CAN->sMsgObj[1].A1R << 11);\r
490     pCanMsg->Id |= (((u32)CAN->sMsgObj[1].A2R & 0x0003) << 27);\r
491   }\r
492 \r
493   pCanMsg->Dlc = CAN->sMsgObj[1].MCR & 0x0F;\r
494 \r
495   pCanMsg->Data[0] = (u8) CAN->sMsgObj[1].DA1R;\r
496   pCanMsg->Data[1] = (u8)(CAN->sMsgObj[1].DA1R >> 8);\r
497   pCanMsg->Data[2] = (u8) CAN->sMsgObj[1].DA2R;\r
498   pCanMsg->Data[3] = (u8)(CAN->sMsgObj[1].DA2R >> 8);\r
499   pCanMsg->Data[4] = (u8) CAN->sMsgObj[1].DB1R;\r
500   pCanMsg->Data[5] = (u8)(CAN->sMsgObj[1].DB1R >> 8);\r
501   pCanMsg->Data[6] = (u8) CAN->sMsgObj[1].DB2R;\r
502   pCanMsg->Data[7] = (u8)(CAN->sMsgObj[1].DB2R >> 8);\r
503 \r
504   return SUCCESS;\r
505 }\r
506 \r
507 /*******************************************************************************\r
508 * Function Name  : CAN_WaitEndOfTx                                           \r
509 * Description    : Waits until current transmission is finished.               \r
510 * Input          : None                                                      \r
511 * Output         : None                                                      \r
512 * Return         : An ErrorStatus enumuration value:\r
513 *                         - SUCCESS: Transmission ended\r
514 *                         - ERROR: Transmission did not occur yet\r
515 *******************************************************************************/\r
516 ErrorStatus CAN_WaitEndOfTx(void)\r
517 {\r
518   if ((CAN->SR & CAN_SR_TXOK) == 0)\r
519   {\r
520     return ERROR;\r
521   }\r
522   CAN->SR &= ~CAN_SR_TXOK;\r
523   \r
524   return SUCCESS;\r
525 }\r
526 \r
527 /*******************************************************************************\r
528 * Function Name  : CAN_BasicSendMessage                                      \r
529 * Description    : Starts transmission of a message in BASIC mode. This mode \r
530 *                  does not use the message RAM.             \r
531 * Input          : pCanMsg: Pointer to the message structure containing data to       \r
532 *                  transmit.                                                  \r
533 * Output         : None                                                      \r
534 * Return         : An ErrorStatus enumuration value:\r
535 *                         - SUCCESS: Transmission OK\r
536 *                         - ERROR: No transmission\r
537 *******************************************************************************/\r
538 ErrorStatus CAN_BasicSendMessage(canmsg* pCanMsg)\r
539 {\r
540   /* clear NewDat bit in IF2 to detect next reception*/\r
541   CAN->sMsgObj[1].MCR &= ~CAN_MCR_NEWDAT;\r
542 \r
543   CAN->SR &= ~CAN_SR_TXOK;\r
544   CAN->sMsgObj[0].CMR = CAN_CMR_WRRD\r
545                       | CAN_CMR_ARB\r
546                       | CAN_CMR_CONTROL\r
547                       | CAN_CMR_DATAA\r
548                       | CAN_CMR_DATAB;\r
549 \r
550   if (pCanMsg->IdType == CAN_STD_ID)\r
551   {\r
552     /* standard ID*/\r
553     CAN->sMsgObj[0].A1R = 0;\r
554     CAN->sMsgObj[0].A2R = (CAN->sMsgObj[0].A2R & 0xE000) | STD_FIXED_ID_ARB(pCanMsg->Id);\r
555   }\r
556   else\r
557   {\r
558     /* extended ID*/\r
559     CAN->sMsgObj[0].A1R = EXT_FIXED_ID_ARB_L(pCanMsg->Id);\r
560     CAN->sMsgObj[0].A2R = ((CAN->sMsgObj[0].A2R) & 0xE000) | EXT_FIXED_ID_ARB_H(pCanMsg->Id);\r
561   }\r
562 \r
563   CAN->sMsgObj[0].MCR = (CAN->sMsgObj[0].MCR & 0xFCF0) | pCanMsg->Dlc;\r
564 \r
565   CAN->sMsgObj[0].DA1R = ((u16)pCanMsg->Data[1]<<8) | pCanMsg->Data[0];\r
566   CAN->sMsgObj[0].DA2R = ((u16)pCanMsg->Data[3]<<8) | pCanMsg->Data[2];\r
567   CAN->sMsgObj[0].DB1R = ((u16)pCanMsg->Data[5]<<8) | pCanMsg->Data[4];\r
568   CAN->sMsgObj[0].DB2R = ((u16)pCanMsg->Data[7]<<8) | pCanMsg->Data[6];\r
569 \r
570   /* request transmission*/\r
571   if (CAN->sMsgObj[0].CRR == CAN_CRR_BUSY )\r
572   {\r
573     return ERROR;\r
574   }\r
575 \r
576   return SUCCESS;\r
577 }\r
578 \r
579 /*******************************************************************************\r
580 * Function Name  : CAN_BasicReceiveMessage                                   \r
581 * Description    : Gets the message in BASIC mode, if received. This mode does\r
582 *                  not use the message RAM.                \r
583 * Input          : pCanMsg: pointer to the message structure where message is copied.    \r
584 * Output         : None                                                      \r
585 * Return         : An ErrorStatus enumuration value:\r
586 *                         - SUCCESS: Reception OK\r
587 *                         - ERROR: No message pending\r
588 *******************************************************************************/\r
589 ErrorStatus CAN_BasicReceiveMessage(canmsg* pCanMsg)\r
590 {\r
591   if ((CAN->sMsgObj[1].MCR & CAN_MCR_NEWDAT) == 0)\r
592   {\r
593     return ERROR;\r
594   }\r
595 \r
596   CAN->SR &= ~CAN_SR_RXOK;\r
597 \r
598   CAN->sMsgObj[1].CMR = CAN_CMR_ARB\r
599                       | CAN_CMR_CONTROL\r
600                       | CAN_CMR_DATAA\r
601                       | CAN_CMR_DATAB;\r
602 \r
603   if ((CAN->sMsgObj[1].A2R & CAN_A2R_XTD) == 0)\r
604   {\r
605     /* standard ID*/\r
606     pCanMsg->IdType = CAN_STD_ID;\r
607     pCanMsg->Id = (CAN->sMsgObj[1].A2R >> 2) & 0x07FF;\r
608   }\r
609   else\r
610   {\r
611     /* extended ID*/\r
612     pCanMsg->IdType = CAN_EXT_ID;\r
613     pCanMsg->Id  = ((CAN->sMsgObj[1].A2R >> 2) & 0x07FF);\r
614     pCanMsg->Id |= ((u32)CAN->sMsgObj[1].A1R << 11);\r
615     pCanMsg->Id |= (((u32)CAN->sMsgObj[1].A2R & 0x0003) << 27);\r
616   }\r
617 \r
618   pCanMsg->Dlc = CAN->sMsgObj[1].MCR & 0x0F;\r
619 \r
620   pCanMsg->Data[0] = (u8) CAN->sMsgObj[1].DA1R;\r
621   pCanMsg->Data[1] = (u8)(CAN->sMsgObj[1].DA1R >> 8);\r
622   pCanMsg->Data[2] = (u8) CAN->sMsgObj[1].DA2R;\r
623   pCanMsg->Data[3] = (u8)(CAN->sMsgObj[1].DA2R >> 8);\r
624   pCanMsg->Data[4] = (u8) CAN->sMsgObj[1].DB1R;\r
625   pCanMsg->Data[5] = (u8)(CAN->sMsgObj[1].DB1R >> 8);\r
626   pCanMsg->Data[6] = (u8) CAN->sMsgObj[1].DB2R;\r
627   pCanMsg->Data[7] = (u8)(CAN->sMsgObj[1].DB2R >> 8);\r
628 \r
629   return SUCCESS;\r
630 }\r
631 \r
632 /*******************************************************************************\r
633 * Function Name  : CAN_EnterInitMode                                         \r
634 * Description    : Switchs the CAN into initialization mode. This function must\r
635 *                  be used in conjunction with CAN_LeaveInitMode().                 \r
636 * Input          : InitMask: specifies the CAN configuration in normal mode.      \r
637 * Output         : None                                                      \r
638 * Return         : None                                                          \r
639 *******************************************************************************/\r
640 void CAN_EnterInitMode(u8 InitMask)\r
641 {\r
642   CAN->CR = InitMask | CAN_CR_INIT;\r
643   CAN->SR = 0;                                  /* reset the status*/\r
644 }\r
645 \r
646 /*******************************************************************************\r
647 * Function Name  : CAN_LeaveInitMode                                         \r
648 * Description    : Leaves the initialization mode (switch into normal mode).\r
649 *                  This function must be used in conjunction with CAN_EnterInitMode().  \r
650 * Input          : None                                                      \r
651 * Output         : None                                                      \r
652 * Return         : None                                                      \r
653 *******************************************************************************/\r
654 void CAN_LeaveInitMode(void)\r
655 {\r
656   CAN->CR &= ~(CAN_CR_INIT | CAN_CR_CCE);\r
657 }\r
658 \r
659 /*******************************************************************************\r
660 * Function Name  : CAN_EnterTestMode                                         \r
661 * Description    : Switchs the CAN into test mode. This function must be used in\r
662 *                  conjunction with CAN_LeaveTestMode().                            \r
663 * Input          : TestMask: specifies the configuration in test modes.     \r
664 * Output         : None                                                      \r
665 * Return         : None                                                            \r
666 *******************************************************************************/\r
667 void CAN_EnterTestMode(u8 TestMask)\r
668 {\r
669   CAN->CR |= CAN_CR_TEST;\r
670   CAN->TESTR |= TestMask;\r
671 }\r
672 \r
673 /*******************************************************************************\r
674 * Function Name  : CAN_LeaveTestMode                                         \r
675 * Description    : Leaves the current test mode (switch into normal mode).\r
676 *                  This function must be used in conjunction with CAN_EnterTestMode().    \r
677 * Input          : None                                                      \r
678 * Output         : None                                                      \r
679 * Return         : None                                                      \r
680 *******************************************************************************/\r
681 void CAN_LeaveTestMode(void)\r
682 {\r
683   CAN->CR |= CAN_CR_TEST;\r
684   CAN->TESTR &= ~(CAN_TESTR_LBACK | CAN_TESTR_SILENT | CAN_TESTR_BASIC);\r
685   CAN->CR &= ~CAN_CR_TEST;\r
686 }\r
687 \r
688 /*******************************************************************************\r
689 * Function Name  : CAN_ReleaseTxMessage                                      \r
690 * Description    : Releases the transmit message object.\r
691 * Input          : - msgobj: specifies the Message object number, from 0 to 31.                     \r
692 * Output         : None                                                      \r
693 * Return         : None                                                                        \r
694 *******************************************************************************/\r
695 void CAN_ReleaseTxMessage(u32 msgobj)\r
696 {\r
697   CAN->sMsgObj[0].CMR = CAN_CMR_CLRINTPND | CAN_CMR_TXRQSTNEWDAT;\r
698   CAN->sMsgObj[0].CRR = 1 + msgobj;\r
699 }\r
700 \r
701 /*******************************************************************************\r
702 * Function Name  : CAN_ReleaseRxMessage                                      \r
703 * Description    : Releases the receive message object.                        \r
704 * Input          : - msgobj: specifies the Message object number, from 0 to 31.                      \r
705 * Output         : None                                                      \r
706 * Return         : None                                                                      \r
707 *******************************************************************************/\r
708 void CAN_ReleaseRxMessage(u32 msgobj)\r
709 {\r
710   CAN->sMsgObj[1].CMR = CAN_CMR_CLRINTPND | CAN_CMR_TXRQSTNEWDAT;\r
711   CAN->sMsgObj[1].CRR = 1 + msgobj;\r
712 }\r
713 \r
714 /*******************************************************************************\r
715 * Function Name  : CAN_IsMessageWaiting                                      \r
716 * Description    : Tests the waiting status of a received message.             \r
717 * Input          : - msgobj: specifies the Message object number, from 0 to 31.                       \r
718 * Output         : None                                                      \r
719 * Return         : A non-zero value if the corresponding message object has  \r
720 *                  received a message waiting to be copied, else 0.           \r
721 *******************************************************************************/\r
722 u32 CAN_IsMessageWaiting(u32 msgobj)\r
723 {\r
724   return (msgobj < 16 ? CAN->ND1R & (1 << msgobj) : CAN->ND2R & (1 << (msgobj-16)));\r
725 }\r
726 \r
727 /*******************************************************************************\r
728 * Function Name  : CAN_IsTransmitRequested                                   \r
729 * Description    : Tests the request status of a transmitted message.          \r
730 * Input          : - msgobj: specifies the Message object number, from 0 to 31.                      \r
731 * Output         : None                                                      \r
732 * Return         : A non-zero value if the corresponding message is requested\r
733 *                  to transmit, else 0.                                       \r
734 *******************************************************************************/\r
735 u32 CAN_IsTransmitRequested(u32 msgobj)\r
736 {\r
737   return (msgobj < 16 ? CAN->TXR1R & (1 << msgobj) : CAN->TXR2R & (1 << (msgobj-16)));\r
738 }\r
739 \r
740 /*******************************************************************************\r
741 * Function Name  : CAN_IsInterruptPending                                    \r
742 * Description    : Tests the interrupt status of a message object.             \r
743 * Input          : - msgobj: specifies the Message object number, from 0 to 31.                      \r
744 * Output         : None                                                      \r
745 * Return         : A non-zero value if the corresponding message has an      \r
746 *                  interrupt pending, else 0.                                 \r
747 *******************************************************************************/\r
748 u32 CAN_IsInterruptPending(u32 msgobj)\r
749 {\r
750   return (msgobj < 16 ? CAN->IP1R & (1 << msgobj) : CAN->IP2R & (1 << (msgobj-16)));\r
751 }\r
752 \r
753 /*******************************************************************************\r
754 * Function Name  : CAN_IsObjectValid                                         \r
755 * Description    : Tests the validity of a message object (ready to use).      \r
756 * Input          : - msgobj: specifies the Message object number, from 0 to 31.                      \r
757 * Output         : None                                                      \r
758 * Return         : A non-zero value if the corresponding message object is   \r
759 *                  valid, else 0.                                             \r
760 *******************************************************************************/\r
761 u32 CAN_IsObjectValid(u32 msgobj)\r
762 {\r
763   return (msgobj < 16 ? CAN->MV1R & (1 << msgobj) : CAN->MV2R & (1 << (msgobj-16)));\r
764 }\r
765 /******************* (C) COPYRIGHT 2006 STMicroelectronics *****END OF FILE****/\r