Subversion Repositories NaviCtrl

Rev

Rev 313 | Details | Compare with Previous | Last modification | View Log | RSS feed

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