A very simple vehicle (Toyota Prius ZVW30) CAN message monitor program with CAN_id filtering.

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 // CAN_MONITOR with filtering  2012/03/21 ym1784
00002 
00003 #include "mbed.h"
00004 #include "CAN.h"
00005 
00006 Serial pc(USBTX, USBRX); // tx, rx
00007 DigitalOut led2(LED2);
00008 
00009 // CAN2 on mbed pins 29(CAN_TXD) and 30(CAN_RXD) using MCP2551.
00010 CAN can2(p30, p29);
00011 
00012 /*--------------------------------------------
00013   setup acceptance filter for CAN controller 2
00014   // original source http://www.dragonwake.com/download/LPC1768/Example/CAN/CAN.c
00015   original source http://www.dragonwake.com/download/LPC1768/Example.zip
00016   simplified for CAN2 interface and std id (11 bit) only
00017  *--------------------------------------------*/
00018 void CAN2_wrFilter (uint32_t id)  {
00019     static int CAN_std_cnt = 0;
00020     uint32_t buf0, buf1;
00021     int cnt1, cnt2, bound1;
00022 
00023     /* Acceptance Filter Memory full */
00024     if (((CAN_std_cnt + 1) >> 1) >= 512)
00025         return;                                       /* error: objects full */
00026 
00027     /* Setup Acceptance Filter Configuration
00028       Acceptance Filter Mode Register = Off  */
00029     LPC_CANAF->AFMR = 0x00000001;
00030 
00031     id |= 1 << 13;                        /* Add controller number(2) */
00032     id &= 0x0000F7FF;                            /* Mask out 16-bits of ID */
00033 
00034     if (CAN_std_cnt == 0)  {                     /* For entering first  ID */
00035         LPC_CANAF_RAM->mask[0] = 0x0000FFFF | (id << 16);
00036     }  else if (CAN_std_cnt == 1)  {             /* For entering second ID */
00037         if ((LPC_CANAF_RAM->mask[0] >> 16) > id)
00038             LPC_CANAF_RAM->mask[0] = (LPC_CANAF_RAM->mask[0] >> 16) | (id << 16);
00039         else
00040             LPC_CANAF_RAM->mask[0] = (LPC_CANAF_RAM->mask[0] & 0xFFFF0000) | id;
00041     }  else  {
00042         /* Find where to insert new ID */
00043         cnt1 = 0;
00044         cnt2 = CAN_std_cnt;
00045         bound1 = (CAN_std_cnt - 1) >> 1;
00046         while (cnt1 <= bound1)  {                  /* Loop through standard existing IDs */
00047             if ((LPC_CANAF_RAM->mask[cnt1] >> 16) > id)  {
00048                 cnt2 = cnt1 * 2;
00049                 break;
00050             }
00051             if ((LPC_CANAF_RAM->mask[cnt1] & 0x0000FFFF) > id)  {
00052                 cnt2 = cnt1 * 2 + 1;
00053                 break;
00054             }
00055             cnt1++;                                  /* cnt1 = U32 where to insert new ID */
00056         }                                          /* cnt2 = U16 where to insert new ID */
00057 
00058         if (cnt1 > bound1)  {                      /* Adding ID as last entry */
00059             if ((CAN_std_cnt & 0x0001) == 0)         /* Even number of IDs exists */
00060                 LPC_CANAF_RAM->mask[cnt1]  = 0x0000FFFF | (id << 16);
00061             else                                     /* Odd  number of IDs exists */
00062                 LPC_CANAF_RAM->mask[cnt1]  = (LPC_CANAF_RAM->mask[cnt1] & 0xFFFF0000) | id;
00063         }  else  {
00064             buf0 = LPC_CANAF_RAM->mask[cnt1];        /* Remember current entry */
00065             if ((cnt2 & 0x0001) == 0)                /* Insert new mask to even address */
00066                 buf1 = (id << 16) | (buf0 >> 16);
00067             else                                     /* Insert new mask to odd  address */
00068                 buf1 = (buf0 & 0xFFFF0000) | id;
00069 
00070             LPC_CANAF_RAM->mask[cnt1] = buf1;        /* Insert mask */
00071 
00072             bound1 = CAN_std_cnt >> 1;
00073             /* Move all remaining standard mask entries one place up */
00074             while (cnt1 < bound1)  {
00075                 cnt1++;
00076                 buf1  = LPC_CANAF_RAM->mask[cnt1];
00077                 LPC_CANAF_RAM->mask[cnt1] = (buf1 >> 16) | (buf0 << 16);
00078                 buf0  = buf1;
00079             }
00080 
00081             if ((CAN_std_cnt & 0x0001) == 0)         /* Even number of IDs exists */
00082                 LPC_CANAF_RAM->mask[cnt1] = (LPC_CANAF_RAM->mask[cnt1] & 0xFFFF0000) | (0x0000FFFF);
00083         }
00084     }
00085     CAN_std_cnt++;
00086 
00087     /* Calculate std ID start address (buf0) and ext ID start address <- none (buf1) */
00088     buf0 = ((CAN_std_cnt + 1) >> 1) << 2;
00089     buf1 = buf0;
00090 
00091     /* Setup acceptance filter pointers */
00092     LPC_CANAF->SFF_sa     = 0;
00093     LPC_CANAF->SFF_GRP_sa = buf0;
00094     LPC_CANAF->EFF_sa     = buf0;
00095     LPC_CANAF->EFF_GRP_sa = buf1;
00096     LPC_CANAF->ENDofTable = buf1;
00097 
00098     LPC_CANAF->AFMR = 0x00000000;                  /* Use acceptance filter */
00099 } // CAN2_wrFilter
00100 
00101 int main() {
00102     pc.baud(921600);
00103     pc.printf("CAN_MONITOR 921600 bps\r\n");
00104 
00105     // 500kbit/s
00106     can2.frequency(500000);
00107     CANMessage can_MsgRx;
00108 
00109     CAN2_wrFilter(0x0B4);
00110     CAN2_wrFilter(0x1C4);
00111     CAN2_wrFilter(0x245);
00112     CAN2_wrFilter(0x3D3);
00113     CAN2_wrFilter(0x498);
00114     CAN2_wrFilter(0x4A6);
00115 
00116     while (1) {
00117         // send received messages to the pc via serial line
00118         if (can2.read(can_MsgRx)) {
00119             pc.printf("t%03X%d", can_MsgRx.id, can_MsgRx.len);
00120             for (char i=0; i<can_MsgRx.len; i++) {
00121                 pc.printf("%02X", can_MsgRx.data[i]);
00122             } // for
00123             pc.printf("\r\n");
00124             // toggle led2
00125             led2 = !led2;
00126         } // if
00127     } // while
00128 } // main