LPCOpen Platform  v1.03
LPCOpen Platform for NXP LPC Microcontrollers
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
can.c
Go to the documentation of this file.
1 /*
2  * @brief CAN example
3  * This example show how to use CAN peripheral
4  *
5  * @note
6  * Copyright(C) NXP Semiconductors, 2012
7  * All rights reserved.
8  *
9  * @par
10  * Software that is described herein is for illustrative purposes only
11  * which provides customers with programming information regarding the
12  * LPC products. This software is supplied "AS IS" without any warranties of
13  * any kind, and NXP Semiconductors and its licensor disclaim any and
14  * all warranties, express or implied, including all implied warranties of
15  * merchantability, fitness for a particular purpose and non-infringement of
16  * intellectual property rights. NXP Semiconductors assumes no responsibility
17  * or liability for the use of the software, conveys no license or rights under any
18  * patent, copyright, mask work right, or any other intellectual property rights in
19  * or to any products. NXP Semiconductors reserves the right to make changes
20  * in the software without notification. NXP Semiconductors also makes no
21  * representation or warranty that such application will be suitable for the
22  * specified use without further testing or modification.
23  *
24  * @par
25  * Permission to use, copy, modify, and distribute this software and its
26  * documentation is hereby granted, under NXP Semiconductors' and its
27  * licensor's relevant copyrights in the software, without fee, provided that it
28  * is used in conjunction with NXP Semiconductors microcontrollers. This
29  * copyright, permission, and disclaimer notice must appear in all copies of
30  * this code.
31  */
32 #include "board.h"
33 
82 /*****************************************************************************
83  * Private types/enumerations/variables
84  ****************************************************************************/
85 #if defined(CHIP_LPC175X_6X)
86 #define CAN_CTRL_NO 1
87 #else
88 #define CAN_CTRL_NO 0
89 #endif
90 #if (CAN_CTRL_NO == 0)
91 #define LPC_CAN (LPC_CAN1)
92 #else
93 #define LPC_CAN (LPC_CAN2)
94 #endif
95 #define AF_LUT_USED 1
96 #if AF_LUT_USED
97 #define FULL_CAN_AF_USED 1
98 #endif
99 #define CAN_TX_MSG_STD_ID (0x200)
100 #define CAN_TX_MSG_REMOTE_STD_ID (0x300)
101 #define CAN_TX_MSG_EXT_ID (0x10000200)
102 #define CAN_RX_MSG_ID (0x100)
103 
104 /*****************************************************************************
105  * Public types/enumerations/variables
106  ****************************************************************************/
107 static char WelcomeMenu[] = "\n\rHello NXP Semiconductors \r\n"
108  "CAN DEMO : Use CAN to transmit and receive Message from CAN Analyzer\r\n"
109  "CAN bit rate : 500kBit/s\r\n";
110 
111 #if AF_LUT_USED
112 #if FULL_CAN_AF_USED
114  {CAN_CTRL_NO, 0, 0x03},
115  {CAN_CTRL_NO, 0, 0x05},
116  {CAN_CTRL_NO, 0, 0x07},
117  {CAN_CTRL_NO, 0, 0x09},
118 };
119 #endif
121  {CAN_CTRL_NO, 0, 0x30},
122  {CAN_CTRL_NO, 0, 0x50},
123  {CAN_CTRL_NO, 0, 0x70},
124  {CAN_CTRL_NO, 0, 0x90},
125  {CAN_CTRL_NO, 0, 0xB0},
126 };
128  {{CAN_CTRL_NO, 0, 0x300}, {CAN_CTRL_NO, 0, 0x400}},
129  {{CAN_CTRL_NO, 0, 0x500}, {CAN_CTRL_NO, 0, 0x600}},
130  {{CAN_CTRL_NO, 0, 0x700}, {CAN_CTRL_NO, 0, 0x780}},
131 };
133  {CAN_CTRL_NO, ((1 << 11) | 0x03)},
134  {CAN_CTRL_NO, ((1 << 11) | 0x05)},
135  {CAN_CTRL_NO, ((1 << 11) | 0x07)},
136  {CAN_CTRL_NO, ((1 << 11) | 0x09)},
137 };
139  {{CAN_CTRL_NO, ((1 << 11) | 0x300)}, {CAN_CTRL_NO, ((1 << 11) | 0x400)}},
140  {{CAN_CTRL_NO, ((1 << 11) | 0x500)}, {CAN_CTRL_NO, ((1 << 11) | 0x600)}},
141  {{CAN_CTRL_NO, ((1 << 11) | 0x700)}, {CAN_CTRL_NO, ((1 << 11) | 0x780)}},
142 };
144 #if FULL_CAN_AF_USED
146 #else
147  NULL, 0,
148 #endif
149  SFFSection, sizeof(SFFSection) / sizeof(CAN_STD_ID_ENTRY_T),
151  EFFSection, sizeof(EFFSection) / sizeof(CAN_EXT_ID_ENTRY_T),
153 };
154 #endif /*AF_LUT_USED*/
155 
156 /*****************************************************************************
157  * Private functions
158  ****************************************************************************/
159 /* Print error */
161 {
162  if (Status & CAN_ICR_EI) {
163  DEBUGOUT("Error Warning!\r\n");
164  }
165  if (Status & CAN_ICR_DOI) {
166  DEBUGOUT("Data Overrun!\r\n");
167  }
168  if (Status & CAN_ICR_EPI) {
169  DEBUGOUT("Error Passive!\r\n");
170  }
171  if (Status & CAN_ICR_ALI) {
172  DEBUGOUT("Arbitration lost in the bit: %d(th)\r\n", CAN_ICR_ALCBIT_VAL(Status));
173  }
174  if (Status & CAN_ICR_BEI) {
175 
176  DEBUGOUT("Bus error !!!\r\n");
177 
178  if (Status & CAN_ICR_ERRDIR_RECEIVE) {
179  DEBUGOUT("\t Error Direction: Transmiting\r\n");
180  }
181  else {
182  DEBUGOUT("\t Error Direction: Receiving\r\n");
183  }
184 
185  DEBUGOUT("\t Error Location: 0x%2x\r\n", CAN_ICR_ERRBIT_VAL(Status));
186  DEBUGOUT("\t Error Type: 0x%1x\r\n", CAN_ICR_ERRC_VAL(Status));
187  }
188 }
189 
190 /* Print CAN Message */
191 static void PrintCANMsg(CAN_MSG_T *pMsg)
192 {
193  uint8_t i;
194  DEBUGOUT("\t**************************\r\n");
195  DEBUGOUT("\tMessage Information: \r\n");
196  DEBUGOUT("\tMessage Type: ");
197  if (pMsg->ID & CAN_EXTEND_ID_USAGE) {
198  DEBUGOUT(" Extend ID Message");
199  }
200  else {
201  DEBUGOUT(" Standard ID Message");
202  }
203  if (pMsg->Type & CAN_REMOTE_MSG) {
204  DEBUGOUT(", Remote Message");
205  }
206  DEBUGOUT("\r\n");
207  DEBUGOUT("\tMessage ID :0x%x\r\n", (pMsg->ID & (~CAN_EXTEND_ID_USAGE)));
208  DEBUGOUT("\tMessage Data :");
209  for (i = 0; i < pMsg->DLC; i++)
210  DEBUGOUT("%x ", pMsg->Data[i]);
211  DEBUGOUT("\r\n\t**************************\r\n");
212 }
213 
214 /* Reply remote message received */
215 static void ReplyRemoteMessage(CAN_MSG_T *pRcvMsg)
216 {
217  CAN_MSG_T SendMsgBuf;
219  uint8_t i;
220  SendMsgBuf.ID = pRcvMsg->ID;
221  SendMsgBuf.DLC = pRcvMsg->DLC;
222  SendMsgBuf.Type = 0;
223  for (i = 0; i < pRcvMsg->DLC; i++)
224  SendMsgBuf.Data[i] = '0' + i;
226  Chip_CAN_Send(LPC_CAN, TxBuf, &SendMsgBuf);
227  DEBUGOUT("Message Replied!!!\r\n");
228  PrintCANMsg(&SendMsgBuf);
229 }
230 
231 /* Reply message received */
232 static void ReplyNormalMessage(CAN_MSG_T *pRcvMsg)
233 {
234  CAN_MSG_T SendMsgBuf = *pRcvMsg;
236  SendMsgBuf.ID = CAN_TX_MSG_STD_ID;
238  Chip_CAN_Send(LPC_CAN, TxBuf, &SendMsgBuf);
239  DEBUGOUT("Message Replied!!!\r\n");
240  PrintCANMsg(&SendMsgBuf);
241 }
242 
243 #if AF_LUT_USED
244 /* Print entries in AF LUT */
245 static void PrintAFLUT(void)
246 {
247  uint16_t i, num;
248  CAN_STD_ID_ENTRY_T StdEntry;
249  CAN_EXT_ID_ENTRY_T ExtEntry;
250  CAN_STD_ID_RANGE_ENTRY_T StdGrpEntry;
251  CAN_EXT_ID_RANGE_ENTRY_T ExtGrpEntry;
252 #if FULL_CAN_AF_USED
253  /* Full CAN Table */
254  DEBUGOUT("\tFULL CAN Table: \r\n");
256  for (i = 0; i < num; i++) {
257  Chip_CAN_ReadFullCANEntry(LPC_CANAF, i, &StdEntry);
258  DEBUGOUT("\t\t%d: Controller ID: %d, ID: 0x%x, Dis: %1d\r\n",
259  i, StdEntry.CtrlNo, StdEntry.ID_11, StdEntry.Disable);
260  }
261 #endif
262  /* Standard ID Table */
263  DEBUGOUT("\tIndividual Standard ID Table: \r\n");
265  for (i = 0; i < num; i++) {
267  DEBUGOUT("\t\t%d: Controller ID: %d, ID: 0x%x, Dis: %1d\r\n",
268  i, StdEntry.CtrlNo, StdEntry.ID_11, StdEntry.Disable);
269  }
270  /* Group Standard ID Table */
271  DEBUGOUT("\tGroup Standard ID Table: \r\n");
273  for (i = 0; i < num; i++) {
274  Chip_CAN_ReadGroupSTDEntry(LPC_CANAF, i, &StdGrpEntry);
275  DEBUGOUT("\t\t%d: Controller ID: %d, ID: 0x%x-0x%x, Dis: %1d\r\n",
276  i, StdGrpEntry.LowerID.CtrlNo, StdGrpEntry.LowerID.ID_11,
277  StdGrpEntry.UpperID.ID_11, StdGrpEntry.LowerID.Disable);
278  }
279  /* Extended ID Table */
280  DEBUGOUT("\tExtended ID Table: \r\n");
282  for (i = 0; i < num; i++) {
284  DEBUGOUT("\t\t%d: Controller ID: %d, ID: 0x%x,\r\n",
285  i, ExtEntry.CtrlNo, ExtEntry.ID_29);
286  }
287  /* Group Extended ID Table */
288  DEBUGOUT("\tGroup Extended ID Table: \r\n");
290  for (i = 0; i < num; i++) {
291  Chip_CAN_ReadGroupEXTEntry(LPC_CANAF, i, &ExtGrpEntry);
292  DEBUGOUT("\t\t%d: Controller ID: %d, ID: 0x%x-0x%x\r\n",
293  i, ExtGrpEntry.LowerID.CtrlNo, ExtGrpEntry.LowerID.ID_29,
294  ExtGrpEntry.UpperID.ID_29);
295  }
296 
297 }
298 
299 /* Setup AF LUT */
300 static void SetupAFLUT(void)
301 {
302  DEBUGOUT("Setup AF LUT... \r\n");
303  Chip_CAN_SetAFLUT(LPC_CANAF, &AFSections);
304  //PrintAFLUT();
305 }
306 
307 /* Insert/Remove entries to/from AF LUT */
308 static void ChangeAFLUT(void)
309 {
310 #if FULL_CAN_AF_USED
311  CAN_STD_ID_ENTRY_T FullEntry = {CAN_CTRL_NO, 0, 0x0A};
312 #endif
313  CAN_STD_ID_ENTRY_T StdEntry = {CAN_CTRL_NO, 0, 0xC0};
314  CAN_EXT_ID_ENTRY_T ExtEntry = {CAN_CTRL_NO, ((1 << 11) | 0x0A)};
315  CAN_STD_ID_RANGE_ENTRY_T StdGrpEntry = {{CAN_CTRL_NO, 0, 0x7A0}, {CAN_CTRL_NO, 0, 0x7B0}};
316  CAN_EXT_ID_RANGE_ENTRY_T ExtGrpEntry = {{CAN_CTRL_NO, ((1 << 11) | 0x7A0)}, {CAN_CTRL_NO, ((1 << 11) | 0x7B0)}};
317 
318  //DEBUGOUT("Insert new entries into the current LUT... \r\n");
319 #if FULL_CAN_AF_USED
320  /* Edit Full CAN Table */
322  FullEntry.ID_11 = 2;
324  FullEntry.ID_11 = 4;
326 #endif /*FULL_CAN_AF_USED*/
327 
328  /* Edit Individual STD ID Table */
330  StdEntry.ID_11 = 0x20;
332  StdEntry.ID_11 = 0x40;
334 
335  /* Edit Individual EXT ID Table */
337  ExtEntry.ID_29 = (1 << 11) | 0x02;
339  ExtEntry.ID_29 = (1 << 11) | 0x04;
341 
342  /* Edit STD ID Group Table */
344  StdGrpEntry.LowerID.ID_11 = 0x200;
345  StdGrpEntry.UpperID.ID_11 = 0x300;
347  StdGrpEntry.LowerID.ID_11 = 0x400;
348  StdGrpEntry.UpperID.ID_11 = 0x500;
350 
351  /* Edit EXT ID Group Table */
353  ExtGrpEntry.LowerID.ID_29 = (1 << 11) | 0x200;
354  ExtGrpEntry.UpperID.ID_29 = (1 << 11) | 0x300;
356  ExtGrpEntry.LowerID.ID_29 = (1 << 11) | 0x400;
357  ExtGrpEntry.UpperID.ID_29 = (1 << 11) | 0x500;
359 
360  //PrintAFLUT();
361 
362  //DEBUGOUT("Remove entries into the current LUT... \r\n");
363  /* Remove entries from the current LUT */
364 #if FULL_CAN_AF_USED
368 #endif
381  //PrintAFLUT();
382 }
383 
384 #endif
385 /*****************************************************************************
386  * Public functions
387  ****************************************************************************/
388 void CAN_IRQHandler(void)
389 {
390 #if FULL_CAN_AF_USED
391  uint16_t i = 0, FullCANEntryNum = 0;
392 #endif
394  CAN_MSG_T RcvMsgBuf;
395  IntStatus = Chip_CAN_GetIntStatus(LPC_CAN);
396 
397  PrintCANErrorInfo(IntStatus);
398 
399  /* New Message came */
400  if (IntStatus & CAN_ICR_RI) {
401  Chip_CAN_Receive(LPC_CAN, &RcvMsgBuf);
402  DEBUGOUT("Message Received!!!\r\n");
403  PrintCANMsg(&RcvMsgBuf);
404 
405  if (RcvMsgBuf.Type & CAN_REMOTE_MSG) {
406  ReplyRemoteMessage(&RcvMsgBuf);
407  }
408  else {
409  ReplyNormalMessage(&RcvMsgBuf);
410  }
411 
412  }
413 #if FULL_CAN_AF_USED
415  if (FullCANEntryNum > 64) {
416  FullCANEntryNum = 64;
417  }
418  for (i = 0; i < FullCANEntryNum; i++)
420  uint8_t SCC;
421  Chip_CAN_FullCANReceive(LPC_CANAF, i, &RcvMsgBuf, &SCC);
422  if (SCC == CAN_CTRL_NO) {
423  DEBUGOUT("FullCAN Message Received!!!\r\n");
424  PrintCANMsg(&RcvMsgBuf);
425  if (RcvMsgBuf.Type & CAN_REMOTE_MSG) {
426  ReplyRemoteMessage(&RcvMsgBuf);
427  }
428  else {
429  ReplyNormalMessage(&RcvMsgBuf);
430  }
431  }
432  }
433 
434 #endif /*FULL_CAN_AF_USED*/
435 }
436 
437 int main(void)
438 {
440  CAN_MSG_T SendMsgBuf;
441 
442  Board_Init();
445  Chip_CAN_SetBitRate(LPC_CAN, 500000);
447 
448 #if AF_LUT_USED
449  SetupAFLUT();
450  ChangeAFLUT();
451  PrintAFLUT();
452 #if FULL_CAN_AF_USED
455 #else
457 #endif /*FULL_CAN_AF_USED*/
458 #else
460 #endif /*AF_LUT_USED*/
461  NVIC_EnableIRQ(CAN_IRQn);
462 
463  SendMsgBuf.ID = CAN_TX_MSG_STD_ID;
464  SendMsgBuf.DLC = 4;
465  SendMsgBuf.Type = 0;
466  SendMsgBuf.Data[0] = 'A';
467  SendMsgBuf.Data[1] = 'B';
468  SendMsgBuf.Data[2] = 'C';
469  SendMsgBuf.Data[3] = 'D';
471  Chip_CAN_Send(LPC_CAN, TxBuf, &SendMsgBuf);
472  while ((Chip_CAN_GetStatus(LPC_CAN) & CAN_SR_TCS(TxBuf)) == 0) {}
473  DEBUGOUT("Message Sent!!!\r\n");
474  PrintCANMsg(&SendMsgBuf);
475 
476  SendMsgBuf.ID = CAN_TX_MSG_REMOTE_STD_ID;
477  SendMsgBuf.Type = CAN_REMOTE_MSG;
478  SendMsgBuf.DLC = 8;
480  Chip_CAN_Send(LPC_CAN, TxBuf, &SendMsgBuf);
481  while ((Chip_CAN_GetStatus(LPC_CAN) & CAN_SR_TCS(TxBuf)) == 0) {}
482  DEBUGOUT("Message Sent!!!\r\n");
483  PrintCANMsg(&SendMsgBuf);
484 
486  SendMsgBuf.Type = 0;
487  SendMsgBuf.Data[0] = 'E';
488  SendMsgBuf.Data[1] = 'F';
489  SendMsgBuf.Data[2] = 'G';
490  SendMsgBuf.Data[3] = 'H';
491  SendMsgBuf.Data[4] = 'I';
492  SendMsgBuf.Data[5] = 'J';
493  SendMsgBuf.Data[6] = 'K';
494  SendMsgBuf.Data[7] = 'L';
496  Chip_CAN_Send(LPC_CAN, TxBuf, &SendMsgBuf);
497  while ((Chip_CAN_GetStatus(LPC_CAN) & CAN_SR_TCS(TxBuf)) == 0) {}
498  DEBUGOUT("Message Sent!!!\r\n");
499  PrintCANMsg(&SendMsgBuf);
500  while (1) ;
501 }
502