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

Dependencies:   mbed

Files at this revision

API Documentation at this revision

Comitter:
ym1784
Date:
Fri Feb 13 23:20:16 2015 +0000
Commit message:
add original source information

Changed in this revision

main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Fri Feb 13 23:20:16 2015 +0000
@@ -0,0 +1,128 @@
+// CAN_MONITOR with filtering  2012/03/21 ym1784
+
+#include "mbed.h"
+#include "CAN.h"
+
+Serial pc(USBTX, USBRX); // tx, rx
+DigitalOut led2(LED2);
+
+// CAN2 on mbed pins 29(CAN_TXD) and 30(CAN_RXD) using MCP2551.
+CAN can2(p30, p29);
+
+/*--------------------------------------------
+  setup acceptance filter for CAN controller 2
+  // original source http://www.dragonwake.com/download/LPC1768/Example/CAN/CAN.c
+  original source http://www.dragonwake.com/download/LPC1768/Example.zip
+  simplified for CAN2 interface and std id (11 bit) only
+ *--------------------------------------------*/
+void CAN2_wrFilter (uint32_t id)  {
+    static int CAN_std_cnt = 0;
+    uint32_t buf0, buf1;
+    int cnt1, cnt2, bound1;
+
+    /* Acceptance Filter Memory full */
+    if (((CAN_std_cnt + 1) >> 1) >= 512)
+        return;                                       /* error: objects full */
+
+    /* Setup Acceptance Filter Configuration
+      Acceptance Filter Mode Register = Off  */
+    LPC_CANAF->AFMR = 0x00000001;
+
+    id |= 1 << 13;                        /* Add controller number(2) */
+    id &= 0x0000F7FF;                            /* Mask out 16-bits of ID */
+
+    if (CAN_std_cnt == 0)  {                     /* For entering first  ID */
+        LPC_CANAF_RAM->mask[0] = 0x0000FFFF | (id << 16);
+    }  else if (CAN_std_cnt == 1)  {             /* For entering second ID */
+        if ((LPC_CANAF_RAM->mask[0] >> 16) > id)
+            LPC_CANAF_RAM->mask[0] = (LPC_CANAF_RAM->mask[0] >> 16) | (id << 16);
+        else
+            LPC_CANAF_RAM->mask[0] = (LPC_CANAF_RAM->mask[0] & 0xFFFF0000) | id;
+    }  else  {
+        /* Find where to insert new ID */
+        cnt1 = 0;
+        cnt2 = CAN_std_cnt;
+        bound1 = (CAN_std_cnt - 1) >> 1;
+        while (cnt1 <= bound1)  {                  /* Loop through standard existing IDs */
+            if ((LPC_CANAF_RAM->mask[cnt1] >> 16) > id)  {
+                cnt2 = cnt1 * 2;
+                break;
+            }
+            if ((LPC_CANAF_RAM->mask[cnt1] & 0x0000FFFF) > id)  {
+                cnt2 = cnt1 * 2 + 1;
+                break;
+            }
+            cnt1++;                                  /* cnt1 = U32 where to insert new ID */
+        }                                          /* cnt2 = U16 where to insert new ID */
+
+        if (cnt1 > bound1)  {                      /* Adding ID as last entry */
+            if ((CAN_std_cnt & 0x0001) == 0)         /* Even number of IDs exists */
+                LPC_CANAF_RAM->mask[cnt1]  = 0x0000FFFF | (id << 16);
+            else                                     /* Odd  number of IDs exists */
+                LPC_CANAF_RAM->mask[cnt1]  = (LPC_CANAF_RAM->mask[cnt1] & 0xFFFF0000) | id;
+        }  else  {
+            buf0 = LPC_CANAF_RAM->mask[cnt1];        /* Remember current entry */
+            if ((cnt2 & 0x0001) == 0)                /* Insert new mask to even address */
+                buf1 = (id << 16) | (buf0 >> 16);
+            else                                     /* Insert new mask to odd  address */
+                buf1 = (buf0 & 0xFFFF0000) | id;
+
+            LPC_CANAF_RAM->mask[cnt1] = buf1;        /* Insert mask */
+
+            bound1 = CAN_std_cnt >> 1;
+            /* Move all remaining standard mask entries one place up */
+            while (cnt1 < bound1)  {
+                cnt1++;
+                buf1  = LPC_CANAF_RAM->mask[cnt1];
+                LPC_CANAF_RAM->mask[cnt1] = (buf1 >> 16) | (buf0 << 16);
+                buf0  = buf1;
+            }
+
+            if ((CAN_std_cnt & 0x0001) == 0)         /* Even number of IDs exists */
+                LPC_CANAF_RAM->mask[cnt1] = (LPC_CANAF_RAM->mask[cnt1] & 0xFFFF0000) | (0x0000FFFF);
+        }
+    }
+    CAN_std_cnt++;
+
+    /* Calculate std ID start address (buf0) and ext ID start address <- none (buf1) */
+    buf0 = ((CAN_std_cnt + 1) >> 1) << 2;
+    buf1 = buf0;
+
+    /* Setup acceptance filter pointers */
+    LPC_CANAF->SFF_sa     = 0;
+    LPC_CANAF->SFF_GRP_sa = buf0;
+    LPC_CANAF->EFF_sa     = buf0;
+    LPC_CANAF->EFF_GRP_sa = buf1;
+    LPC_CANAF->ENDofTable = buf1;
+
+    LPC_CANAF->AFMR = 0x00000000;                  /* Use acceptance filter */
+} // CAN2_wrFilter
+
+int main() {
+    pc.baud(921600);
+    pc.printf("CAN_MONITOR 921600 bps\r\n");
+
+    // 500kbit/s
+    can2.frequency(500000);
+    CANMessage can_MsgRx;
+
+    CAN2_wrFilter(0x0B4);
+    CAN2_wrFilter(0x1C4);
+    CAN2_wrFilter(0x245);
+    CAN2_wrFilter(0x3D3);
+    CAN2_wrFilter(0x498);
+    CAN2_wrFilter(0x4A6);
+
+    while (1) {
+        // send received messages to the pc via serial line
+        if (can2.read(can_MsgRx)) {
+            pc.printf("t%03X%d", can_MsgRx.id, can_MsgRx.len);
+            for (char i=0; i<can_MsgRx.len; i++) {
+                pc.printf("%02X", can_MsgRx.data[i]);
+            } // for
+            pc.printf("\r\n");
+            // toggle led2
+            led2 = !led2;
+        } // if
+    } // while
+} // main
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Fri Feb 13 23:20:16 2015 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/e188a91d3eaa
\ No newline at end of file