//=========================================================================== // Thread 1 //=========================================================================== void can_tx_thread(cyg_addrword_t data) { cyg_uint32 len; cyg_can_message tx_msg; cyg_uint32 msg_cnt = 0; cyg_uint8 i; CYG_CAN_MSG_SET_PARAM(tx_msg, 0, CYGNUM_CAN_ID_STD, 0, CYGNUM_CAN_FRAME_DATA); // // Prepare CAN message with a known CAN state // for (i = 0; i < 8; ++i) { tx_msg.data.bytes[i] = i; } while (msg_cnt < 0xF0) { tx_msg.id = msg_cnt; len = sizeof(tx_msg); if (ENOERR != cyg_io_write(hCAN_Tbl[0], &tx_msg, &len)) { CYG_TEST_FAIL_FINISH("Error writing to channel 0"); } tx_msg.id = msg_cnt; len = sizeof(tx_msg); if (ENOERR != cyg_io_write(hLoopCAN_Tbl[0], &tx_msg, &len)) { CYG_TEST_FAIL_FINISH("Error writing to channel 1"); } // // Increment data in each single data byte // for (i = 0; i < 8; ++i) { tx_msg.data.bytes[i] += 1; } msg_cnt++; tx_msg.dlc = (tx_msg.dlc + 1) % 9; } // while (msg_cnt < 0x100) }
//=========================================================================== // 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) }
//=========================================================================== // READER THREAD //=========================================================================== void can_thread(cyg_addrword_t data) { cyg_uint32 len; cyg_can_message tx_msg; cyg_can_info_t can_info; cyg_can_baud_rate_t baud; cyg_uint8 i = 0; cyg_uint8 j = 0; // // Check that all cannels have the same baudrate // #ifdef CYGPKG_DEVS_CAN_LPC2XXX_CAN0 len = sizeof(can_info); if (ENOERR != cyg_io_get_config(hCAN_Tbl[0], CYG_IO_GET_CONFIG_CAN_INFO, &can_info, &len)) { CYG_TEST_FAIL_FINISH("Error reading baudrate of CAN channel 0"); } else { baud = can_info.baud; ++i; } #endif #ifdef CYGPKG_DEVS_CAN_LPC2XXX_CAN1 len = sizeof(can_info); if (ENOERR != cyg_io_get_config(hCAN_Tbl[1], CYG_IO_GET_CONFIG_CAN_INFO, &can_info, &len)) { CYG_TEST_FAIL_FINISH("Error reading baudrate of CAN channel 1"); } else { if (i && (baud != can_info.baud)) { CYG_TEST_FAIL_FINISH("Error - different baudrates for CAN channel 0 and 1"); } baud = can_info.baud; ++i; } #endif #ifdef CYGPKG_DEVS_CAN_LPC2XXX_CAN2 len = sizeof(can_info); if (ENOERR != cyg_io_get_config(hCAN_Tbl[2], CYG_IO_GET_CONFIG_CAN_INFO, &can_info, &len)) { CYG_TEST_FAIL_FINISH("Error reading baudrate of CAN channel 2"); } else { if (i && (baud != can_info.baud)) { CYG_TEST_FAIL_FINISH("Error - different baudrates for CAN channel 1 and 2"); } baud = can_info.baud; ++i; } #endif #ifdef CYGPKG_DEVS_CAN_LPC2XXX_CAN3 len = sizeof(can_info); if (ENOERR != cyg_io_get_config(hCAN_Tbl[3], CYG_IO_GET_CONFIG_CAN_INFO, &can_info, &len)) { CYG_TEST_FAIL_FINISH("Error reading baudrate of CAN channel 3"); } else { if (i && (baud != can_info.baud)) { CYG_TEST_FAIL_FINISH("Error - different baudrates for CAN channel 2 and 3"); } baud = can_info.baud; ++i; } #endif diag_printf("\n\nYou should no receive 4 CAN messages from each active CAN channel\n"); // // Now each CAN channel sends 10 CAN messages // for (i = 0; i < 4; ++i) { if (hCAN_Tbl[i]) { CYG_CAN_MSG_SET_PARAM(tx_msg, i * 0x100, CYGNUM_CAN_ID_STD, 4, CYGNUM_CAN_FRAME_DATA); tx_msg.data.dwords[0] = 0; tx_msg.data.dwords[1] = 0; char err_msg[64]; diag_snprintf(err_msg, sizeof(err_msg), "Error sending TX using CAN channel %d", i); for (j = 0; j < 4; ++j) { tx_msg.id = i * 0x100 + j; tx_msg.data.bytes[0] = j; len = sizeof(tx_msg); if (ENOERR != cyg_io_write(hCAN_Tbl[i], &tx_msg, &len)) { CYG_TEST_FAIL_FINISH(err_msg); } } } // if (hCAN_Tbl[i]) } // for (i = 0; i < 4; ++i) CYG_TEST_PASS_FINISH("LPC2xxx CAN multi channel TX 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, ""); } } } }