Yoshi Mimura
/
CAN_MONITOR2
A very simple vehicle (Toyota Prius ZVW30) CAN message monitor program with CAN_id filtering.
Diff: main.cpp
- Revision:
- 0:1fc3bdb49371
--- /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