uc-sdk
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
lpc17xx_can.c
Go to the documentation of this file.
1 /***********************************************************************/
20 /* Peripheral group ----------------------------------------------------------- */
25 /* Includes ------------------------------------------------------------------- */
26 #include "lpc17xx_can.h"
27 #include "lpc17xx_clkpwr.h"
28 
29 /* If this source file built with example, the LPC17xx FW library configuration
30  * file in each example directory ("lpc17xx_libcfg.h") must be included,
31  * otherwise the default FW library configuration file must be included instead
32  */
33 #ifdef __BUILD_WITH_EXAMPLE__
34 #include "lpc17xx_libcfg.h"
35 #else
36 #include "lpc17xx_libcfg_default.h"
37 #endif /* __BUILD_WITH_EXAMPLE__ */
38 
39 
40 #ifdef _CAN
41 
42 /* Private Variables ---------------------------------------------------------- */
47 FunctionalState FULLCAN_ENABLE;
48 
49 
50 /* Counts number of filters (CAN message objects) used */
51 uint16_t CANAF_FullCAN_cnt = 0;
52 uint16_t CANAF_std_cnt = 0;
53 uint16_t CANAF_gstd_cnt = 0;
54 uint16_t CANAF_ext_cnt = 0;
55 uint16_t CANAF_gext_cnt = 0;
56 
57 /* End of Private Variables ----------------------------------------------------*/
62 /* Private Variables ---------------------------------------------------------- */
63 static void can_SetBaudrate (LPC_CAN_TypeDef *CANx, uint32_t baudrate);
64 
65 /*********************************************************************/
73 static void can_SetBaudrate (LPC_CAN_TypeDef *CANx, uint32_t baudrate)
74 {
75  uint32_t result = 0;
76  uint8_t NT, TSEG1 = 0, TSEG2 = 0;
77  uint32_t CANPclk = 0;
78  uint32_t BRP = 0;
79  CHECK_PARAM(PARAM_CANx(CANx));
80 
81  if (CANx == LPC_CAN1)
82  {
84  }
85  else
86  {
88  }
89  result = CANPclk / baudrate;
90  /* Calculate suitable nominal time value
91  * NT (nominal time) = (TSEG1 + TSEG2 + 3)
92  * NT <= 24
93  * TSEG1 >= 2*TSEG2
94  */
95  for(NT=24;NT>0;NT=NT-2)
96  {
97  if ((result%NT)==0)
98  {
99  BRP = result / NT - 1;
100  NT--;
101  TSEG2 = (NT/3) - 1;
102  TSEG1 = NT -(NT/3) - 1;
103  break;
104  }
105  }
106  /* Enter reset mode */
107  CANx->MOD = 0x01;
108  /* Set bit timing
109  * Default: SAM = 0x00;
110  * SJW = 0x03;
111  */
112  CANx->BTR = (TSEG2<<20)|(TSEG1<<16)|(3<<14)|BRP;
113  /* Return to normal operating */
114  CANx->MOD = 0;
115 }
116 /* End of Private Functions ----------------------------------------------------*/
117 
118 
119 /* Public Functions ----------------------------------------------------------- */
124 /********************************************************************/
132 void CAN_Init(LPC_CAN_TypeDef *CANx, uint32_t baudrate)
133 {
134  volatile uint32_t temp;
135  uint16_t i;
136  CHECK_PARAM(PARAM_CANx(CANx));
137 
138  if(CANx == LPC_CAN1)
139  {
140  /* Turn on power and clock for CAN1 */
142  /* Set clock divide for CAN1 */
144  }
145  else
146  {
147  /* Turn on power and clock for CAN1 */
149  /* Set clock divide for CAN2 */
151  }
152 
153  CANx->MOD = 1; // Enter Reset Mode
154  CANx->IER = 0; // Disable All CAN Interrupts
155  CANx->GSR = 0;
156  /* Request command to release Rx, Tx buffer and clear data overrun */
157  //CANx->CMR = CAN_CMR_AT | CAN_CMR_RRB | CAN_CMR_CDO;
158  CANx->CMR = (1<<1)|(1<<2)|(1<<3);
159  /* Read to clear interrupt pending in interrupt capture register */
160  temp = CANx->ICR;
161  (void )temp;
162  CANx->MOD = 0;// Return Normal operating
163 
164  //Reset CANAF value
165  LPC_CANAF->AFMR = 0x01;
166 
167  //clear ALUT RAM
168  for (i = 0; i < 512; i++) {
169  LPC_CANAF_RAM->mask[i] = 0x00;
170  }
171 
172  LPC_CANAF->SFF_sa = 0x00;
173  LPC_CANAF->SFF_GRP_sa = 0x00;
174  LPC_CANAF->EFF_sa = 0x00;
175  LPC_CANAF->EFF_GRP_sa = 0x00;
176  LPC_CANAF->ENDofTable = 0x00;
177 
178  LPC_CANAF->AFMR = 0x00;
179  /* Set baudrate */
180  can_SetBaudrate (CANx, baudrate);
181 }
182 
183 /********************************************************************/
190 void CAN_DeInit(LPC_CAN_TypeDef *CANx)
191 {
192  CHECK_PARAM(PARAM_CANx(CANx));
193 
194  if(CANx == LPC_CAN1)
195  {
196  /* Turn on power and clock for CAN1 */
198  }
199  else
200  {
201  /* Turn on power and clock for CAN1 */
203  }
204 }
205 
206 /********************************************************************/
218 {
219  uint8_t ctrl1,ctrl2;
220  uint8_t dis1, dis2;
221  uint16_t SID, SID_temp,i, count = 0;
222  uint32_t EID, EID_temp, entry, buf;
223  uint16_t lowerSID, upperSID;
224  uint32_t lowerEID, upperEID;
225 
226  CHECK_PARAM(PARAM_CANAFx(CANAFx));
227  CANAFx->AFMR = 0x01;
228 
229 /***** setup FullCAN Table *****/
230  if(AFSection->FullCAN_Sec == NULL)
231  {
232  FULLCAN_ENABLE = DISABLE;
233  }
234  else
235  {
236  FULLCAN_ENABLE = ENABLE;
237  for(i=0;i<(AFSection->FC_NumEntry);i++)
238  {
239  if(count + 1 > 64)
240  {
241  return CAN_OBJECTS_FULL_ERROR;
242  }
243  ctrl1 = AFSection->FullCAN_Sec->controller;
244  SID = AFSection->FullCAN_Sec->id_11;
245  dis1 = AFSection->FullCAN_Sec->disable;
246 
247  CHECK_PARAM(PARAM_CTRL(ctrl1));
248  CHECK_PARAM(PARAM_ID_11(SID));
250  entry = 0x00; //reset entry value
251  if((CANAF_FullCAN_cnt & 0x00000001)==0)
252  {
253  if(count!=0x00)
254  {
255  buf = LPC_CANAF_RAM->mask[count-1];
256  SID_temp = (buf & 0x000003FF);
257  if(SID_temp > SID)
258  {
259  return CAN_AF_ENTRY_ERROR;
260  }
261  }
262  entry = (ctrl1<<29)|(dis1<<28)|(SID<<16)|(1<<27);
263  LPC_CANAF_RAM->mask[count] &= 0x0000FFFF;
264  LPC_CANAF_RAM->mask[count] |= entry;
265  CANAF_FullCAN_cnt++;
266  }
267  else
268  {
269  buf = LPC_CANAF_RAM->mask[count];
270  SID_temp = (buf & 0x03FF0000)>>16;
271  if(SID_temp > SID)
272  {
273  return CAN_AF_ENTRY_ERROR;
274  }
275  entry = (ctrl1<<13)|(dis1<<12)|(SID<<0)|(1<<11);
276  LPC_CANAF_RAM->mask[count] &= 0xFFFF0000;
277  LPC_CANAF_RAM->mask[count]|= entry;
278  count++;
279  CANAF_FullCAN_cnt++;
280  }
281  AFSection->FullCAN_Sec = (FullCAN_Entry *)((uint32_t)(AFSection->FullCAN_Sec)+ sizeof(FullCAN_Entry));
282  }
283  }
284 
285 /***** Setup Explicit Standard Frame Format Section *****/
286  if(AFSection->SFF_Sec != NULL)
287  {
288  for(i=0;i<(AFSection->SFF_NumEntry);i++)
289  {
290  if(count + 1 > 512)
291  {
292  return CAN_OBJECTS_FULL_ERROR;
293  }
294  ctrl1 = AFSection->SFF_Sec->controller;
295  SID = AFSection->SFF_Sec->id_11;
296  dis1 = AFSection->SFF_Sec->disable;
297 
298  //check parameter
299  CHECK_PARAM(PARAM_CTRL(ctrl1));
300  CHECK_PARAM(PARAM_ID_11(SID));
302 
303  entry = 0x00; //reset entry value
304  if((CANAF_std_cnt & 0x00000001)==0)
305  {
306  if(CANAF_std_cnt !=0 )
307  {
308  buf = LPC_CANAF_RAM->mask[count-1];
309  SID_temp = (buf & 0x00000FFF);
310  if(SID_temp > SID)
311  {
312  return CAN_AF_ENTRY_ERROR;
313  }
314  }
315  entry = (ctrl1<<29)|(dis1<<28)|(SID<<16);
316  LPC_CANAF_RAM->mask[count] &= 0x0000FFFF;
317  LPC_CANAF_RAM->mask[count] |= entry;
318  CANAF_std_cnt++;
319  }
320  else
321  {
322  buf = LPC_CANAF_RAM->mask[count];
323  SID_temp = (buf & 0x0FFF0000)>>16;
324  if(SID_temp > SID)
325  {
326  return CAN_AF_ENTRY_ERROR;
327  }
328  entry = (ctrl1<<13)|(dis1<<12)|(SID<<0);
329  LPC_CANAF_RAM->mask[count] &= 0xFFFF0000;
330  LPC_CANAF_RAM->mask[count] |= entry;
331  count++;
332  CANAF_std_cnt++;
333  }
334  AFSection->SFF_Sec = (SFF_Entry *)((uint32_t)(AFSection->SFF_Sec)+ sizeof(SFF_Entry));
335  }
336  }
337 
338 /***** Setup Group of Standard Frame Format Identifier Section *****/
339  if(AFSection->SFF_GPR_Sec != NULL)
340  {
341  for(i=0;i<(AFSection->SFF_GPR_NumEntry);i++)
342  {
343  if(count + 1 > 512)
344  {
345  return CAN_OBJECTS_FULL_ERROR;
346  }
347  ctrl1 = AFSection->SFF_GPR_Sec->controller1;
348  ctrl2 = AFSection->SFF_GPR_Sec->controller2;
349  dis1 = AFSection->SFF_GPR_Sec->disable1;
350  dis2 = AFSection->SFF_GPR_Sec->disable2;
351  lowerSID = AFSection->SFF_GPR_Sec->lowerID;
352  upperSID = AFSection->SFF_GPR_Sec->upperID;
353 
354  /* check parameter */
355  CHECK_PARAM(PARAM_CTRL(ctrl1));
356  CHECK_PARAM(PARAM_CTRL(ctrl2));
359  CHECK_PARAM(PARAM_ID_11(lowerSID));
360  CHECK_PARAM(PARAM_ID_11(upperSID));
361 
362  entry = 0x00;
363  if(CANAF_gstd_cnt!=0)
364  {
365  buf = LPC_CANAF_RAM->mask[count-1];
366  SID_temp = buf & 0x00000FFF;
367  if(SID_temp > lowerSID)
368  {
369  return CAN_AF_ENTRY_ERROR;
370  }
371  }
372  entry = (ctrl1 << 29)|(dis1 << 28)|(lowerSID << 16)| \
373  (ctrl2 << 13)|(dis2 << 12)|(upperSID << 0);
374  LPC_CANAF_RAM->mask[count] = entry;
375  CANAF_gstd_cnt++;
376  count++;
377  AFSection->SFF_GPR_Sec = (SFF_GPR_Entry *)((uint32_t)(AFSection->SFF_GPR_Sec)+ sizeof(SFF_GPR_Entry));
378  }
379  }
380 
381 /***** Setup Explicit Extend Frame Format Identifier Section *****/
382  if(AFSection->EFF_Sec != NULL)
383  {
384  for(i=0;i<(AFSection->EFF_NumEntry);i++)
385  {
386  if(count + 1 > 512)
387  {
388  return CAN_OBJECTS_FULL_ERROR;
389  }
390  EID = AFSection->EFF_Sec->ID_29;
391  ctrl1 = AFSection->EFF_Sec->controller;
392 
393  // check parameter
394  CHECK_PARAM(PARAM_ID_29(EID));
395  CHECK_PARAM(PARAM_CTRL(ctrl1));
396 
397  entry = 0x00; //reset entry value
398  if(CANAF_ext_cnt != 0)
399  {
400  buf = LPC_CANAF_RAM->mask[count-1];
401  EID_temp = buf & 0x0FFFFFFF;
402  if(EID_temp > EID)
403  {
404  return CAN_AF_ENTRY_ERROR;
405  }
406  }
407  entry = (ctrl1 << 29)|(EID << 0);
408  LPC_CANAF_RAM->mask[count] = entry;
409  CANAF_ext_cnt ++;
410  count++;
411  AFSection->EFF_Sec = (EFF_Entry *)((uint32_t)(AFSection->EFF_Sec)+ sizeof(EFF_Entry));
412  }
413  }
414 
415 /***** Setup Group of Extended Frame Format Identifier Section *****/
416  if(AFSection->EFF_GPR_Sec != NULL)
417  {
418  for(i=0;i<(AFSection->EFF_GPR_NumEntry);i++)
419  {
420  if(count + 2 > 512)
421  {
422  return CAN_OBJECTS_FULL_ERROR;
423  }
424  ctrl1 = AFSection->EFF_GPR_Sec->controller1;
425  ctrl2 = AFSection->EFF_GPR_Sec->controller2;
426  lowerEID = AFSection->EFF_GPR_Sec->lowerEID;
427  upperEID = AFSection->EFF_GPR_Sec->upperEID;
428 
429  //check parameter
430  CHECK_PARAM(PARAM_CTRL(ctrl1));
431  CHECK_PARAM(PARAM_CTRL(ctrl2));
432  CHECK_PARAM(PARAM_ID_29(lowerEID));
433  CHECK_PARAM(PARAM_ID_29(upperEID));
434 
435  entry = 0x00;
436  if(CANAF_gext_cnt != 0)
437  {
438  buf = LPC_CANAF_RAM->mask[count-1];
439  EID_temp = buf & 0x0FFFFFFF;
440  if(EID_temp > lowerEID)
441  {
442  return CAN_AF_ENTRY_ERROR;
443  }
444  }
445  entry = (ctrl1 << 29)|(lowerEID << 0);
446  LPC_CANAF_RAM->mask[count++] = entry;
447  entry = (ctrl2 << 29)|(upperEID << 0);
448  LPC_CANAF_RAM->mask[count++] = entry;
449  CANAF_gext_cnt++;
450  AFSection->EFF_GPR_Sec = (EFF_GPR_Entry *)((uint32_t)(AFSection->EFF_GPR_Sec)+ sizeof(EFF_GPR_Entry));
451  }
452  }
453  //update address values
454  LPC_CANAF->SFF_sa = ((CANAF_FullCAN_cnt + 1)>>1)<<2;
455  LPC_CANAF->SFF_GRP_sa = LPC_CANAF->SFF_sa + (((CANAF_std_cnt+1)>>1)<< 2);
456  LPC_CANAF->EFF_sa = LPC_CANAF->SFF_GRP_sa + (CANAF_gstd_cnt << 2);
457  LPC_CANAF->EFF_GRP_sa = LPC_CANAF->EFF_sa + (CANAF_ext_cnt << 2);
458  LPC_CANAF->ENDofTable = LPC_CANAF->EFF_GRP_sa + (CANAF_gext_cnt << 3);
459 
460  if(FULLCAN_ENABLE == DISABLE)
461  {
462  LPC_CANAF->AFMR = 0x00; // Normal mode
463  }
464  else
465  {
466  LPC_CANAF->AFMR = 0x04;
467  }
468  return CAN_OK;
469 }
470 /********************************************************************/
485 {
486  uint32_t tmp0 = 0;
487  uint32_t buf0=0, buf1=0;
488  int16_t cnt1=0, cnt2=0, bound1=0, total=0;
489 
490 
491  CHECK_PARAM(PARAM_CANx(CANx));
492  CHECK_PARAM(PARAM_ID_FORMAT(format));
493 
494  if (CANx == LPC_CAN1)
495  {
496  tmp0 = 0;
497  }
498  else if (CANx == LPC_CAN2)
499  {
500  tmp0 = 1;
501  }
502 
503  /* Acceptance Filter Memory full - return */
504  total =((CANAF_FullCAN_cnt+1)>>1)+ CANAF_FullCAN_cnt*3 +((CANAF_std_cnt + 1) >> 1)+ \
505  CANAF_gstd_cnt + CANAF_ext_cnt + (CANAF_gext_cnt<<1);
506  if (total >= 512){ //don't have enough space
507  return CAN_OBJECTS_FULL_ERROR;
508  }
509 
510  /* Setup Acceptance Filter Configuration
511  Acceptance Filter Mode Register = Off */
512  LPC_CANAF->AFMR = 0x00000001;
513 
514 /*********** Add Explicit Standard Identifier Frame Format entry *********/
515  if(format == STD_ID_FORMAT)
516  {
517  id &= 0x07FF;
518  id |= (tmp0 << 13); /* Add controller number */
519  /* Move all remaining sections one place up
520  if new entry will increase FullCAN list */
521  if ((CANAF_std_cnt & 0x0001) == 0)
522  {
523  cnt1 = ((CANAF_FullCAN_cnt+1)>>1)+((CANAF_std_cnt+1)>>1);
524  bound1 = total - cnt1;
525  buf0 = LPC_CANAF_RAM->mask[cnt1];
526  while(bound1--)
527  {
528  cnt1++;
529  buf1 = LPC_CANAF_RAM->mask[cnt1];
530  LPC_CANAF_RAM->mask[cnt1] = buf0;
531  buf0 = buf1;
532  }
533  }
534  if (CANAF_std_cnt == 0)
535  {
536  cnt2 = (CANAF_FullCAN_cnt + 1)>>1;
537  /* For entering first ID */
538  LPC_CANAF_RAM->mask[cnt2] = 0x0000FFFF | (id << 16);
539  }
540  else if (CANAF_std_cnt == 1)
541  {
542  cnt2 = (CANAF_FullCAN_cnt + 1)>>1;
543  /* For entering second ID */
544  if ((LPC_CANAF_RAM->mask[cnt2] >> 16) > id)
545  {
546  LPC_CANAF_RAM->mask[cnt2] = (LPC_CANAF_RAM->mask[cnt2] >> 16) | (id << 16);
547  }
548  else
549  {
550  LPC_CANAF_RAM->mask[cnt2] = (LPC_CANAF_RAM->mask[cnt2] & 0xFFFF0000) | id;
551  }
552  }
553  else
554  {
555  /* Find where to insert new ID */
556  cnt1 = (CANAF_FullCAN_cnt+1)>>1;
557  cnt2 = CANAF_std_cnt;
558  bound1 = ((CANAF_FullCAN_cnt+1)>>1)+((CANAF_std_cnt+1)>>1);
559  while (cnt1 < bound1)
560  {
561  /* Loop through standard existing IDs */
562  if ((LPC_CANAF_RAM->mask[cnt1] >> 16) > id)
563  {
564  cnt2 = cnt1 * 2;
565  break;
566  }
567 
568  if ((LPC_CANAF_RAM->mask[cnt1] & 0x0000FFFF) > id)
569  {
570  cnt2 = cnt1 * 2 + 1;
571  break;
572  }
573 
574  cnt1++;
575  }
576  /* cnt1 = U32 where to insert new ID */
577  /* cnt2 = U16 where to insert new ID */
578 
579  if (cnt1 == bound1)
580  {
581  /* Adding ID as last entry */
582  /* Even number of IDs exists */
583  if ((CANAF_std_cnt & 0x0001) == 0)
584  {
585  LPC_CANAF_RAM->mask[cnt1] = 0x0000FFFF | (id << 16);
586  }
587  /* Odd number of IDs exists */
588  else
589  {
590  LPC_CANAF_RAM->mask[cnt1] = (LPC_CANAF_RAM->mask[cnt1] & 0xFFFF0000) | id;
591  }
592  }
593  else
594  {
595  buf0 = LPC_CANAF_RAM->mask[cnt1]; /* Remember current entry */
596  if ((cnt2 & 0x0001) == 0)
597  {
598  /* Insert new mask to even address*/
599  buf1 = (id << 16) | (buf0 >> 16);
600  }
601  else
602  {
603  /* Insert new mask to odd address */
604  buf1 = (buf0 & 0xFFFF0000) | id;
605  }
606  LPC_CANAF_RAM->mask[cnt1] = buf1;/* Insert mask */
607  bound1 = ((CANAF_FullCAN_cnt+1)>>1)+((CANAF_std_cnt+1)>>1)-1;
608  /* Move all remaining standard mask entries one place up */
609  while (cnt1 < bound1)
610  {
611  cnt1++;
612  buf1 = LPC_CANAF_RAM->mask[cnt1];
613  LPC_CANAF_RAM->mask[cnt1] = (buf1 >> 16) | (buf0 << 16);
614  buf0 = buf1;
615  }
616 
617  if ((CANAF_std_cnt & 0x0001) == 0)
618  {
619  /* Even number of IDs exists */
620  LPC_CANAF_RAM->mask[cnt1+1] = (buf0 <<16) |(0x0000FFFF);
621  }
622  }
623  }
624  CANAF_std_cnt++;
625  //update address values
626  LPC_CANAF->SFF_GRP_sa +=0x04 ;
627  LPC_CANAF->EFF_sa +=0x04 ;
628  LPC_CANAF->EFF_GRP_sa +=0x04;
629  LPC_CANAF->ENDofTable +=0x04;
630  }
631 
632 /*********** Add Explicit Extended Identifier Frame Format entry *********/
633  else
634  {
635  /* Add controller number */
636  id |= (tmp0) << 29;
637 
638  cnt1 = ((CANAF_FullCAN_cnt+1)>>1)+(((CANAF_std_cnt + 1) >> 1) + CANAF_gstd_cnt);
639  cnt2 = 0;
640  while (cnt2 < CANAF_ext_cnt)
641  {
642  /* Loop through extended existing masks*/
643  if (LPC_CANAF_RAM->mask[cnt1] > id)
644  {
645  break;
646  }
647  cnt1++;/* cnt1 = U32 where to insert new mask */
648  cnt2++;
649  }
650 
651  buf0 = LPC_CANAF_RAM->mask[cnt1]; /* Remember current entry */
652  LPC_CANAF_RAM->mask[cnt1] = id; /* Insert mask */
653 
654  CANAF_ext_cnt++;
655 
656  bound1 = total;
657  /* Move all remaining extended mask entries one place up*/
658  while (cnt2 < bound1)
659  {
660  cnt1++;
661  cnt2++;
662  buf1 = LPC_CANAF_RAM->mask[cnt1];
663  LPC_CANAF_RAM->mask[cnt1] = buf0;
664  buf0 = buf1;
665  }
666  /* update address values */
667  LPC_CANAF->EFF_GRP_sa += 4;
668  LPC_CANAF->ENDofTable += 4;
669  }
670  if(CANAF_FullCAN_cnt == 0) //not use FullCAN mode
671  {
672  LPC_CANAF->AFMR = 0x00;//not use FullCAN mode
673  }
674  else
675  {
676  LPC_CANAF->AFMR = 0x04;
677  }
678 
679  return CAN_OK;
680 }
681 
682 /********************************************************************/
694 {
695  uint32_t ctrl0 = 0;
696  uint32_t buf0=0, buf1=0, buf2=0;
697  uint32_t tmp0=0, tmp1=0, tmp2=0;
698  int16_t cnt1=0, cnt2=0, bound1=0, total=0;
699 
700  CHECK_PARAM(PARAM_CANx(CANx));
701 
702  if (CANx == LPC_CAN1)
703  {
704  ctrl0 = 0;
705  }
706  else if (CANx == LPC_CAN2)
707  {
708  ctrl0 = 1;
709  }
710 
711  /* Acceptance Filter Memory full - return */
712  total =((CANAF_FullCAN_cnt+1)>>1)+ CANAF_FullCAN_cnt*3 +((CANAF_std_cnt + 1) >> 1)+ \
713  CANAF_gstd_cnt + CANAF_ext_cnt + (CANAF_gext_cnt<<1);
714  //don't have enough space for this fullCAN Entry and its Object(3*32 bytes)
715  if ((total >=508)||(CANAF_FullCAN_cnt>=64)){
716  return CAN_OBJECTS_FULL_ERROR;
717  }
718  /* Setup Acceptance Filter Configuration
719  Acceptance Filter Mode Register = Off */
720  LPC_CANAF->AFMR = 0x00000001;
721 
722  /* Add mask for standard identifiers */
723  id &= 0x07FF;
724  id |= (ctrl0 << 13) | (1 << 11); /* Add controller number */
725 // total = ((CANAF_std_cnt + 1) >> 1)+ CANAF_gstd_cnt + CANAF_ext_cnt + (CANAF_gext_cnt<<1);
726  /* Move all remaining sections one place up
727  if new entry will increase FullCAN list */
728  if (((CANAF_FullCAN_cnt & 0x0001) == 0)&&(total!=0))
729  {
730  //then remove remaining section
731  cnt1 = (CANAF_FullCAN_cnt >> 1);
732  bound1 = total;
733  buf0 = LPC_CANAF_RAM->mask[cnt1];
734 
735  while (bound1--)
736  {
737  cnt1++;
738  buf1 = LPC_CANAF_RAM->mask[cnt1];
739  LPC_CANAF_RAM->mask[cnt1] = buf0;
740  buf0 = buf1;
741  }
742  }
743  if (CANAF_FullCAN_cnt == 0)
744  {
745  /* For entering first ID */
746  LPC_CANAF_RAM->mask[0] = 0x0000FFFF | (id << 16);
747  }
748  else if (CANAF_FullCAN_cnt == 1)
749  {
750  /* For entering second ID */
751  if ((LPC_CANAF_RAM->mask[0] >> 16) > id)
752  {
753  LPC_CANAF_RAM->mask[0] = (LPC_CANAF_RAM->mask[0] >> 16) | (id << 16);
754  }
755  else
756  {
757  LPC_CANAF_RAM->mask[0] = (LPC_CANAF_RAM->mask[0] & 0xFFFF0000) | id;
758  }
759  }
760  else
761  {
762  /* Find where to insert new ID */
763  cnt1 = 0;
764  cnt2 = CANAF_FullCAN_cnt;
765  bound1 = (CANAF_FullCAN_cnt - 1) >> 1;
766  while (cnt1 <= bound1)
767  {
768  /* Loop through standard existing IDs */
769  if ((LPC_CANAF_RAM->mask[cnt1] >> 16) > id)
770  {
771  cnt2 = cnt1 * 2;
772  break;
773  }
774 
775  if ((LPC_CANAF_RAM->mask[cnt1] & 0x0000FFFF) > id)
776  {
777  cnt2 = cnt1 * 2 + 1;
778  break;
779  }
780 
781  cnt1++;
782  }
783  /* cnt1 = U32 where to insert new ID */
784  /* cnt2 = U16 where to insert new ID */
785 
786  if (cnt1 > bound1)
787  {
788  /* Adding ID as last entry */
789  /* Even number of IDs exists */
790  if ((CANAF_FullCAN_cnt & 0x0001) == 0)
791  {
792  LPC_CANAF_RAM->mask[cnt1] = 0x0000FFFF | (id << 16);
793  }
794  /* Odd number of IDs exists */
795  else
796  {
797  LPC_CANAF_RAM->mask[cnt1] = (LPC_CANAF_RAM->mask[cnt1] & 0xFFFF0000) | id;
798  }
799  }
800  else
801  {
802  buf0 = LPC_CANAF_RAM->mask[cnt1]; /* Remember current entry */
803  if ((cnt2 & 0x0001) == 0)
804  {
805  /* Insert new mask to even address*/
806  buf1 = (id << 16) | (buf0 >> 16);
807  }
808  else
809  {
810  /* Insert new mask to odd address */
811  buf1 = (buf0 & 0xFFFF0000) | id;
812  }
813  LPC_CANAF_RAM->mask[cnt1] = buf1;/* Insert mask */
814  bound1 = CANAF_FullCAN_cnt >> 1;
815  /* Move all remaining standard mask entries one place up */
816  while (cnt1 < bound1)
817  {
818  cnt1++;
819  buf1 = LPC_CANAF_RAM->mask[cnt1];
820  LPC_CANAF_RAM->mask[cnt1] = (buf1 >> 16) | (buf0 << 16);
821  buf0 = buf1;
822  }
823 
824  if ((CANAF_FullCAN_cnt & 0x0001) == 0)
825  {
826  /* Even number of IDs exists */
827  LPC_CANAF_RAM->mask[cnt1] = (LPC_CANAF_RAM->mask[cnt1] & 0xFFFF0000)
828  | (0x0000FFFF);
829  }
830  }
831  }
832  //restruct FulCAN Object Section
833  bound1 = CANAF_FullCAN_cnt - cnt2;
834  cnt1 = total - (CANAF_FullCAN_cnt)*3 + cnt2*3 + 1;
835  buf0 = LPC_CANAF_RAM->mask[cnt1];
836  buf1 = LPC_CANAF_RAM->mask[cnt1+1];
837  buf2 = LPC_CANAF_RAM->mask[cnt1+2];
838  LPC_CANAF_RAM->mask[cnt1]=LPC_CANAF_RAM->mask[cnt1+1]= LPC_CANAF_RAM->mask[cnt1+2]=0x00;
839  cnt1+=3;
840  while(bound1--)
841  {
842  tmp0 = LPC_CANAF_RAM->mask[cnt1];
843  tmp1 = LPC_CANAF_RAM->mask[cnt1+1];
844  tmp2 = LPC_CANAF_RAM->mask[cnt1+2];
845  LPC_CANAF_RAM->mask[cnt1]= buf0;
846  LPC_CANAF_RAM->mask[cnt1+1]= buf1;
847  LPC_CANAF_RAM->mask[cnt1+2]= buf2;
848  buf0 = tmp0;
849  buf1 = tmp1;
850  buf2 = tmp2;
851  cnt1+=3;
852  }
853  CANAF_FullCAN_cnt++;
854  //update address values
855  LPC_CANAF->SFF_sa +=0x04;
856  LPC_CANAF->SFF_GRP_sa +=0x04 ;
857  LPC_CANAF->EFF_sa +=0x04 ;
858  LPC_CANAF->EFF_GRP_sa +=0x04;
859  LPC_CANAF->ENDofTable +=0x04;
860 
861  LPC_CANAF->AFMR = 0x04;
862  return CAN_OK;
863 }
864 
865 /********************************************************************/
879 CAN_ERROR CAN_LoadGroupEntry(LPC_CAN_TypeDef* CANx, uint32_t lowerID, \
880  uint32_t upperID, CAN_ID_FORMAT_Type format)
881 {
882  uint16_t tmp = 0;
883  uint32_t buf0, buf1, entry1, entry2, LID,UID;
884  int16_t cnt1, bound1, total;
885 
886  CHECK_PARAM(PARAM_CANx(CANx));
887  CHECK_PARAM(PARAM_ID_FORMAT(format));
888 
889  if(lowerID > upperID) return CAN_CONFLICT_ID_ERROR;
890  if(CANx == LPC_CAN1)
891  {
892  tmp = 0;
893  }
894  else
895  {
896  tmp = 1;
897  }
898 
899  total =((CANAF_FullCAN_cnt+1)>>1)+ CANAF_FullCAN_cnt*3 +((CANAF_std_cnt + 1) >> 1)+ \
900  CANAF_gstd_cnt + CANAF_ext_cnt + (CANAF_gext_cnt<<1);
901 
902  /* Setup Acceptance Filter Configuration
903  Acceptance Filter Mode Register = Off */
904  LPC_CANAF->AFMR = 0x00000001;
905 
906 /*********Add Group of Standard Identifier Frame Format************/
907  if(format == STD_ID_FORMAT)
908  {
909  if ((total >= 512)){//don't have enough space
910  return CAN_OBJECTS_FULL_ERROR;
911  }
912  lowerID &=0x7FF; //mask ID
913  upperID &=0x7FF;
914  entry1 = (tmp << 29)|(lowerID << 16)|(tmp << 13)|(upperID << 0);
915  cnt1 = ((CANAF_FullCAN_cnt+1)>>1) + ((CANAF_std_cnt + 1) >> 1);
916 
917  //if this is the first Group standard ID entry
918  if(CANAF_gstd_cnt == 0)
919  {
920  LPC_CANAF_RAM->mask[cnt1] = entry1;
921  }
922  else
923  {
924  //find the position to add new Group entry
925  bound1 = ((CANAF_FullCAN_cnt+1)>>1) + ((CANAF_std_cnt + 1) >> 1) + CANAF_gstd_cnt;
926  while(cnt1 < bound1)
927  {
928  buf0 = LPC_CANAF_RAM->mask[cnt1];
929  LID = (buf0 >> 16)&0x7FF;
930  UID = buf0 & 0x7FF;
931  if (upperID <= LID)
932  {
933  //add new entry before this entry
934  LPC_CANAF_RAM->mask[cnt1] = entry1;
935  break;
936  }
937  else if (lowerID >= UID)
938  {
939  //load next entry to compare
940  cnt1 ++;
941  }
942  else
943  return CAN_CONFLICT_ID_ERROR;
944  }
945  if(cnt1 >= bound1)
946  {
947  //add new entry at the last position in this list
948  buf0 = LPC_CANAF_RAM->mask[cnt1];
949  LPC_CANAF_RAM->mask[cnt1] = entry1;
950  }
951 
952  //remove all remaining entry of this section one place up
953  bound1 = total - cnt1;
954  while(bound1--)
955  {
956  cnt1++;
957  buf1 = LPC_CANAF_RAM->mask[cnt1];
958  LPC_CANAF_RAM->mask[cnt1] = buf0;
959  buf0 = buf1;
960  }
961  }
962  CANAF_gstd_cnt++;
963  //update address values
964  LPC_CANAF->EFF_sa +=0x04 ;
965  LPC_CANAF->EFF_GRP_sa +=0x04;
966  LPC_CANAF->ENDofTable +=0x04;
967  }
968 
969 
970 /*********Add Group of Extended Identifier Frame Format************/
971  else
972  {
973  if ((total >= 511)){//don't have enough space
974  return CAN_OBJECTS_FULL_ERROR;
975  }
976  lowerID &= 0x1FFFFFFF; //mask ID
977  upperID &= 0x1FFFFFFF;
978  entry1 = (tmp << 29)|(lowerID << 0);
979  entry2 = (tmp << 29)|(upperID << 0);
980 
981  cnt1 = ((CANAF_FullCAN_cnt+1)>>1) + ((CANAF_std_cnt + 1) >> 1) + CANAF_gstd_cnt + CANAF_ext_cnt;
982  //if this is the first Group standard ID entry
983  if(CANAF_gext_cnt == 0)
984  {
985  LPC_CANAF_RAM->mask[cnt1] = entry1;
986  LPC_CANAF_RAM->mask[cnt1+1] = entry2;
987  }
988  else
989  {
990  //find the position to add new Group entry
991  bound1 = ((CANAF_FullCAN_cnt+1)>>1) + ((CANAF_std_cnt + 1) >> 1) + CANAF_gstd_cnt \
992  + CANAF_ext_cnt + (CANAF_gext_cnt<<1);
993  while(cnt1 < bound1)
994  {
995  buf0 = LPC_CANAF_RAM->mask[cnt1];
996  buf1 = LPC_CANAF_RAM->mask[cnt1+1];
997  LID = buf0 & 0x1FFFFFFF; //mask ID
998  UID = buf1 & 0x1FFFFFFF;
999  if (upperID <= LID)
1000  {
1001  //add new entry before this entry
1002  LPC_CANAF_RAM->mask[cnt1] = entry1;
1003  LPC_CANAF_RAM->mask[++cnt1] = entry2;
1004  break;
1005  }
1006  else if (lowerID >= UID)
1007  {
1008  //load next entry to compare
1009  cnt1 +=2;
1010  }
1011  else
1012  return CAN_CONFLICT_ID_ERROR;
1013  }
1014  if(cnt1 >= bound1)
1015  {
1016  //add new entry at the last position in this list
1017  buf0 = LPC_CANAF_RAM->mask[cnt1];
1018  buf1 = LPC_CANAF_RAM->mask[cnt1+1];
1019  LPC_CANAF_RAM->mask[cnt1] = entry1;
1020  LPC_CANAF_RAM->mask[++cnt1] = entry2;
1021  }
1022  //remove all remaining entry of this section two place up
1023  bound1 = total - cnt1 + 1;
1024  cnt1++;
1025  while(bound1>0)
1026  {
1027  entry1 = LPC_CANAF_RAM->mask[cnt1];
1028  entry2 = LPC_CANAF_RAM->mask[cnt1+1];
1029  LPC_CANAF_RAM->mask[cnt1] = buf0;
1030  LPC_CANAF_RAM->mask[cnt1+1] = buf1;
1031  buf0 = entry1;
1032  buf1 = entry2;
1033  cnt1 +=2;
1034  bound1 -=2;
1035  }
1036  }
1037  CANAF_gext_cnt++;
1038  //update address values
1039  LPC_CANAF->ENDofTable +=0x08;
1040  }
1041  LPC_CANAF->AFMR = 0x04;
1042  return CAN_OK;
1043 }
1044 
1045 /********************************************************************/
1059 CAN_ERROR CAN_RemoveEntry(AFLUT_ENTRY_Type EntryType, uint16_t position)
1060 {
1061  uint16_t cnt, bound, total;
1062  uint32_t buf0, buf1;
1063  CHECK_PARAM(PARAM_AFLUT_ENTRY_TYPE(EntryType));
1064  CHECK_PARAM(PARAM_POSITION(position));
1065 
1066  /* Setup Acceptance Filter Configuration
1067  Acceptance Filter Mode Register = Off */
1068  LPC_CANAF->AFMR = 0x00000001;
1069  total = ((CANAF_FullCAN_cnt+1)>>1)+((CANAF_std_cnt + 1) >> 1) + \
1070  CANAF_gstd_cnt + CANAF_ext_cnt + (CANAF_gext_cnt<<1);
1071 
1072 
1073 /************** Remove FullCAN Entry *************/
1074  if(EntryType == FULLCAN_ENTRY)
1075  {
1076  if((CANAF_FullCAN_cnt==0)||(position >= CANAF_FullCAN_cnt))
1077  {
1078  return CAN_ENTRY_NOT_EXIT_ERROR;
1079  }
1080  else
1081  {
1082  cnt = position >> 1;
1083  buf0 = LPC_CANAF_RAM->mask[cnt];
1084  bound = (CANAF_FullCAN_cnt - position -1)>>1;
1085  if((position & 0x0001) == 0) //event position
1086  {
1087  while(bound--)
1088  {
1089  //remove all remaining FullCAN entry one place down
1090  buf1 = LPC_CANAF_RAM->mask[cnt+1];
1091  LPC_CANAF_RAM->mask[cnt] = (buf1 >> 16) | (buf0 << 16);
1092  buf0 = buf1;
1093  cnt++;
1094  }
1095  }
1096  else //odd position
1097  {
1098  while(bound--)
1099  {
1100  //remove all remaining FullCAN entry one place down
1101  buf1 = LPC_CANAF_RAM->mask[cnt+1];
1102  LPC_CANAF_RAM->mask[cnt] = (buf0 & 0xFFFF0000)|(buf1 >> 16);
1103  LPC_CANAF_RAM->mask[cnt+1] = LPC_CANAF_RAM->mask[cnt+1] << 16;
1104  buf0 = buf1<<16;
1105  cnt++;
1106  }
1107  }
1108  if((CANAF_FullCAN_cnt & 0x0001) == 0)
1109  {
1110  if((position & 0x0001)==0)
1111  LPC_CANAF_RAM->mask[cnt] = (buf0 << 16) | (0x0000FFFF);
1112  else
1113  LPC_CANAF_RAM->mask[cnt] = buf0 | 0x0000FFFF;
1114  }
1115  else
1116  {
1117  //remove all remaining section one place down
1118  cnt = (CANAF_FullCAN_cnt + 1)>>1;
1119  bound = total + CANAF_FullCAN_cnt * 3;
1120  while(bound>cnt)
1121  {
1122  LPC_CANAF_RAM->mask[cnt-1] = LPC_CANAF_RAM->mask[cnt];
1123  cnt++;
1124  }
1125  LPC_CANAF_RAM->mask[cnt-1]=0x00;
1126  //update address values
1127  LPC_CANAF->SFF_sa -=0x04;
1128  LPC_CANAF->SFF_GRP_sa -=0x04 ;
1129  LPC_CANAF->EFF_sa -=0x04 ;
1130  LPC_CANAF->EFF_GRP_sa -=0x04;
1131  LPC_CANAF->ENDofTable -=0x04;
1132  }
1133  CANAF_FullCAN_cnt--;
1134 
1135  //delete its FullCAN Object in the FullCAN Object section
1136  //remove all remaining FullCAN Object three place down
1137  cnt = total + position * 3;
1138  bound = (CANAF_FullCAN_cnt - position + 1) * 3;
1139 
1140  while(bound)
1141  {
1142  LPC_CANAF_RAM->mask[cnt]=LPC_CANAF_RAM->mask[cnt+3];;
1143  LPC_CANAF_RAM->mask[cnt+1]=LPC_CANAF_RAM->mask[cnt+4];
1144  LPC_CANAF_RAM->mask[cnt+2]=LPC_CANAF_RAM->mask[cnt+5];
1145  bound -=3;
1146  cnt +=3;
1147  }
1148  }
1149  }
1150 
1151 /************** Remove Explicit Standard ID Entry *************/
1152  else if(EntryType == EXPLICIT_STANDARD_ENTRY)
1153  {
1154  if((CANAF_std_cnt==0)||(position >= CANAF_std_cnt))
1155  {
1156  return CAN_ENTRY_NOT_EXIT_ERROR;
1157  }
1158  else
1159  {
1160  cnt = ((CANAF_FullCAN_cnt+1)>>1)+ (position >> 1);
1161  buf0 = LPC_CANAF_RAM->mask[cnt];
1162  bound = (CANAF_std_cnt - position - 1)>>1;
1163  if((position & 0x0001) == 0) //event position
1164  {
1165  while(bound--)
1166  {
1167  //remove all remaining FullCAN entry one place down
1168  buf1 = LPC_CANAF_RAM->mask[cnt+1];
1169  LPC_CANAF_RAM->mask[cnt] = (buf1 >> 16) | (buf0 << 16);
1170  buf0 = buf1;
1171  cnt++;
1172  }
1173  }
1174  else //odd position
1175  {
1176  while(bound--)
1177  {
1178  //remove all remaining FullCAN entry one place down
1179  buf1 = LPC_CANAF_RAM->mask[cnt+1];
1180  LPC_CANAF_RAM->mask[cnt] = (buf0 & 0xFFFF0000)|(buf1 >> 16);
1181  LPC_CANAF_RAM->mask[cnt+1] = LPC_CANAF_RAM->mask[cnt+1] << 16;
1182  buf0 = buf1<<16;
1183  cnt++;
1184  }
1185  }
1186  if((CANAF_std_cnt & 0x0001) == 0)
1187  {
1188  if((position & 0x0001)==0)
1189  LPC_CANAF_RAM->mask[cnt] = (buf0 << 16) | (0x0000FFFF);
1190  else
1191  LPC_CANAF_RAM->mask[cnt] = buf0 | 0x0000FFFF;
1192  }
1193  else
1194  {
1195  //remove all remaining section one place down
1196  cnt = ((CANAF_FullCAN_cnt + 1)>>1) + ((CANAF_std_cnt + 1) >> 1);
1197  bound = total + CANAF_FullCAN_cnt * 3;
1198  while(bound>cnt)
1199  {
1200  LPC_CANAF_RAM->mask[cnt-1] = LPC_CANAF_RAM->mask[cnt];
1201  cnt++;
1202  }
1203  LPC_CANAF_RAM->mask[cnt-1]=0x00;
1204  //update address value
1205  LPC_CANAF->SFF_GRP_sa -=0x04 ;
1206  LPC_CANAF->EFF_sa -=0x04 ;
1207  LPC_CANAF->EFF_GRP_sa -=0x04;
1208  LPC_CANAF->ENDofTable -=0x04;
1209  }
1210  CANAF_std_cnt--;
1211  }
1212  }
1213 
1214 /************** Remove Group of Standard ID Entry *************/
1215  else if(EntryType == GROUP_STANDARD_ENTRY)
1216  {
1217  if((CANAF_gstd_cnt==0)||(position >= CANAF_gstd_cnt))
1218  {
1219  return CAN_ENTRY_NOT_EXIT_ERROR;
1220  }
1221  else
1222  {
1223  cnt = ((CANAF_FullCAN_cnt + 1)>>1) + ((CANAF_std_cnt + 1) >> 1)+ position + 1;
1224  bound = total + CANAF_FullCAN_cnt * 3;
1225  while (cnt<bound)
1226  {
1227  LPC_CANAF_RAM->mask[cnt-1] = LPC_CANAF_RAM->mask[cnt];
1228  cnt++;
1229  }
1230  LPC_CANAF_RAM->mask[cnt-1]=0x00;
1231  }
1232  CANAF_gstd_cnt--;
1233  //update address value
1234  LPC_CANAF->EFF_sa -=0x04;
1235  LPC_CANAF->EFF_GRP_sa -=0x04;
1236  LPC_CANAF->ENDofTable -=0x04;
1237  }
1238 
1239 /************** Remove Explicit Extended ID Entry *************/
1240  else if(EntryType == EXPLICIT_EXTEND_ENTRY)
1241  {
1242  if((CANAF_ext_cnt==0)||(position >= CANAF_ext_cnt))
1243  {
1244  return CAN_ENTRY_NOT_EXIT_ERROR;
1245  }
1246  else
1247  {
1248  cnt = ((CANAF_FullCAN_cnt + 1)>>1) + ((CANAF_std_cnt + 1) >> 1)+ CANAF_gstd_cnt + position + 1;
1249  bound = total + CANAF_FullCAN_cnt * 3;
1250  while (cnt<bound)
1251  {
1252  LPC_CANAF_RAM->mask[cnt-1] = LPC_CANAF_RAM->mask[cnt];
1253  cnt++;
1254  }
1255  LPC_CANAF_RAM->mask[cnt-1]=0x00;
1256  }
1257  CANAF_ext_cnt--;
1258  LPC_CANAF->EFF_GRP_sa -=0x04;
1259  LPC_CANAF->ENDofTable -=0x04;
1260  }
1261 
1262 /************** Remove Group of Extended ID Entry *************/
1263  else
1264  {
1265  if((CANAF_gext_cnt==0)||(position >= CANAF_gext_cnt))
1266  {
1267  return CAN_ENTRY_NOT_EXIT_ERROR;
1268  }
1269  else
1270  {
1271  cnt = total - (CANAF_gext_cnt<<1) + (position<<1);
1272  bound = total + CANAF_FullCAN_cnt * 3;
1273  while (cnt<bound)
1274  {
1275  //remove all remaining entry two place up
1276  LPC_CANAF_RAM->mask[cnt] = LPC_CANAF_RAM->mask[cnt+2];
1277  LPC_CANAF_RAM->mask[cnt+1] = LPC_CANAF_RAM->mask[cnt+3];
1278  cnt+=2;
1279  }
1280  }
1281  CANAF_gext_cnt--;
1282  LPC_CANAF->ENDofTable -=0x08;
1283  }
1284  LPC_CANAF->AFMR = 0x04;
1285  return CAN_OK;
1286 }
1287 
1288 /********************************************************************/
1300 {
1301  uint32_t data;
1302  CHECK_PARAM(PARAM_CANx(CANx));
1303  CHECK_PARAM(PARAM_ID_FORMAT(CAN_Msg->format));
1304  if(CAN_Msg->format==STD_ID_FORMAT)
1305  {
1306  CHECK_PARAM(PARAM_ID_11(CAN_Msg->id));
1307  }
1308  else
1309  {
1310  CHECK_PARAM(PARAM_ID_29(CAN_Msg->id));
1311  }
1312  CHECK_PARAM(PARAM_DLC(CAN_Msg->len));
1313  CHECK_PARAM(PARAM_FRAME_TYPE(CAN_Msg->type));
1314 
1315  //Check status of Transmit Buffer 1
1316  if ((CANx->SR & 0x00000004)>>2)
1317  {
1318  /* Transmit Channel 1 is available */
1319  /* Write frame informations and frame data into its CANxTFI1,
1320  * CANxTID1, CANxTDA1, CANxTDB1 register */
1321  CANx->TFI1 &= ~0x000F0000;
1322  CANx->TFI1 |= (CAN_Msg->len)<<16;
1323  if(CAN_Msg->type == REMOTE_FRAME)
1324  {
1325  CANx->TFI1 |= (1<<30); //set bit RTR
1326  }
1327  else
1328  {
1329  CANx->TFI1 &= ~(1<<30);
1330  }
1331  if(CAN_Msg->format == EXT_ID_FORMAT)
1332  {
1333  CANx->TFI1 |= (1<<31); //set bit FF
1334  }
1335  else
1336  {
1337  CANx->TFI1 &= ~(1<<31);
1338  }
1339 
1340  /* Write CAN ID*/
1341  CANx->TID1 = CAN_Msg->id;
1342 
1343  /*Write first 4 data bytes*/
1344  data = (CAN_Msg->dataA[0])|(((CAN_Msg->dataA[1]))<<8)|((CAN_Msg->dataA[2])<<16)|((CAN_Msg->dataA[3])<<24);
1345  CANx->TDA1 = data;
1346 
1347  /*Write second 4 data bytes*/
1348  data = (CAN_Msg->dataB[0])|(((CAN_Msg->dataB[1]))<<8)|((CAN_Msg->dataB[2])<<16)|((CAN_Msg->dataB[3])<<24);
1349  CANx->TDB1 = data;
1350 
1351  /*Write transmission request*/
1352  CANx->CMR = 0x21;
1353  return SUCCESS;
1354  }
1355  //check status of Transmit Buffer 2
1356  else if((CANx->SR & 0x00000004)>>10)
1357  {
1358  /* Transmit Channel 2 is available */
1359  /* Write frame informations and frame data into its CANxTFI2,
1360  * CANxTID2, CANxTDA2, CANxTDB2 register */
1361  CANx->TFI2 &= ~0x000F0000;
1362  CANx->TFI2 |= (CAN_Msg->len)<<16;
1363  if(CAN_Msg->type == REMOTE_FRAME)
1364  {
1365  CANx->TFI2 |= (1<<30); //set bit RTR
1366  }
1367  else
1368  {
1369  CANx->TFI2 &= ~(1<<30);
1370  }
1371  if(CAN_Msg->format == EXT_ID_FORMAT)
1372  {
1373  CANx->TFI2 |= (1<<31); //set bit FF
1374  }
1375  else
1376  {
1377  CANx->TFI2 &= ~(1<<31);
1378  }
1379 
1380  /* Write CAN ID*/
1381  CANx->TID2 = CAN_Msg->id;
1382 
1383  /*Write first 4 data bytes*/
1384  data = (CAN_Msg->dataA[0])|(((CAN_Msg->dataA[1]))<<8)|((CAN_Msg->dataA[2])<<16)|((CAN_Msg->dataA[3])<<24);
1385  CANx->TDA2 = data;
1386 
1387  /*Write second 4 data bytes*/
1388  data = (CAN_Msg->dataB[0])|(((CAN_Msg->dataB[1]))<<8)|((CAN_Msg->dataB[2])<<16)|((CAN_Msg->dataB[3])<<24);
1389  CANx->TDB2 = data;
1390 
1391  /*Write transmission request*/
1392  CANx->CMR = 0x41;
1393  return SUCCESS;
1394  }
1395  //check status of Transmit Buffer 3
1396  else if ((CANx->SR & 0x00000004)>>18)
1397  {
1398  /* Transmit Channel 3 is available */
1399  /* Write frame informations and frame data into its CANxTFI3,
1400  * CANxTID3, CANxTDA3, CANxTDB3 register */
1401  CANx->TFI3 &= ~0x000F0000;
1402  CANx->TFI3 |= (CAN_Msg->len)<<16;
1403  if(CAN_Msg->type == REMOTE_FRAME)
1404  {
1405  CANx->TFI3 |= (1<<30); //set bit RTR
1406  }
1407  else
1408  {
1409  CANx->TFI3 &= ~(1<<30);
1410  }
1411  if(CAN_Msg->format == EXT_ID_FORMAT)
1412  {
1413  CANx->TFI3 |= (1<<31); //set bit FF
1414  }
1415  else
1416  {
1417  CANx->TFI3 &= ~(1<<31);
1418  }
1419 
1420  /* Write CAN ID*/
1421  CANx->TID3 = CAN_Msg->id;
1422 
1423  /*Write first 4 data bytes*/
1424  data = (CAN_Msg->dataA[0])|(((CAN_Msg->dataA[1]))<<8)|((CAN_Msg->dataA[2])<<16)|((CAN_Msg->dataA[3])<<24);
1425  CANx->TDA3 = data;
1426 
1427  /*Write second 4 data bytes*/
1428  data = (CAN_Msg->dataB[0])|(((CAN_Msg->dataB[1]))<<8)|((CAN_Msg->dataB[2])<<16)|((CAN_Msg->dataB[3])<<24);
1429  CANx->TDB3 = data;
1430 
1431  /*Write transmission request*/
1432  CANx->CMR = 0x81;
1433  return SUCCESS;
1434  }
1435  else
1436  {
1437  return ERROR;
1438  }
1439 }
1440 
1441 /********************************************************************/
1453 {
1454  uint32_t data;
1455 
1456  CHECK_PARAM(PARAM_CANx(CANx));
1457 
1458  //check status of Receive Buffer
1459  if((CANx->SR &0x00000001))
1460  {
1461  /* Receive message is available */
1462  /* Read frame informations */
1463  CAN_Msg->format = (uint8_t)(((CANx->RFS) & 0x80000000)>>31);
1464  CAN_Msg->type = (uint8_t)(((CANx->RFS) & 0x40000000)>>30);
1465  CAN_Msg->len = (uint8_t)(((CANx->RFS) & 0x000F0000)>>16);
1466 
1467 
1468  /* Read CAN message identifier */
1469  CAN_Msg->id = CANx->RID;
1470 
1471  /* Read the data if received message was DATA FRAME */
1472  if (CAN_Msg->type == DATA_FRAME)
1473  {
1474  /* Read first 4 data bytes */
1475  data = CANx->RDA;
1476  *((uint8_t *) &CAN_Msg->dataA[0])= data & 0x000000FF;
1477  *((uint8_t *) &CAN_Msg->dataA[1])= (data & 0x0000FF00)>>8;;
1478  *((uint8_t *) &CAN_Msg->dataA[2])= (data & 0x00FF0000)>>16;
1479  *((uint8_t *) &CAN_Msg->dataA[3])= (data & 0xFF000000)>>24;
1480 
1481  /* Read second 4 data bytes */
1482  data = CANx->RDB;
1483  *((uint8_t *) &CAN_Msg->dataB[0])= data & 0x000000FF;
1484  *((uint8_t *) &CAN_Msg->dataB[1])= (data & 0x0000FF00)>>8;
1485  *((uint8_t *) &CAN_Msg->dataB[2])= (data & 0x00FF0000)>>16;
1486  *((uint8_t *) &CAN_Msg->dataB[3])= (data & 0xFF000000)>>24;
1487 
1488  /*release receive buffer*/
1489  CANx->CMR = 0x04;
1490  }
1491  else
1492  {
1493  /* Received Frame is a Remote Frame, not have data, we just receive
1494  * message information only */
1495  return SUCCESS;
1496  }
1497  }
1498  else
1499  {
1500  // no receive message available
1501  return ERROR;
1502  }
1503  return SUCCESS;
1504 }
1505 
1506 /********************************************************************/
1517 {
1518  uint32_t *pSrc, data;
1519  uint32_t interrut_word, msg_idx, test_bit, head_idx, tail_idx;
1520 
1521  CHECK_PARAM(PARAM_CANAFx(CANAFx));
1522 
1523  interrut_word = 0;
1524 
1525  if (LPC_CANAF->FCANIC0 != 0)
1526  {
1527  interrut_word = LPC_CANAF->FCANIC0;
1528  head_idx = 0;
1529  tail_idx = 31;
1530  }
1531  else if (LPC_CANAF->FCANIC1 != 0)
1532  {
1533  interrut_word = LPC_CANAF->FCANIC1;
1534  head_idx = 32;
1535  tail_idx = 63;
1536  }
1537 
1538  if (interrut_word != 0)
1539  {
1540  /* Detect for interrupt pending */
1541  msg_idx = 0;
1542  for (msg_idx = head_idx; msg_idx <= tail_idx; msg_idx++)
1543  {
1544  test_bit = interrut_word & 0x1;
1545  interrut_word = interrut_word >> 1;
1546 
1547  if (test_bit)
1548  {
1549  pSrc = (uint32_t *) (LPC_CANAF->ENDofTable + LPC_CANAF_RAM_BASE + msg_idx * 12);
1550 
1551  /* Has been finished updating the content */
1552  if ((*pSrc & 0x03000000L) == 0x03000000L)
1553  {
1554  /*clear semaphore*/
1555  *pSrc &= 0xFCFFFFFF;
1556 
1557  /*Set to DatA*/
1558  pSrc++;
1559  /* Copy to dest buf */
1560  data = *pSrc;
1561  *((uint8_t *) &CAN_Msg->dataA[0])= data & 0x000000FF;
1562  *((uint8_t *) &CAN_Msg->dataA[1])= (data & 0x0000FF00)>>8;
1563  *((uint8_t *) &CAN_Msg->dataA[2])= (data & 0x00FF0000)>>16;
1564  *((uint8_t *) &CAN_Msg->dataA[3])= (data & 0xFF000000)>>24;
1565 
1566  /*Set to DatB*/
1567  pSrc++;
1568  /* Copy to dest buf */
1569  data = *pSrc;
1570  *((uint8_t *) &CAN_Msg->dataB[0])= data & 0x000000FF;
1571  *((uint8_t *) &CAN_Msg->dataB[1])= (data & 0x0000FF00)>>8;
1572  *((uint8_t *) &CAN_Msg->dataB[2])= (data & 0x00FF0000)>>16;
1573  *((uint8_t *) &CAN_Msg->dataB[3])= (data & 0xFF000000)>>24;
1574  /*Back to Dat1*/
1575  pSrc -= 2;
1576 
1577  CAN_Msg->id = *pSrc & 0x7FF;
1578  CAN_Msg->len = (uint8_t) (*pSrc >> 16) & 0x0F;
1579  CAN_Msg->format = 0; //FullCAN Object ID always is 11-bit value
1580  CAN_Msg->type = (uint8_t)(*pSrc >> 30) &0x01;
1581  /*Re-read semaphore*/
1582  if ((*pSrc & 0x03000000L) == 0)
1583  {
1584  return CAN_OK;
1585  }
1586  }
1587  }
1588  }
1589  }
1590  return CAN_FULL_OBJ_NOT_RCV;
1591 }
1592 /********************************************************************/
1606 {
1607  CHECK_PARAM(PARAM_CANx(CANx));
1609 
1610  switch (arg)
1611  {
1612  case CANCTRL_GLOBAL_STS:
1613  return CANx->GSR;
1614 
1615  case CANCTRL_INT_CAP:
1616  return CANx->ICR;
1617 
1618  case CANCTRL_ERR_WRN:
1619  return CANx->EWL;
1620 
1621  default: // CANCTRL_STS
1622  return CANx->SR;
1623  }
1624 }
1625 /********************************************************************/
1635 uint32_t CAN_GetCRStatus (LPC_CANCR_TypeDef* CANCRx, CAN_CR_STS_Type arg)
1636 {
1637  CHECK_PARAM(PARAM_CANCRx(CANCRx));
1639 
1640  switch (arg)
1641  {
1642  case CANCR_TX_STS:
1643  return CANCRx->CANTxSR;
1644 
1645  case CANCR_RX_STS:
1646  return CANCRx->CANRxSR;
1647 
1648  default: // CANCR_MS
1649  return CANCRx->CANMSR;
1650  }
1651 }
1652 /********************************************************************/
1676 void CAN_IRQCmd (LPC_CAN_TypeDef* CANx, CAN_INT_EN_Type arg, FunctionalState NewState)
1677 {
1678  CHECK_PARAM(PARAM_CANx(CANx));
1681 
1682  if(NewState == ENABLE)
1683  {
1684  if(arg==CANINT_FCE)
1685  {
1686  LPC_CANAF->AFMR = 0x01;
1687  LPC_CANAF->FCANIE = 0x01;
1688  LPC_CANAF->AFMR = 0x04;
1689  }
1690  else
1691  CANx->IER |= (1 << arg);
1692  }
1693  else
1694  {
1695  if(arg==CANINT_FCE){
1696  LPC_CANAF->AFMR = 0x01;
1697  LPC_CANAF->FCANIE = 0x01;
1698  LPC_CANAF->AFMR = 0x00;
1699  }
1700  else
1701  CANx->IER &= ~(1 << arg);
1702  }
1703 }
1704 
1705 /********************************************************************/
1715 void CAN_SetAFMode (LPC_CANAF_TypeDef* CANAFx, CAN_AFMODE_Type AFMode)
1716 {
1717  CHECK_PARAM(PARAM_CANAFx(CANAFx));
1718  CHECK_PARAM(PARAM_AFMODE_TYPE(AFMode));
1719 
1720  switch(AFMode)
1721  {
1722  case CAN_Normal:
1723  CANAFx->AFMR = 0x00;
1724  break;
1725  case CAN_AccOff:
1726  CANAFx->AFMR = 0x01;
1727  break;
1728  case CAN_AccBP:
1729  CANAFx->AFMR = 0x02;
1730  break;
1731  case CAN_eFCAN:
1732  CANAFx->AFMR = 0x04;
1733  break;
1734  }
1735 }
1736 
1737 /********************************************************************/
1756 void CAN_ModeConfig(LPC_CAN_TypeDef* CANx, CAN_MODE_Type mode, FunctionalState NewState)
1757 {
1758  CHECK_PARAM(PARAM_CANx(CANx));
1761 
1762  switch(mode)
1763  {
1764  case CAN_OPERATING_MODE:
1765  CANx->MOD = 0x00;
1766  break;
1767  case CAN_RESET_MODE:
1768  if(NewState == ENABLE)
1769  CANx->MOD |=CAN_MOD_RM;
1770  else
1771  CANx->MOD &= ~CAN_MOD_RM;
1772  break;
1773  case CAN_LISTENONLY_MODE:
1774  CANx->MOD |=CAN_MOD_RM;//Enter Reset mode
1775  if(NewState == ENABLE)
1776  CANx->MOD |=CAN_MOD_LOM;
1777  else
1778  CANx->MOD &=~CAN_MOD_LOM;
1779  CANx->MOD &=~CAN_MOD_RM;//Release Reset mode
1780  break;
1781  case CAN_SELFTEST_MODE:
1782  CANx->MOD |=CAN_MOD_RM;//Enter Reset mode
1783  if(NewState == ENABLE)
1784  CANx->MOD |=CAN_MOD_STM;
1785  else
1786  CANx->MOD &=~CAN_MOD_STM;
1787  CANx->MOD &=~CAN_MOD_RM;//Release Reset mode
1788  break;
1789  case CAN_TXPRIORITY_MODE:
1790  if(NewState == ENABLE)
1791  CANx->MOD |=CAN_MOD_TPM;
1792  else
1793  CANx->MOD &=~CAN_MOD_TPM;
1794  break;
1795  case CAN_SLEEP_MODE:
1796  if(NewState == ENABLE)
1797  CANx->MOD |=CAN_MOD_SM;
1798  else
1799  CANx->MOD &=~CAN_MOD_SM;
1800  break;
1801  case CAN_RXPOLARITY_MODE:
1802  if(NewState == ENABLE)
1803  CANx->MOD |=CAN_MOD_RPM;
1804  else
1805  CANx->MOD &=~CAN_MOD_RPM;
1806  break;
1807  case CAN_TEST_MODE:
1808  if(NewState == ENABLE)
1809  CANx->MOD |=CAN_MOD_TM;
1810  else
1811  CANx->MOD &=~CAN_MOD_TM;
1812  break;
1813  }
1814 }
1815 /*********************************************************************/
1831 void CAN_SetCommand(LPC_CAN_TypeDef* CANx, uint32_t CMRType)
1832 {
1833  CHECK_PARAM(PARAM_CANx(CANx));
1834  CANx->CMR |= CMRType;
1835 }
1836 
1837 /*********************************************************************/
1844 uint32_t CAN_IntGetStatus(LPC_CAN_TypeDef* CANx)
1845 {
1846  CHECK_PARAM(PARAM_CANx(CANx));
1847  return CANx->ICR;
1848 }
1849 
1850 /*********************************************************************/
1858 {
1859  CHECK_PARAM( PARAM_CANAFx(CANAFx));
1860  if (CANAFx->FCANIE)
1861  return SET;
1862  return RESET;
1863 }
1864 
1865 /*********************************************************************/
1874 {
1875  CHECK_PARAM(PARAM_CANAFx(CANAFx));
1876  CHECK_PARAM( PARAM_FULLCAN_IC(type));
1877  if (type == FULLCAN_IC0)
1878  return CANAFx->FCANIC0;
1879  return CANAFx->FCANIC1;
1880 }
1881 /* End of Public Variables ---------------------------------------------------------- */
1886 #endif /* _CAN */
1887 
1892 /* --------------------------------- End Of File ------------------------------ */