Subversion Repositories NaviCtrl

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

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