Beispiel #1
0
//===========================================================================
//                             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, "");    
        }
    }

              
}
Beispiel #2
0
//===========================================================================
//                             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");                     
}
Beispiel #3
0
//===========================================================================
//                             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)
}
Beispiel #5
0
//===========================================================================
// 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");         
}
Beispiel #6
0
//===========================================================================
//                            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)  
        }
        
    }
}
Beispiel #7
0
//===========================================================================
//                             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());                 
}
Beispiel #8
0
//===========================================================================
// 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)
}
Beispiel #9
0
//===========================================================================
// 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");
}
Beispiel #10
0
//===========================================================================
// 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, "");   
            }
        }
    }         
}