OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [freertos-6.1.1/] [Demo/] [ARM7_STR75x_IAR/] [STLibrary/] [src/] [75x_can.c] - Blame information for rev 609

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.