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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [freertos-6.1.1/] [Demo/] [ARM9_STR91X_IAR/] [Library/] [source/] [91x_can.c] - Blame information for rev 675

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