
A very simple vehicle (Toyota Prius ZVW30) CAN message monitor program with CAN_id filtering.
main.cpp@0:1fc3bdb49371, 2015-02-13 (annotated)
- Committer:
- ym1784
- Date:
- Fri Feb 13 23:20:16 2015 +0000
- Revision:
- 0:1fc3bdb49371
add original source information
Who changed what in which revision?
User | Revision | Line number | New 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 |