//=========================================================================== // READER THREAD //=========================================================================== void can0_thread(cyg_addrword_t data) { cyg_uint32 len; cyg_can_event rx_event; cyg_can_remote_buf rtr_buf; cyg_can_remote_buf rtr_buf2; cyg_can_msgbuf_info msgbox_info; cyg_can_mode mode; cyg_can_state state; // // before we start configuring the CAN hardware we stop the chip // mode = CYGNUM_CAN_MODE_STOP; len = sizeof(mode); if (ENOERR != cyg_io_set_config(hDrvFlexCAN, CYG_IO_SET_CONFIG_CAN_MODE ,&mode, &len)) { CYG_TEST_FAIL_FINISH("Error writing config of /dev/can0"); } // // now check if FlexCAN modul is really stopped // len = sizeof(state); if (ENOERR != cyg_io_get_config(hDrvFlexCAN, CYG_IO_GET_CONFIG_CAN_STATE ,&state, &len)) { CYG_TEST_FAIL_FINISH("Error reading config of /dev/can0"); } if (state != CYGNUM_CAN_STATE_STOPPED) { CYG_TEST_FAIL_FINISH("Error stopping FlexCAN /dev/can0"); } // // We would like to setup 2 remote buffers - check if we have enough // free message buffers // len = sizeof(msgbox_info); if (ENOERR != cyg_io_get_config(hDrvFlexCAN, CYG_IO_GET_CONFIG_CAN_MSGBUF_INFO ,&msgbox_info, &len)) { CYG_TEST_FAIL_FINISH("Error reading config of /dev/can0"); } else { diag_printf("Message boxes available: %d free: %d\n", msgbox_info.count, msgbox_info.free); } if (msgbox_info.free < 2) { CYG_TEST_FAIL_FINISH("Not enough free message buffers/dev/can0"); } // // Setup the first remote response buffer for resception of standard // remote frames // rtr_buf.cfg_id = CYGNUM_CAN_MSGBUF_REMOTE_BUF_ADD; rtr_buf.msg.id = 0x7FF; rtr_buf.msg.ext = CYGNUM_CAN_ID_STD; rtr_buf.msg.rtr = CYGNUM_CAN_FRAME_DATA; rtr_buf.msg.dlc = 1; rtr_buf.msg.data[0] = 0xAB; len = sizeof(rtr_buf); if (ENOERR != cyg_io_set_config(hDrvFlexCAN, CYG_IO_SET_CONFIG_CAN_MSGBUF ,&rtr_buf, &len)) { CYG_TEST_FAIL_FINISH("Error writing config of /dev/can0"); } // // setup the second remote response buffer for reception of extended // remote frames // rtr_buf2.cfg_id = CYGNUM_CAN_MSGBUF_REMOTE_BUF_ADD; rtr_buf2.msg.id = 0x800; rtr_buf2.msg.ext = CYGNUM_CAN_ID_EXT; rtr_buf2.msg.rtr = CYGNUM_CAN_FRAME_DATA; rtr_buf2.msg.dlc = 4; rtr_buf2.msg.data[0] = 0xAB; len = sizeof(rtr_buf2); if (ENOERR != cyg_io_set_config(hDrvFlexCAN, CYG_IO_SET_CONFIG_CAN_MSGBUF ,&rtr_buf2, &len)) { CYG_TEST_FAIL_FINISH("Error writing config of /dev/can0"); } if (rtr_buf.handle == CYGNUM_CAN_MSGBUF_NA) { CYG_TEST_FAIL_FINISH("No free message buffer available for /dev/can0"); } // // now configuration is finished and we can start chip again // mode = CYGNUM_CAN_MODE_START; len = sizeof(mode); if (ENOERR != cyg_io_set_config(hDrvFlexCAN, CYG_IO_SET_CONFIG_CAN_MODE ,&mode, &len)) { CYG_TEST_FAIL_FINISH("Error writing config of /dev/can0"); } diag_printf("Test of FlexCAN remote response buffer configuration\n" "If a CAN node sends a remote request with ID 0x7FF\n" "or 0x800 then the FlexCAN modul should respond with\n" "data frames.\n"); diag_printf("!!! This test can be stopped by sending a data frame with ID 0x100 !!!\n\n"); len = sizeof(msgbox_info); if (ENOERR != cyg_io_get_config(hDrvFlexCAN, CYG_IO_GET_CONFIG_CAN_MSGBUF_INFO ,&msgbox_info, &len)) { CYG_TEST_FAIL_FINISH("Error writing config of /dev/can0"); } else { diag_printf("Message boxes available: %d free: %d\n", msgbox_info.count, msgbox_info.free); } while (1) { len = sizeof(rx_event); if (ENOERR != cyg_io_read(hDrvFlexCAN, &rx_event, &len)) { CYG_TEST_FAIL_FINISH("Error reading from /dev/can0"); } if (0x100 == rx_event.msg.id) { CYG_TEST_PASS_FINISH("flexcan_remote test OK"); } else { print_can_flags(rx_event.flags, ""); print_can_msg(&rx_event.msg, ""); } } }
//=========================================================================== // WRITER THREAD //=========================================================================== void can0_thread(cyg_addrword_t data) { cyg_io_handle_t hCAN0; cyg_uint32 len; cyg_can_buf_info_t buf_info; cyg_uint16 i; cyg_can_event rx_event; cyg_can_message tx_msg = { 0x000, // CAN identifier {0x00, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7}, // 8 data bytes CYGNUM_CAN_ID_STD, // standard frame CYGNUM_CAN_FRAME_DATA, // data frame 4, // data length code }; if (ENOERR != cyg_io_lookup("/dev/can0", &hCAN0)) { CYG_TEST_FAIL_FINISH("Error opening /dev/can0"); } // // first we read the buffer info // len = sizeof(buf_info); if (ENOERR != cyg_io_get_config(hCAN0, CYG_IO_GET_CONFIG_CAN_BUFFER_INFO ,&buf_info, &len)) { CYG_TEST_FAIL_FINISH("Error reading config of /dev/can0"); } // // check if buffer is really empty // if (buf_info.rx_count != 0) { CYG_TEST_FAIL_FINISH("Receive buffer of /dev/can0 is not empty."); } // // now send messages - because TX events are supported each transmitted CAN message // will cause a TX event that is filled into receive queue // diag_printf("Sending %d CAN messages to /dev/can0 \n", buf_info.rx_bufsize); for (i = 0; i < buf_info.rx_bufsize; ++i) { tx_msg.id = i; tx_msg.data[0] = i; len = sizeof(tx_msg); if (ENOERR != cyg_io_write(hCAN0, &tx_msg, &len)) { CYG_TEST_FAIL_FINISH("Error writing to /dev/can0"); } else { print_can_msg(&tx_msg, ""); } } // // now we read the buffer info - we expect a completely filled recieve queue // len = sizeof(buf_info); if (ENOERR != cyg_io_get_config(hCAN0, CYG_IO_GET_CONFIG_CAN_BUFFER_INFO ,&buf_info, &len)) { CYG_TEST_FAIL_FINISH("Error reading config of /dev/can0"); } // // if receive queue is not completely filled, then we have an error here // if (buf_info.rx_bufsize != buf_info.rx_count) { diag_printf("RX bufsize: %d events in RX buffer: %d\n", buf_info.rx_bufsize, buf_info.rx_count); CYG_TEST_FAIL_FINISH("Receive queue of /dev/can0 not completely filled."); } // // now we read the receive queue // diag_printf("Receiving %d TX events from /dev/can0 \n", buf_info.rx_count); for (i = 0; i < buf_info.rx_count; ++i) { len = sizeof(rx_event); if (ENOERR != cyg_io_read(hCAN0, &rx_event, &len)) { CYG_TEST_FAIL_FINISH("Error reading from /dev/can0"); } // // we expect only a set TX flag because no other events may arrive for the // loopback driver // if (!(rx_event.flags & CYGNUM_CAN_EVENT_TX) || (rx_event.flags & !CYGNUM_CAN_EVENT_TX)) { CYG_TEST_FAIL_FINISH("Unexpected receive event flags."); } // // Now check if TX events contain valid data - we know that the ID and the first // data byte contain the message number // if ((rx_event.msg.id != i) || (rx_event.msg.data[0] != i)) { CYG_TEST_FAIL_FINISH("Received invalid data in TX event"); } else { print_can_msg(&rx_event.msg, ""); } } // for (i = 0; i < buf_info.rx_count; ++i) CYG_TEST_PASS_FINISH("can_txevent test OK"); }
//=========================================================================== // READER THREAD //=========================================================================== void can_thread(cyg_addrword_t data) { cyg_uint32 len; cyg_uint8 i = 0; // // Check that all cannels have the same baudrate // #ifdef CYGPKG_DEVS_CAN_LPC2XXX_CAN0 can_setup_channel(hCAN_Tbl[0], 0); #endif #ifdef CYGPKG_DEVS_CAN_LPC2XXX_CAN1 can_setup_channel(hCAN_Tbl[1], 1); #endif #ifdef CYGPKG_DEVS_CAN_LPC2XXX_CAN2 can_setup_channel(hCAN_Tbl[2], 2); #endif #ifdef CYGPKG_DEVS_CAN_LPC2XXX_CAN3 can_setup_channel(hCAN_Tbl[3], 3); #endif diag_printf("\n\nThis test uses all available CAN channels for reception\n" "of CAN standard messages. The following messages will be received:\n\n"); for (i = 0; i < 4; ++i) { if (hCAN_Tbl[i]) { diag_printf("CAN channel %d: msg: 0x%03x - 0x%03x\n", i, i * 0x100, i * 0x100 + 9); } } diag_printf("\n\nYou can stop this test by sending a message with ID 0xX09\n"); while (1) { for (i = 0; i < 4; ++i) { if (hCAN_Tbl[i]) { Cyg_ErrNo ret; cyg_can_event rx_event; len = sizeof(rx_event); ret = cyg_io_read(hCAN_Tbl[i], &rx_event, &len); if ((ret == -EAGAIN) || (ret == -EINTR)) { continue; } if (ENOERR != ret) { CYG_TEST_FAIL_FINISH("Error reading from channel"); } else { diag_printf("Channel %d events: ", i); print_can_flags(rx_event.flags, ""); if (rx_event.flags & CYGNUM_CAN_EVENT_RX) { print_can_msg(&rx_event.msg, ""); if ((rx_event.msg.id & 9) == 9) { CYG_TEST_PASS_FINISH("LPC2xxx CAN multi channel RX test OK"); } } // if (rx_event.flags & CYGNUM_CAN_EVENT_RX) } } // if (hCAN_Tbl[i]) } // for (i = 0; i < 4; ++i) } // while (1) }
//=========================================================================== // READER THREAD //=========================================================================== void can0_thread(cyg_addrword_t data) { cyg_uint32 len; cyg_can_event rx_event; cyg_can_filtergroup_cfg acc_filt_grp; cyg_can_msgbuf_cfg msgbox_cfg; // // First we reset message buffer configuration - this is mandatory bevore starting // message buffer runtime configuration. This call clears/frees all message buffers // The CAN controller cannot receive any further CAN message after this call // msgbox_cfg.cfg_id = CYGNUM_CAN_MSGBUF_RESET_ALL; len = sizeof(msgbox_cfg); if (ENOERR != cyg_io_set_config(hCAN0, CYG_IO_SET_CONFIG_CAN_MSGBUF ,&msgbox_cfg, &len)) { CYG_TEST_FAIL_FINISH("Error resetting message buffer configuration of /dev/can0"); } // // Now we setup two different acceptance filter groups. Acceptance filter // groups are not part of the CAN I/O layer and are a LPC2xxx specific // feature. You should not use appcetance filter groups if you would like // to code portable eCos CAN applications // #ifdef CYGOPT_IO_CAN_STD_CAN_ID acc_filt_grp.ext = CYGNUM_CAN_ID_STD; acc_filt_grp.lower_id_bound = 0x100; acc_filt_grp.upper_id_bound = 0x110; len = sizeof(acc_filt_grp); if (ENOERR != cyg_io_set_config(hCAN0, CYG_IO_SET_CONFIG_LPC2XXX_ACCFILT_GROUP ,&acc_filt_grp, &len)) { CYG_TEST_FAIL_FINISH("Error adding filter group to /dev/can0"); } #endif // CYGOPT_IO_CAN_STD_CAN_ID #ifdef CYGOPT_IO_CAN_EXT_CAN_ID acc_filt_grp.ext = CYGNUM_CAN_ID_EXT; acc_filt_grp.lower_id_bound = 0x2000; acc_filt_grp.upper_id_bound = 0x2200; len = sizeof(acc_filt_grp); if (ENOERR != cyg_io_set_config(hCAN0, CYG_IO_SET_CONFIG_LPC2XXX_ACCFILT_GROUP ,&acc_filt_grp, &len)) { CYG_TEST_FAIL_FINISH("Error adding filter group to /dev/can0"); } #endif // CYGOPT_IO_CAN_STD_CAN_ID diag_printf("\n\nNow try to send CAN messages. The device should only\n" "receive standard messages identifiers in the range of 0x100\n" "to 0x110 and/or extended identifiers in the range 0x2000 to\n" "0x2200. As soon as a standard message with ID 0x110 or an\n" "extended message with ID 0x2200 arrives, the test finishes\n\n"); while (1) { len = sizeof(rx_event); if (ENOERR != cyg_io_read(hCAN0, &rx_event, &len)) { CYG_TEST_FAIL_FINISH("Error reading from /dev/can0"); } else { print_can_flags(rx_event.flags, ""); if (rx_event.flags & CYGNUM_CAN_EVENT_RX) { print_can_msg(&rx_event.msg, ""); #ifdef CYGOPT_IO_CAN_STD_CAN_ID if (rx_event.msg.id == 0x110) { CYG_TEST_PASS_FINISH("LPC2xxx CAN message filter group test OK"); } #endif // CYGOPT_IO_CAN_STD_CAN_ID #ifdef CYGOPT_IO_CAN_EXT_CAN_ID if (rx_event.msg.id == 0x2200) { CYG_TEST_PASS_FINISH("LPC2xxx CAN message filter group test OK"); } #endif // CYGOPT_IO_CAN_EXT_CAN_ID if (((rx_event.msg.id > 0x110) && (rx_event.msg.id < 0x2000)) || (rx_event.msg.id > 0x2200)) { CYG_TEST_FAIL_FINISH("Received CAN identifier outside filter group bounds"); } } } } // while (1) }
//=========================================================================== // Thread 0 //=========================================================================== void can_rx_thread(cyg_addrword_t data) { cyg_uint32 len; cyg_can_event rx_event; cyg_can_event loop_rx_event; cyg_uint32 msg_cnt = 0; cyg_uint8 i; while (msg_cnt < 0xF0) { // // First receive CAN event from real CAN hardware // len = sizeof(rx_event); if (ENOERR != cyg_io_read(hCAN_Tbl[1], &rx_event, &len)) { CYG_TEST_FAIL_FINISH("Error reading from channel 1"); } if (rx_event.flags & CYGNUM_CAN_EVENT_RX) { print_can_msg(&rx_event.msg, "RX chan 1:"); } // if (rx_event.flags & CYGNUM_CAN_EVENT_RX) else { print_can_flags(rx_event.flags, ""); } // // Now receive CAN event from loop CAN driver // len = sizeof(loop_rx_event); if (ENOERR != cyg_io_read(hLoopCAN_Tbl[1], &loop_rx_event, &len)) { CYG_TEST_FAIL_FINISH("Error reading from loop channel 1"); } if (rx_event.flags & CYGNUM_CAN_EVENT_RX) { print_can_msg(&rx_event.msg, "RX loop 1:"); } // if (rx_event.flags & CYGNUM_CAN_EVENT_RX) else { print_can_flags(rx_event.flags, ""); } // // Chaeck message ID and DLC of HW CAN message and CAN message from loop driver // booth should be the same // if (rx_event.msg.id != loop_rx_event.msg.id) { CYG_TEST_FAIL_FINISH("Received message IDs of hw CAN channel and loop CAN channel are not equal"); } if (rx_event.msg.dlc != loop_rx_event.msg.dlc) { CYG_TEST_FAIL_FINISH("Received DLCs of hw CAN msg and loop CAN msg are not equal"); } // // Now check each data byte of the receive message // for (i = 0; i < rx_event.msg.dlc; ++i) { if (rx_event.msg.data.bytes[i] != loop_rx_event.msg.data.bytes[i]) { CYG_TEST_FAIL_FINISH("Data of hw CAN msg and loop CAN msg are not equal"); } if (rx_event.msg.data.bytes[i] != (i + msg_cnt)) { CYG_TEST_FAIL_FINISH("CAN message contains unexpected data"); } } msg_cnt++; } // while (1) CYG_TEST_PASS_FINISH("CAN rx/tx test OK"); }
//=========================================================================== // READER THREAD //=========================================================================== void can1_thread(cyg_addrword_t data) { cyg_io_handle_t hCAN1; cyg_uint8 i; cyg_uint32 len; cyg_can_buf_info_t rx_buf_info; cyg_can_event rx_event; cyg_can_message tx_msg; if (ENOERR != cyg_io_lookup("/dev/can1", &hCAN1)) { CYG_TEST_FAIL_FINISH("Error opening /dev/can1"); } len = sizeof(rx_buf_info); if (ENOERR != cyg_io_get_config(hCAN1, CYG_IO_GET_CONFIG_CAN_BUFFER_INFO ,&rx_buf_info, &len)) { CYG_TEST_FAIL_FINISH("Error reading config of /dev/can1"); } // // first we send the size of our receive buffer to the writer // we setup tx message now // tx_msg.id = 0x000; tx_msg.ext = CYGNUM_CAN_ID_STD; tx_msg.rtr = CYGNUM_CAN_FRAME_DATA; tx_msg.dlc = sizeof(rx_buf_info.rx_bufsize); // // we store size of rx buffer in CAN message. We do not need to care about // endianess here because this is a loopback driver test and we will receive // our own messages // *((cyg_uint32 *)tx_msg.data) = rx_buf_info.rx_bufsize; len = sizeof(tx_msg); // // as soon as we send a CAN message, thread 0 will resume because it is waiting // for a message // diag_printf("/dev/can1: Sending size of RX buffer %d\n", rx_buf_info.rx_bufsize); if (ENOERR != cyg_io_write(hCAN1, &tx_msg, &len)) { CYG_TEST_FAIL_FINISH("Error writing to /dev/can1"); } cyg_thread_delay(10); // let thread 0 run // // now we check if we received CAN messages - if receive buffer is not full // the we have an error here because we expect a full receive buffer // len = sizeof(rx_buf_info); if (ENOERR != cyg_io_get_config(hCAN1, CYG_IO_GET_CONFIG_CAN_BUFFER_INFO ,&rx_buf_info, &len)) { CYG_TEST_FAIL_FINISH("Error reading config of /dev/can1"); } if (rx_buf_info.rx_bufsize != rx_buf_info.rx_count) { CYG_TEST_FAIL_FINISH("RX buffer of /dev/can1 does not contain number of expected messages"); } // // now we wait for messages from /dev/can0 // diag_printf("/dev/can1: Receiving %d CAN messages\n", rx_buf_info.rx_count); for (i = 0; i < rx_buf_info.rx_count; ++i) { len = sizeof(rx_event); if (ENOERR != cyg_io_read(hCAN1, &rx_event, &len)) { CYG_TEST_FAIL_FINISH("Error reading from /dev/can0"); } else { if (rx_event.flags & CYGNUM_CAN_EVENT_RX) { print_can_msg(&rx_event.msg, ""); if (rx_event.msg.data[0] != (i + 1)) { CYG_TEST_FAIL_FINISH("Received /dev/can1 RX event contains invalid data"); } } else { CYG_TEST_FAIL_FINISH("Unexpected CAN event for /dev/can1"); } // // now check if any other flag is set // if (rx_event.flags & CYGNUM_CAN_EVENT_OVERRUN_RX) { diag_printf("RX queue overrun successfully indicated for /dev/can1\n"); // // if TX events are supported then we have already a TX event in receive queue because // we sent a message and the RX queue overrun will occur one message earlier // #if defined(CYGOPT_IO_CAN_TX_EVENT_SUPPORT) if (i < (rx_buf_info.rx_bufsize - 2)) #else if (i < (rx_buf_info.rx_bufsize - 1)) #endif { CYG_TEST_FAIL_FINISH("RX queue overrun occured too early for /dev/can1"); } else { CYG_TEST_PASS_FINISH("can_overrun2 test OK"); } } // if (rx_event.flags & CYGNUM_CAN_EVENT_OVERRUN_RX) } } }
//=========================================================================== // WRITER THREAD //=========================================================================== void can0_thread(cyg_addrword_t data) { cyg_io_handle_t hCAN0; cyg_uint8 i; cyg_uint32 len; cyg_uint32 rx_bufsize; cyg_can_buf_info_t tx_buf_info; cyg_can_event rx_event; cyg_can_message tx_msg = { 0x000, // CAN identifier {0x00, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7}, // 8 data bytes CYGNUM_CAN_ID_STD, // standard frame CYGNUM_CAN_FRAME_DATA, // data frame 2, // data length code }; if (ENOERR != cyg_io_lookup("/dev/can0", &hCAN0)) { CYG_TEST_FAIL_FINISH("Error opening /dev/can0"); } len = sizeof(tx_buf_info); if (ENOERR != cyg_io_get_config(hCAN0, CYG_IO_GET_CONFIG_CAN_BUFFER_INFO ,&tx_buf_info, &len)) { CYG_TEST_FAIL_FINISH("Error reading config of /dev/can0"); } // // Before we can write the CAN messages, we need to know the buffer size of the // receiver. The receiver will tell us this buffer size with one single CAN // message // len = sizeof(rx_event); if (ENOERR != cyg_io_read(hCAN0, &rx_event, &len)) { CYG_TEST_FAIL_FINISH("Error reading from /dev/can0"); } // // we expect a RX event here - we treat any other flag as an error // if (!(rx_event.flags & CYGNUM_CAN_EVENT_RX) || (rx_event.flags & !CYGNUM_CAN_EVENT_RX)) { CYG_TEST_FAIL_FINISH("Unexpected RX event for /dev/can0"); } rx_bufsize = *((cyg_uint32 *)rx_event.msg.data); // // now we send exactly one CAN message more than there is space in the receive buffer // this should cause an RX ovverun in receive buffer // diag_printf("/dev/can0: Sending %d CAN messages\n", rx_bufsize); for (i = 0; i <= rx_bufsize; ++i) { // // we store the message number as CAN id and in first data byte so // a receiver can check this later // tx_msg.id = 0x000 + i; tx_msg.data[0] = i; len = sizeof(tx_msg); if (ENOERR != cyg_io_write(hCAN0, &tx_msg, &len)) { CYG_TEST_FAIL_FINISH("Error writing to /dev/can0"); } else { print_can_msg(&tx_msg, ""); } } // for (i = 0; i <= rx_bufsize; ++i) cyg_thread_suspend(cyg_thread_self()); }
//=========================================================================== // Thread 0 //=========================================================================== void can0_thread(cyg_addrword_t data) { cyg_uint32 len; cyg_can_message tx_msg; cyg_can_event rx_event; cyg_uint32 i; cyg_uint32 rx_msg_cnt = 0; // // Prepeare message - we use a data length of 0 bytes here. Each received message // causes an iterrupt. The shortest message is a 0 data byte message. This will generate // the highest interrupt rate // CYG_CAN_MSG_SET_PARAM(tx_msg, 0, CYGNUM_CAN_ID_STD, 0, CYGNUM_CAN_FRAME_DATA); // // Now send 1024 CAN messages as fast as possible to stress the receiver of CAN // channel 1 // for (i = 0; i< 1024; ++i) { tx_msg.id = i; len = sizeof(tx_msg); if (ENOERR != cyg_io_write(hCAN_Tbl[1], &tx_msg, &len)) { CYG_TEST_FAIL_FINISH("Error writing to channel 0"); } } // // Now try to receive all 1024 CAN messages. If all messages are received // and no overrun occured then the message processing is fast enought // while (1) { len = sizeof(rx_event); // // First receive CAN event from real CAN hardware // len = sizeof(rx_event); if (ENOERR != cyg_io_read(hCAN_Tbl[0], &rx_event, &len)) { CYG_TEST_FAIL_FINISH("Error reading from channel 1"); } if (rx_event.flags & CYGNUM_CAN_EVENT_RX) { print_can_msg(&rx_event.msg, "RX chan 1:"); rx_msg_cnt++; if (rx_msg_cnt == 1024) { CYG_TEST_PASS_FINISH("CAN load test OK"); } } // if (rx_event.flags & CYGNUM_CAN_EVENT_RX) else { print_can_flags(rx_event.flags, ""); if (rx_event.flags & CYGNUM_CAN_EVENT_OVERRUN_RX) { CYG_TEST_FAIL_FINISH("RX overrun for channel 1"); } if (rx_event.flags & CYGNUM_CAN_EVENT_ERR_PASSIVE) { CYG_TEST_FAIL_FINISH("Channel 1 error passive event"); } if (rx_event.flags & CYGNUM_CAN_EVENT_BUS_OFF) { CYG_TEST_FAIL_FINISH("Channel 1 bus off event"); } } } // while (1) }
//=========================================================================== // Main thread //=========================================================================== void can0_thread(cyg_addrword_t data) { cyg_uint32 len; cyg_can_event rx_event; cyg_uint16 i; cyg_can_hdi hdi; cyg_can_msgbuf_info msgbox_info; cyg_can_msgbuf_cfg msgbox_cfg; len = sizeof(hdi); if (ENOERR != cyg_io_get_config(hCAN0, CYG_IO_GET_CONFIG_CAN_HDI ,&hdi, &len)) { CYG_TEST_FAIL_FINISH("Error reading config of /dev/can0"); } // // Normally the CAN modul should support message filters. So the // FULLCAN flag should be set - if it is not, we treat this as an error // if (!(hdi.support_flags & CYGNUM_CAN_HDI_FULLCAN)) { CYG_TEST_FAIL_FINISH("/dev/can0 does not support message buffers"); } // // Now reset message buffer configuration - this is mandatory bevore starting // message buffer runtime configuration // msgbox_cfg.cfg_id = CYGNUM_CAN_MSGBUF_RESET_ALL; len = sizeof(msgbox_cfg); if (ENOERR != cyg_io_set_config(hCAN0, CYG_IO_SET_CONFIG_CAN_MSGBUF ,&msgbox_cfg, &len)) { CYG_TEST_FAIL_FINISH("Error resetting message buffer configuration of /dev/can0"); } // // Now query number of available and free message boxes // len = sizeof(msgbox_info); if (ENOERR != cyg_io_get_config(hCAN0, CYG_IO_GET_CONFIG_CAN_MSGBUF_INFO ,&msgbox_info, &len)) { CYG_TEST_FAIL_FINISH("Error reading config of /dev/can0"); } // // if there are no free message boxes available then this is a failure // if (!msgbox_info.free) { CYG_TEST_FAIL_FINISH("No free message boxes available for /dev/can0"); } // // We setup as many standard CAN message filters as there are free // message buffers available. // for (i = 0; i < msgbox_info.free; ++i) { cyg_can_filter rx_filter; rx_filter.cfg_id = CYGNUM_CAN_MSGBUF_RX_FILTER_ADD; rx_filter.msg.id = i; rx_filter.msg.ext = CYGNUM_CAN_ID_STD; len = sizeof(rx_filter); if (ENOERR != cyg_io_set_config(hCAN0, CYG_IO_SET_CONFIG_CAN_MSGBUF ,&rx_filter, &len)) { CYG_TEST_FAIL_FINISH("Error writing config of /dev/can0"); } else if (CYGNUM_CAN_MSGBUF_NA == rx_filter.handle) { CYG_TEST_FAIL_FINISH("Error setting up message filter for /dev/can0"); } } diag_printf("\n\nNow try to send CAN messages. The device should only\n" "receive messages identifiers in the range of 0x00 to 0x%X.\n" "As soon as a standard message with ID 0x000 arrives, all\n" "message filters will be cleared\n\n", (msgbox_info.free - 1)); // // Now receive messages until a message arrives with largest ID of all // available message filters // rx_event.msg.id = 1; while(rx_event.msg.id != 0) { len = sizeof(rx_event); if (ENOERR != cyg_io_read(hCAN0, &rx_event, &len)) { CYG_TEST_FAIL_FINISH("Error reading from /dev/can0"); } else if (rx_event.flags & CYGNUM_CAN_EVENT_RX) { print_can_msg(&rx_event.msg, ""); } // if (ENOERR != cyg_io_read(hCAN0, &rx_event, &len)) else { print_can_flags(rx_event.flags, ""); rx_event.msg.id = 1; } } // while(1) // // Now enable reception of all available CAN messages // cyg_can_filter rx_filter; rx_filter.cfg_id = CYGNUM_CAN_MSGBUF_RX_FILTER_ALL; len = sizeof(rx_filter); if (ENOERR != cyg_io_set_config(hCAN0, CYG_IO_SET_CONFIG_CAN_MSGBUF , &rx_filter, &len)) { CYG_TEST_FAIL_FINISH("Error writing config of /dev/can0"); } diag_printf("\n\nAll message filters have been cleared an now the device\n" "will receive any available CAN message identifiers.\n" "Send a CAN message with ID 0x100 to stop this test.\n\n"); // // Now receive messages until a message arrives with largest ID of all // available message filters // rx_event.msg.id = 1; while(rx_event.msg.id != 0x100) { len = sizeof(rx_event); if (ENOERR != cyg_io_read(hCAN0, &rx_event, &len)) { CYG_TEST_FAIL_FINISH("Error reading from /dev/can0"); } else if (rx_event.flags & CYGNUM_CAN_EVENT_RX) { print_can_msg(&rx_event.msg, ""); } // if (ENOERR != cyg_io_read(hCAN0, &rx_event, &len)) } // while(1) CYG_TEST_PASS_FINISH("can_filter test OK"); }
//=========================================================================== // Main thread //=========================================================================== void can0_thread(cyg_addrword_t data) { cyg_uint32 len; cyg_can_event rx_event; cyg_can_remote_buf rtr_buf; cyg_can_filter rx_filter; cyg_can_msgbuf_info msgbox_info; cyg_can_msgbuf_cfg msgbox_cfg; // // We would like to setup 2 remote buffers - check if we have enough // free message buffers // len = sizeof(msgbox_info); if (ENOERR != cyg_io_get_config(hCAN0, CYG_IO_GET_CONFIG_CAN_MSGBUF_INFO ,&msgbox_info, &len)) { CYG_TEST_FAIL_FINISH("Error reading config of /dev/can0"); } else { diag_printf("\n\n\nMessage boxes available: %d free: %d\n", msgbox_info.count, msgbox_info.free); } // // We have not enougth free message buffers, so we clear all message buffers now // and try again // if (msgbox_info.free < 2) { msgbox_cfg.cfg_id = CYGNUM_CAN_MSGBUF_RESET_ALL; len = sizeof(msgbox_cfg); if (ENOERR != cyg_io_set_config(hCAN0, CYG_IO_SET_CONFIG_CAN_MSGBUF, &msgbox_cfg, &len)) { CYG_TEST_FAIL_FINISH("Error clearing message buffers of /dev/can0"); } // // Now query number of free message boxes again. We need 3 free message boxes. // 2 message boxes for setup of remote response buffers and 1 message box for // setup of receive message box for CAN identifier 0x100 // len = sizeof(msgbox_info); if (ENOERR != cyg_io_get_config(hCAN0, CYG_IO_GET_CONFIG_CAN_MSGBUF_INFO ,&msgbox_info, &len)) { CYG_TEST_FAIL_FINISH("Error reading config of /dev/can0"); } else { diag_printf("Message boxes available: %d free: %d\n", msgbox_info.count, msgbox_info.free); } if (msgbox_info.free < 3) { CYG_TEST_FAIL_FINISH("Not enough free message buffers available for /dev/can0"); } else { rx_filter.cfg_id = CYGNUM_CAN_MSGBUF_RX_FILTER_ADD; CYG_CAN_MSG_SET_STD_ID(rx_filter.msg, 0x100); len = sizeof(rx_filter); if (ENOERR != cyg_io_set_config(hCAN0, CYG_IO_SET_CONFIG_CAN_MSGBUF ,&rx_filter, &len)) { CYG_TEST_FAIL_FINISH("Error adding rx filter for CAN ID 0x100 for /dev/can0"); } } // if (msgbox_info.free < 3) } // if (msgbox_info.free < 2) #ifdef CYGOPT_IO_CAN_STD_CAN_ID // // Setup the first remote response buffer for resception of standard // remote frames // rtr_buf.cfg_id = CYGNUM_CAN_MSGBUF_REMOTE_BUF_ADD; CYG_CAN_MSG_SET_PARAM(rtr_buf.msg, 0x7FF, CYGNUM_CAN_ID_STD, 1, CYGNUM_CAN_FRAME_DATA); CYG_CAN_MSG_SET_DATA(rtr_buf.msg, 0, 0xAB); len = sizeof(rtr_buf); if (ENOERR != cyg_io_set_config(hCAN0, CYG_IO_SET_CONFIG_CAN_MSGBUF ,&rtr_buf, &len)) { CYG_TEST_FAIL_FINISH("Error writing config of /dev/can0"); } #endif #ifdef CYGOPT_IO_CAN_EXT_CAN_ID cyg_can_remote_buf rtr_buf2; // // setup the second remote response buffer for reception of extended // remote frames // rtr_buf2.cfg_id = CYGNUM_CAN_MSGBUF_REMOTE_BUF_ADD; CYG_CAN_MSG_SET_PARAM(rtr_buf2.msg, 0x800, CYGNUM_CAN_ID_EXT, 4, CYGNUM_CAN_FRAME_DATA); CYG_CAN_MSG_SET_DATA(rtr_buf2.msg, 0, 0xCD); len = sizeof(rtr_buf2); if (ENOERR != cyg_io_set_config(hCAN0, CYG_IO_SET_CONFIG_CAN_MSGBUF ,&rtr_buf2, &len)) { CYG_TEST_FAIL_FINISH("Error writing config of /dev/can0"); } if (rtr_buf.handle == CYGNUM_CAN_MSGBUF_NA) { CYG_TEST_FAIL_FINISH("No free message buffer available for /dev/can0"); } #endif diag_printf("\nTest of CAN remote response buffer configuration\n" "If a CAN node sends a remote request with ID 0x7FF (std. ID)\n" "or 0x800 (ext. ID) then the CAN driver should respond with\n" "data frames.\n\n"); diag_printf("!!! This test can be stopped by sending a data frame\n" "with ID 0x100 !!!\n\n"); len = sizeof(msgbox_info); if (ENOERR != cyg_io_get_config(hCAN0, CYG_IO_GET_CONFIG_CAN_MSGBUF_INFO ,&msgbox_info, &len)) { CYG_TEST_FAIL_FINISH("Error writing config of /dev/can0"); } else { diag_printf("Message boxes available: %d free: %d\n", msgbox_info.count, msgbox_info.free); } while (1) { len = sizeof(rx_event); if (ENOERR != cyg_io_read(hCAN0, &rx_event, &len)) { CYG_TEST_FAIL_FINISH("Error reading from /dev/can0"); } if (0x100 == rx_event.msg.id) { CYG_TEST_PASS_FINISH("can_remote test OK"); } else { print_can_flags(rx_event.flags, ""); if (rx_event.flags & CYGNUM_CAN_EVENT_RX) { print_can_msg(&rx_event.msg, ""); } } } }