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

Dependencies:   mbed

Committer:
ym1784
Date:
Fri Feb 13 23:20:16 2015 +0000
Revision:
0:1fc3bdb49371
add original source information

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ym1784 0:1fc3bdb49371 1 // CAN_MONITOR with filtering 2012/03/21 ym1784
ym1784 0:1fc3bdb49371 2
ym1784 0:1fc3bdb49371 3 #include "mbed.h"
ym1784 0:1fc3bdb49371 4 #include "CAN.h"
ym1784 0:1fc3bdb49371 5
ym1784 0:1fc3bdb49371 6 Serial pc(USBTX, USBRX); // tx, rx
ym1784 0:1fc3bdb49371 7 DigitalOut led2(LED2);
ym1784 0:1fc3bdb49371 8
ym1784 0:1fc3bdb49371 9 // CAN2 on mbed pins 29(CAN_TXD) and 30(CAN_RXD) using MCP2551.
ym1784 0:1fc3bdb49371 10 CAN can2(p30, p29);
ym1784 0:1fc3bdb49371 11
ym1784 0:1fc3bdb49371 12 /*--------------------------------------------
ym1784 0:1fc3bdb49371 13 setup acceptance filter for CAN controller 2
ym1784 0:1fc3bdb49371 14 // original source http://www.dragonwake.com/download/LPC1768/Example/CAN/CAN.c
ym1784 0:1fc3bdb49371 15 original source http://www.dragonwake.com/download/LPC1768/Example.zip
ym1784 0:1fc3bdb49371 16 simplified for CAN2 interface and std id (11 bit) only
ym1784 0:1fc3bdb49371 17 *--------------------------------------------*/
ym1784 0:1fc3bdb49371 18 void CAN2_wrFilter (uint32_t id) {
ym1784 0:1fc3bdb49371 19 static int CAN_std_cnt = 0;
ym1784 0:1fc3bdb49371 20 uint32_t buf0, buf1;
ym1784 0:1fc3bdb49371 21 int cnt1, cnt2, bound1;
ym1784 0:1fc3bdb49371 22
ym1784 0:1fc3bdb49371 23 /* Acceptance Filter Memory full */
ym1784 0:1fc3bdb49371 24 if (((CAN_std_cnt + 1) >> 1) >= 512)
ym1784 0:1fc3bdb49371 25 return; /* error: objects full */
ym1784 0:1fc3bdb49371 26
ym1784 0:1fc3bdb49371 27 /* Setup Acceptance Filter Configuration
ym1784 0:1fc3bdb49371 28 Acceptance Filter Mode Register = Off */
ym1784 0:1fc3bdb49371 29 LPC_CANAF->AFMR = 0x00000001;
ym1784 0:1fc3bdb49371 30
ym1784 0:1fc3bdb49371 31 id |= 1 << 13; /* Add controller number(2) */
ym1784 0:1fc3bdb49371 32 id &= 0x0000F7FF; /* Mask out 16-bits of ID */
ym1784 0:1fc3bdb49371 33
ym1784 0:1fc3bdb49371 34 if (CAN_std_cnt == 0) { /* For entering first ID */
ym1784 0:1fc3bdb49371 35 LPC_CANAF_RAM->mask[0] = 0x0000FFFF | (id << 16);
ym1784 0:1fc3bdb49371 36 } else if (CAN_std_cnt == 1) { /* For entering second ID */
ym1784 0:1fc3bdb49371 37 if ((LPC_CANAF_RAM->mask[0] >> 16) > id)
ym1784 0:1fc3bdb49371 38 LPC_CANAF_RAM->mask[0] = (LPC_CANAF_RAM->mask[0] >> 16) | (id << 16);
ym1784 0:1fc3bdb49371 39 else
ym1784 0:1fc3bdb49371 40 LPC_CANAF_RAM->mask[0] = (LPC_CANAF_RAM->mask[0] & 0xFFFF0000) | id;
ym1784 0:1fc3bdb49371 41 } else {
ym1784 0:1fc3bdb49371 42 /* Find where to insert new ID */
ym1784 0:1fc3bdb49371 43 cnt1 = 0;
ym1784 0:1fc3bdb49371 44 cnt2 = CAN_std_cnt;
ym1784 0:1fc3bdb49371 45 bound1 = (CAN_std_cnt - 1) >> 1;
ym1784 0:1fc3bdb49371 46 while (cnt1 <= bound1) { /* Loop through standard existing IDs */
ym1784 0:1fc3bdb49371 47 if ((LPC_CANAF_RAM->mask[cnt1] >> 16) > id) {
ym1784 0:1fc3bdb49371 48 cnt2 = cnt1 * 2;
ym1784 0:1fc3bdb49371 49 break;
ym1784 0:1fc3bdb49371 50 }
ym1784 0:1fc3bdb49371 51 if ((LPC_CANAF_RAM->mask[cnt1] & 0x0000FFFF) > id) {
ym1784 0:1fc3bdb49371 52 cnt2 = cnt1 * 2 + 1;
ym1784 0:1fc3bdb49371 53 break;
ym1784 0:1fc3bdb49371 54 }
ym1784 0:1fc3bdb49371 55 cnt1++; /* cnt1 = U32 where to insert new ID */
ym1784 0:1fc3bdb49371 56 } /* cnt2 = U16 where to insert new ID */
ym1784 0:1fc3bdb49371 57
ym1784 0:1fc3bdb49371 58 if (cnt1 > bound1) { /* Adding ID as last entry */
ym1784 0:1fc3bdb49371 59 if ((CAN_std_cnt & 0x0001) == 0) /* Even number of IDs exists */
ym1784 0:1fc3bdb49371 60 LPC_CANAF_RAM->mask[cnt1] = 0x0000FFFF | (id << 16);
ym1784 0:1fc3bdb49371 61 else /* Odd number of IDs exists */
ym1784 0:1fc3bdb49371 62 LPC_CANAF_RAM->mask[cnt1] = (LPC_CANAF_RAM->mask[cnt1] & 0xFFFF0000) | id;
ym1784 0:1fc3bdb49371 63 } else {
ym1784 0:1fc3bdb49371 64 buf0 = LPC_CANAF_RAM->mask[cnt1]; /* Remember current entry */
ym1784 0:1fc3bdb49371 65 if ((cnt2 & 0x0001) == 0) /* Insert new mask to even address */
ym1784 0:1fc3bdb49371 66 buf1 = (id << 16) | (buf0 >> 16);
ym1784 0:1fc3bdb49371 67 else /* Insert new mask to odd address */
ym1784 0:1fc3bdb49371 68 buf1 = (buf0 & 0xFFFF0000) | id;
ym1784 0:1fc3bdb49371 69
ym1784 0:1fc3bdb49371 70 LPC_CANAF_RAM->mask[cnt1] = buf1; /* Insert mask */
ym1784 0:1fc3bdb49371 71
ym1784 0:1fc3bdb49371 72 bound1 = CAN_std_cnt >> 1;
ym1784 0:1fc3bdb49371 73 /* Move all remaining standard mask entries one place up */
ym1784 0:1fc3bdb49371 74 while (cnt1 < bound1) {
ym1784 0:1fc3bdb49371 75 cnt1++;
ym1784 0:1fc3bdb49371 76 buf1 = LPC_CANAF_RAM->mask[cnt1];
ym1784 0:1fc3bdb49371 77 LPC_CANAF_RAM->mask[cnt1] = (buf1 >> 16) | (buf0 << 16);
ym1784 0:1fc3bdb49371 78 buf0 = buf1;
ym1784 0:1fc3bdb49371 79 }
ym1784 0:1fc3bdb49371 80
ym1784 0:1fc3bdb49371 81 if ((CAN_std_cnt & 0x0001) == 0) /* Even number of IDs exists */
ym1784 0:1fc3bdb49371 82 LPC_CANAF_RAM->mask[cnt1] = (LPC_CANAF_RAM->mask[cnt1] & 0xFFFF0000) | (0x0000FFFF);
ym1784 0:1fc3bdb49371 83 }
ym1784 0:1fc3bdb49371 84 }
ym1784 0:1fc3bdb49371 85 CAN_std_cnt++;
ym1784 0:1fc3bdb49371 86
ym1784 0:1fc3bdb49371 87 /* Calculate std ID start address (buf0) and ext ID start address <- none (buf1) */
ym1784 0:1fc3bdb49371 88 buf0 = ((CAN_std_cnt + 1) >> 1) << 2;
ym1784 0:1fc3bdb49371 89 buf1 = buf0;
ym1784 0:1fc3bdb49371 90
ym1784 0:1fc3bdb49371 91 /* Setup acceptance filter pointers */
ym1784 0:1fc3bdb49371 92 LPC_CANAF->SFF_sa = 0;
ym1784 0:1fc3bdb49371 93 LPC_CANAF->SFF_GRP_sa = buf0;
ym1784 0:1fc3bdb49371 94 LPC_CANAF->EFF_sa = buf0;
ym1784 0:1fc3bdb49371 95 LPC_CANAF->EFF_GRP_sa = buf1;
ym1784 0:1fc3bdb49371 96 LPC_CANAF->ENDofTable = buf1;
ym1784 0:1fc3bdb49371 97
ym1784 0:1fc3bdb49371 98 LPC_CANAF->AFMR = 0x00000000; /* Use acceptance filter */
ym1784 0:1fc3bdb49371 99 } // CAN2_wrFilter
ym1784 0:1fc3bdb49371 100
ym1784 0:1fc3bdb49371 101 int main() {
ym1784 0:1fc3bdb49371 102 pc.baud(921600);
ym1784 0:1fc3bdb49371 103 pc.printf("CAN_MONITOR 921600 bps\r\n");
ym1784 0:1fc3bdb49371 104
ym1784 0:1fc3bdb49371 105 // 500kbit/s
ym1784 0:1fc3bdb49371 106 can2.frequency(500000);
ym1784 0:1fc3bdb49371 107 CANMessage can_MsgRx;
ym1784 0:1fc3bdb49371 108
ym1784 0:1fc3bdb49371 109 CAN2_wrFilter(0x0B4);
ym1784 0:1fc3bdb49371 110 CAN2_wrFilter(0x1C4);
ym1784 0:1fc3bdb49371 111 CAN2_wrFilter(0x245);
ym1784 0:1fc3bdb49371 112 CAN2_wrFilter(0x3D3);
ym1784 0:1fc3bdb49371 113 CAN2_wrFilter(0x498);
ym1784 0:1fc3bdb49371 114 CAN2_wrFilter(0x4A6);
ym1784 0:1fc3bdb49371 115
ym1784 0:1fc3bdb49371 116 while (1) {
ym1784 0:1fc3bdb49371 117 // send received messages to the pc via serial line
ym1784 0:1fc3bdb49371 118 if (can2.read(can_MsgRx)) {
ym1784 0:1fc3bdb49371 119 pc.printf("t%03X%d", can_MsgRx.id, can_MsgRx.len);
ym1784 0:1fc3bdb49371 120 for (char i=0; i<can_MsgRx.len; i++) {
ym1784 0:1fc3bdb49371 121 pc.printf("%02X", can_MsgRx.data[i]);
ym1784 0:1fc3bdb49371 122 } // for
ym1784 0:1fc3bdb49371 123 pc.printf("\r\n");
ym1784 0:1fc3bdb49371 124 // toggle led2
ym1784 0:1fc3bdb49371 125 led2 = !led2;
ym1784 0:1fc3bdb49371 126 } // if
ym1784 0:1fc3bdb49371 127 } // while
ym1784 0:1fc3bdb49371 128 } // main