Beispiel #1
0
static void
test_channel(const char *dev, cyg_io_handle_t channel)
{
    Cyg_ErrNo res;
    cyg_uint32 cfg_data;
    cyg_uint32 len;
    cyg_adc_sample_t sample;
    int count;
    
    diag_printf("\nTesting ADC channel '%s'\n", dev);
    
    // Disable channel
    res = cyg_io_set_config(channel, CYG_IO_SET_CONFIG_ADC_DISABLE, 0, 0);
    if (res != ENOERR)
        CYG_TEST_FAIL_FINISH("Failed to disable ADC channel");
    
    // Make channel non-blocking
    cfg_data = 0;
    len = sizeof(cfg_data);
    res = cyg_io_set_config(channel, CYG_IO_SET_CONFIG_READ_BLOCKING,
                            &cfg_data, &len);
    if (res != ENOERR)
        CYG_TEST_FAIL_FINISH("Failed to make ADC channel non-blocking");

    // Set channel sampling rate
    cfg_data = TEST_RATE;
    len = sizeof(cfg_data);
    res = cyg_io_set_config(channel, CYG_IO_SET_CONFIG_ADC_RATE,
                            &cfg_data, &len);
    if (res != ENOERR)
        CYG_TEST_FAIL_FINISH("Failed to set ADC channel sampling rate");
    
    // Flush channel
    do {
        len = sizeof(sample);
        res = cyg_io_read(channel, &sample, &len);
    } while (res == ENOERR);
    
    // Enable channel
    res = cyg_io_set_config(channel, CYG_IO_SET_CONFIG_ADC_ENABLE, 0, 0);
    if (res != ENOERR)
        CYG_TEST_FAIL_FINISH("Failed to enable ADC channel");
    
    // Read from channel
    count = 0;
    while (count < TEST_SAMPLES) {
        len = sizeof(sample);
        res = cyg_io_read(channel, &sample, &len);
        if (res == ENOERR) {
            diag_printf("%d\n", sample);
            count++;
        }
    }
    
    // Disable channel
    res = cyg_io_set_config(channel, CYG_IO_SET_CONFIG_ADC_DISABLE, 0, 0);
    if (res != ENOERR)
        CYG_TEST_FAIL_FINISH("Failed to disable ADC channel");
}
//===========================================================================
//                             READER THREAD 
//===========================================================================
void can0_thread(cyg_addrword_t data)
{
    cyg_uint32             len;
    cyg_uint32             blocking;
    cyg_can_event          rx_event;
    Cyg_ErrNo              res;

    blocking = 0;
    len = sizeof(blocking);
    if (ENOERR != cyg_io_set_config(hDrvFlexCAN, CYG_IO_SET_CONFIG_READ_BLOCKING ,&blocking, &len))
    {
        CYG_TEST_FAIL_FINISH("Error writing config of /dev/can0");
    } 
    
    len = sizeof(rx_event);  
    res = cyg_io_read(hDrvFlexCAN, &rx_event, &len);
            
    if (-EAGAIN == res)
    {
        CYG_TEST_PASS_FINISH("can_test1 test OK");
    }
    else if (-EINTR == res)
    {
    	CYG_TEST_PASS_FINISH("can_test1 test OK");
    }
    else
    {
        CYG_TEST_FAIL_FINISH("Error reading from /dev/can0");
    }           
}
Beispiel #3
0
/*
 * Tries to read from the serial device. Same as sio_read but returns
 * immediately if no data is available and never blocks.
 */
u32_t sio_tryread(sio_fd_t fd, u8_t *data, u32_t len)
{
    Cyg_ErrNo ret;
    cyg_serial_buf_info_t info;
    cyg_uint32 l;
    
#ifdef CYGDBG_LWIP_DEBUG_SIO
    diag_printf("sio_tryread(fd=%p,data=%p,len=%lu:)\n", fd, data, len);
#endif

    // Check how many bytes there are to read
    l = sizeof(info);
    ret = cyg_io_get_config((cyg_io_handle_t) fd, CYG_IO_GET_CONFIG_SERIAL_BUFFER_INFO, &info, &l);
    if (ret != ENOERR)
        return 0;
    l = info.rx_count;
    if (l < 1)
        return 0;
    if (l > len)
        l = len;

    ret = cyg_io_read((cyg_io_handle_t) fd, data, &l);
    if (ret != ENOERR)
        return 0;
    
#ifdef CYGDBG_LWIP_DEBUG_SIO
   diag_printf("sio_tryread: ");
   diag_dump_buf(data, len);
#endif
   
   return l;
}
Beispiel #4
0
static int
uart_read(void *base, char *buf, int len)
{
    struct BSP_IO *io = (struct BSP_IO *)base;
    if (io->chan) {
        cyg_io_read(io->chan, buf, &len);
        return len;
    }
    return 0;
}
Beispiel #5
0
static int
uart_getchar(void *base)
{
    char buf = '\0';
    int len;
    struct BSP_IO *io = (struct BSP_IO *)base;
    if (io->chan) {
        len = 1;
        cyg_io_read(io->chan, &buf, &len);
    }
    return buf;
}
Beispiel #6
0
/*
 * Receives a single character from the serial device.
 */
u8_t sio_recv(sio_fd_t fd)
{
    cyg_uint32 len = 1;
    char c;
    
#ifdef CYGDBG_LWIP_DEBUG_SIO
    diag_printf("sio_recv(fd=%p)\n", fd);
#endif
    
	cyg_io_read((cyg_io_handle_t) fd, &c, &len);
	
#ifdef CYGDBG_LWIP_DEBUG_SIO
    diag_printf("sio_recv: %02X\n", (cyg_uint8) c);
#endif
	
	return c;
}
Beispiel #7
0
/*
 * Reads from the serial device.
 */
u32_t sio_read(sio_fd_t fd, u8_t *data, u32_t len)
{
    Cyg_ErrNo ret;
    
#ifdef CYGDBG_LWIP_DEBUG_SIO
    diag_printf("sio_read(fd=%p,data=%p,len=%lu:)\n", fd, data, len);
#endif
    
    ret = cyg_io_read((cyg_io_handle_t) fd, data, (cyg_uint32 *) &len);
    if (ret != ENOERR)
        return 0;

#ifdef CYGDBG_LWIP_DEBUG_SIO
    diag_printf("sio_read: ");
    diag_dump_buf(data, len);
#endif

    return len;
}
Beispiel #8
0
void
tty_api_test(cyg_io_handle_t* handle)
{
    int res;
    cyg_uint32 len;
    unsigned char buffer[16];

    // Always return...
    if (handle)
        return;

    CYG_TEST_FAIL_FINISH("Not reached");

    // read & write
    res = cyg_io_read(handle, &buffer[0], &len);
    res = cyg_io_write(handle, &buffer[0], &len);

    // cyg_io_get_config
    // TTY layer
    cyg_io_get_config(handle, 
                      CYG_IO_GET_CONFIG_TTY_INFO, &buffer[0], &len);
    // Call-throughs to serial layer.
    cyg_io_get_config(handle, 
                      CYG_IO_GET_CONFIG_SERIAL_INFO, &buffer[0], &len);
    cyg_io_get_config(handle, 
                      CYG_IO_GET_CONFIG_SERIAL_OUTPUT_DRAIN, &buffer[0], &len);
    cyg_io_get_config(handle, 
                      CYG_IO_GET_CONFIG_SERIAL_INPUT_FLUSH, &buffer[0], &len);
    cyg_io_get_config(handle, 
                      CYG_IO_GET_CONFIG_SERIAL_ABORT, &buffer[0], &len);
    cyg_io_get_config(handle, 
                      CYG_IO_GET_CONFIG_SERIAL_OUTPUT_FLUSH, &buffer[0], &len);

    // cyg_io_set_config
    // TTY layer.
    cyg_io_set_config(handle, 
                      CYG_IO_SET_CONFIG_TTY_INFO, &buffer[0], &len);
    // Call-throughs to serial layer.
    cyg_io_set_config(handle, 
                      CYG_IO_SET_CONFIG_SERIAL_INFO, &buffer[0], &len);
}
Beispiel #9
0
void
serial_api_test(int dummy)
{
    cyg_io_handle_t handle;
    int res;
    cyg_uint32 len;
    unsigned char buffer[16];

    // Always return...
    if (dummy)
        return;

    CYG_TEST_FAIL_FINISH("Not reached");

    test_open_ser(&handle);

    // read & write
    res = cyg_io_read(handle, &buffer[0], &len);
    res = cyg_io_write(handle, &buffer[0], &len);

    // cyg_io_get_config
    cyg_io_get_config(handle, 
                      CYG_IO_GET_CONFIG_SERIAL_INFO, &buffer[0], &len);
    cyg_io_get_config(handle, 
                      CYG_IO_GET_CONFIG_SERIAL_OUTPUT_DRAIN, &buffer[0], &len);
    cyg_io_get_config(handle, 
                      CYG_IO_GET_CONFIG_SERIAL_INPUT_FLUSH, &buffer[0], &len);
    cyg_io_get_config(handle, 
                      CYG_IO_GET_CONFIG_SERIAL_ABORT, &buffer[0], &len);
    cyg_io_get_config(handle, 
                      CYG_IO_GET_CONFIG_SERIAL_OUTPUT_FLUSH, &buffer[0], &len);

    // cyg_io_set_config
    cyg_io_set_config(handle, 
                      CYG_IO_SET_CONFIG_SERIAL_INFO, &buffer[0], &len);
}
//===========================================================================
//                             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 #11
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 #12
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 #13
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)
}
Beispiel #14
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 #15
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 #16
0
//===========================================================================
//                             READER THREAD 
//===========================================================================
void can0_thread(cyg_addrword_t data)
{
    cyg_uint32             len;
    cyg_can_event          rx_event1;
    cyg_can_event          rx_event2;
    cyg_can_msgbuf_info    msgbox_info;
    cyg_can_mode           mode; 
    cyg_can_state          state;
    
   
    diag_printf("Test of FlexCAN standby mode with selfwakeup\n"
                "As soon as a message arrives the FlexCAN modul\n"
                "will leave standby and generates a leave standby event.\n"
                "Each time you send a message you should see LSTY first\n"
                "for \"leaving standby\" and then \"RX\" for the\n"
                "RX event that caused the leave standby event. You can send\n"
                "a CAN data frame with any ID\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)
    {
       //
       // now we set FlexCAN into standby mode
       //
       mode = CYGNUM_CAN_MODE_STANDBY;
       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 in standby mode
       //
       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_STANDBY)
       {
           CYG_TEST_FAIL_FINISH("Error stopping FlexCAN /dev/can0");
       }
       
       //
       // as soon as a message arrives the FlexCAN modul leaves standby mode
       // and we should receive a CYGNUM_CAN_EVENT_LEAVING_STANDBY event but
       // we will also receive a RX event because a message arrived
       // 
       len = sizeof(rx_event1);      
       if (ENOERR != cyg_io_read(hDrvFlexCAN, &rx_event1, &len))
       {
           CYG_TEST_FAIL_FINISH("Error reading from /dev/can0");
       }
       
       len = sizeof(rx_event2);      
       if (ENOERR != cyg_io_read(hDrvFlexCAN, &rx_event2, &len))
       {
           CYG_TEST_FAIL_FINISH("Error reading from /dev/can0");
       }
       
       print_can_flags(rx_event1.flags, "");
       print_can_flags(rx_event2.flags, "");
       
       //
       // The first event we receive should be a leaving standby event because
       // first flexcan leaves standby and then a message will be received
       // 
       if (!(rx_event1.flags & CYGNUM_CAN_EVENT_LEAVING_STANDBY))
       {
           CYG_TEST_FAIL_FINISH("CYGNUM_CAN_EVENT_LEAVING_STANDBY event expexted /dev/can0");
       }
       
       if (rx_event2.msg.id == 0x100)
       {
           CYG_TEST_PASS_FINISH("flexcan_wake test OK");
       }
    }              
}
Beispiel #17
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, "");   
            }
        }
    }         
}
Beispiel #18
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 #19
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 #20
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 #21
0
void
console_test( CYG_ADDRWORD x )
{
    Cyg_ErrNo res;
    cyg_io_handle_t handle;
    char msg[] = "This is a test\n";
    int msglen = sizeof(msg)-1;
    char in_msg[80];
    int in_msglen = sizeof(in_msg)-1;
    cyg_serial_info_t serial_info;
    cyg_tty_info_t tty_info;
    char short_msg[] = "This is a short message\n";
    char long_msg[] = "This is a longer message 0123456789abcdefghijklmnopqrstuvwxyz\n";
    char filler[] = "          ";
    char prompt[] = "\nPlease enter some data: ";
    int i, len;

    res = cyg_io_lookup(CYGDAT_IO_SERIAL_TTY_CONSOLE, &handle);
    if (res != ENOERR) {
        diag_printf("Can't lookup - DEVIO error: %d\n", res);
        return;
    }
    len = sizeof(serial_info);
    res = cyg_io_get_config(handle, CYG_IO_GET_CONFIG_SERIAL_INFO, &serial_info, &len);
    if (res != ENOERR) {
        diag_printf("Can't get serial config - DEVIO error: %d\n", res);
hang();
        return;
    }
    len = sizeof(tty_info);
    res = cyg_io_get_config(handle, CYG_IO_GET_CONFIG_TTY_INFO, &tty_info, &len);
    if (res != ENOERR) {
        diag_printf("Can't get tty config - DEVIO error: %d\n", res);
hang();
        return;
    }
    diag_printf("Config - baud: %d, stop: %d, parity: %d, out flags: %x, in flags: %x\n", 
                serial_info.baud, serial_info.stop, serial_info.parity,
                tty_info.tty_out_flags, tty_info.tty_in_flags);
    len = sizeof(serial_info);
    res = cyg_io_set_config(handle, CYG_IO_SET_CONFIG_SERIAL_INFO, &serial_info, &len);
    if (res != ENOERR) {
        diag_printf("Can't set serial config - DEVIO error: %d\n", res);
hang();
        return;
    }
    len = sizeof(tty_info);
    res = cyg_io_set_config(handle, CYG_IO_SET_CONFIG_TTY_INFO, &tty_info, &len);
    if (res != ENOERR) {
        diag_printf("Can't set tty config - DEVIO error: %d\n", res);
hang();
        return;
    }
    msglen = strlen(msg);
    res = cyg_io_write(handle, msg, &msglen);
    if (res != ENOERR) {
        diag_printf("Can't write data - DEVIO error: %d\n", res);
hang();
        return;
    }
    for (i = 0;  i < 10;  i++) {
        len = strlen(short_msg);
        res = cyg_io_write(handle, short_msg, &len);
        if (res != ENOERR) {
            diag_printf("Can't write [short] data - DEVIO error: %d\n", res);
            hang();
            return;
        }
    }
    for (i = 0;  i < 100;  i++) {
        len = (i % 10) + 1;
        cyg_io_write(handle, filler, &len);
        len = strlen(long_msg);
        res = cyg_io_write(handle, long_msg, &len);
        if (res != ENOERR) {
            diag_printf("Can't write [long] data - DEVIO error: %d\n", res);
            hang();
            return;
        }
    }
    len = strlen(prompt);
    cyg_io_write(handle, prompt, &len);
    res = cyg_io_read(handle, in_msg, &in_msglen);
    if (res != ENOERR) {
        diag_printf("Can't read data - DEVIO error: %d\n", res);
hang();
        return;
    }
    diag_printf("Read %d bytes\n", in_msglen);
    dump_buf(in_msg, in_msglen);
    CYG_TEST_PASS_FINISH("Console I/O test OK");
}
Beispiel #22
0
static Cyg_ErrNo 
termios_read(cyg_io_handle_t handle, void *_buf, cyg_uint32 *len)
{
    cyg_devtab_entry_t *dt = (cyg_devtab_entry_t *)handle;
    struct termios_private_info *priv = (struct termios_private_info *)dt->priv;
    cyg_io_handle_t chan = (cyg_io_handle_t)priv->dev_handle;
    struct termios *t = &priv->termios;
    cyg_uint32 clen;
    cyg_uint32 size;
    Cyg_ErrNo res;
    cyg_uint8 c;
    cyg_uint8 *buf = (cyg_uint8 *)_buf;
    cyg_bool discardc; // should c be discarded (not read, not printed)
    cyg_bool returnnow = false; // return back to user after this char
    
    // if receiver off
    if (0 == (t->c_cflag & CREAD) ) {
        *len = 0;
        return -EINVAL;
    }

    size = 0;
    if ( 0 == (t->c_lflag & ICANON) ) {
        // In non-canonical mode we return the min of *len and the
        // number of bytes available
        // So we query the driver for how many bytes are available - this
        // guarantees we won't block
        cyg_serial_buf_info_t dev_buf_conf;
        cyg_uint32 dbc_len = sizeof( dev_buf_conf );
        res = cyg_io_get_config( chan,
                                 CYG_IO_GET_CONFIG_SERIAL_BUFFER_INFO,
                                 &dev_buf_conf, &dbc_len );
        CYG_ASSERT( res == ENOERR, "Query buffer status failed!" );
        if (dev_buf_conf.rx_count > 0) {
            // Adjust length to be max characters currently available
            *len = *len < dev_buf_conf.rx_count ? *len : dev_buf_conf.rx_count;
        } else if (t->c_cc[VMIN] == 0) {
            // No chars available - don't block
            *len = 0;
            return ENOERR;
        }
    } // if

    while (!returnnow && size < *len) {
        clen = 1;
        discardc = false;
        res = cyg_io_read(chan, &c, &clen);
        if (res != ENOERR) {
            *len = size;
            return res;
        }

        // lock to prevent termios getting corrupted while we read from it
        cyg_drv_mutex_lock( &priv->lock );

        if ( t->c_iflag & ISTRIP )
            c &= 0x7f;

        // canonical mode: erase, kill, and newline processing
        if ( t->c_lflag & ICANON ) {
            if ( t->c_cc[ VERASE ] == c ) {
                discardc = true;
                // erase on display?
                if ( (t->c_lflag & ECHO) && (t->c_lflag & ECHOE) ) {
                    cyg_uint8 erasebuf[3];
                    erasebuf[0] = erasebuf[2] = t->c_cc[ VERASE ];
                    erasebuf[1] = ' ';
                    clen = sizeof(erasebuf);
                    // FIXME: what about error or non-blocking?
                    cyg_io_write(chan, erasebuf, &clen);
                }
                if ( size )
                    size--;
            } // if
            else if ( t->c_cc[ VKILL ] == c ) {
                // kill line on display?
                if ( (t->c_lflag & ECHO) && (t->c_lflag & ECHOK) ) {

                    // we could try and be more efficient here and 
                    // output a stream of erases, and then a stream
                    // of spaces and then more erases. But this is poor
                    // because on a slow terminal the user will see characters
                    // delete from the middle forward in chunks!
                    // But at least we try and chunk up sets of writes
                    cyg_uint8 erasebuf[30];
                    cyg_uint8 erasechunks;
                    cyg_uint8 i;

                    erasechunks = size < (sizeof(erasebuf)/3) ? 
                        size : (sizeof(erasebuf)/3);

                    for (i=0; i<erasechunks; i++) {
                        erasebuf[i*3] = erasebuf[i*3+2] = t->c_cc[ VERASE ];
                        erasebuf[i*3+1] = ' ';
                    }

                    while( size ) {
                        cyg_uint8 j;

                        j = size < (sizeof(erasebuf)/3) ? 
                            size : (sizeof(erasebuf)/3);
                        clen = (j*3);
                        // FIXME: what about error or non-blocking?
                        cyg_io_write( chan, erasebuf, &clen );
                        size -= j;
                    }
                } else
                    size = 0;
                discardc = true;
            } // else if
            // CR
            else if ( '\r' == c ) {
                if ( t->c_iflag & IGNCR )
                    discardc = true;
                else if ( t->c_iflag & ICRNL )
                    c = '\n';
            }
            // newlines or similar.
            // Note: not an else if to catch CRNL conversion
            if ( (t->c_cc[ VEOF ] == c) || (t->c_cc[ VEOL ] == c) ||
                 ('\n' == c) ) {
                if ( t->c_cc[ VEOF ] == c )
                     discardc = true;
                if ( t->c_lflag & ECHONL ) { // don't check ECHO in this case
                    clen = 1;
                    // FIXME: what about error or non-blocking?
                    // FIXME: what if INLCR is set?
                    cyg_io_write( chan, "\n", &clen );
                }
                if ( t->c_iflag & INLCR )
                    c = '\r';
                returnnow = true; // FIXME: true even for INLCR?
            } // else if
        } // if 

#ifdef CYGSEM_IO_SERIAL_TERMIOS_USE_SIGNALS
        if ( (t->c_lflag & ISIG) && (t->c_cc[ VINTR ] == c) ) {
            discardc = true;
            if ( 0 == (t->c_lflag & NOFLSH) )
                size = 0;
            // raise could be a non-local jump - we should unlock mutex
            cyg_drv_mutex_unlock( &priv->lock ); 

            // FIXME: what if raise returns != 0?
            raise( SIGINT );
            cyg_drv_mutex_lock( &priv->lock ); 
        } 

        if ( (t->c_lflag & ISIG) && (t->c_cc[ VQUIT ] == c) ) {
            discardc = true;
            if ( 0 == (t->c_lflag & NOFLSH) )
                size = 0;
            // raise could be a non-local jump - we should unlock mutex
            cyg_drv_mutex_unlock( &priv->lock ); 

            // FIXME: what if raise returns != 0?
            raise( SIGQUIT );
            cyg_drv_mutex_lock( &priv->lock ); 
        } 
#endif
        if (!discardc) {
            buf[size++] = c;
            if ( t->c_lflag & ECHO ) {
                clen = 1;
                // FIXME: what about error or non-blocking?
                termios_write( handle, &c, &clen );
            }
        }

        if ( (t->c_lflag & ICANON) == 0 ) {
            // Check to see if read has been satisfied
            if ( t->c_cc[ VMIN ] && (size >= t->c_cc[ VMIN ]) )
                returnnow = true;
        }
        cyg_drv_mutex_unlock( &priv->lock );
    } // while

    *len = size;
    return ENOERR;
}
Beispiel #23
0
//===========================================================================
//                             ADC THREAD
//===========================================================================
void adc_thread(cyg_addrword_t data)
{
    int             res;
    cyg_io_handle_t handle[8]     = {0, 0, 0, 0, 0, 0, 0, 0};
    cyg_uint32      sample_cnt[8] = {0, 0, 0, 0, 0, 0, 0, 0};
    cyg_uint32      cfg_data;
    cyg_uint32      len;
    cyg_uint32      start_time;
    cyg_uint32      end_time;
    int             i;
    cyg_uint8       seconds = 0;
    float           final_seconds;
    cyg_uint32      samples_expected;


    diag_printf("This test reads samples from all enabled ADC channels.\n"
                "Each second the number of already acquired samples\n"
                "will be printed. After 10 seconds all ADC channels\n"
                "will be stopped and each ADC buffer will be read until\n"
                "it is empty. If the number of acquired samples is much\n"
                "smaller than the number of expected samples, then you\n"
                "should lower the sample rate.\n\n");

    // Get a handle for ADC device 0 channel 1 - 8
    res = cyg_io_lookup( "/dev/adc00", &handle[0]);
    res = cyg_io_lookup( "/dev/adc01", &handle[1]);
    res = cyg_io_lookup( "/dev/adc02", &handle[2]);
    res = cyg_io_lookup( "/dev/adc03", &handle[3]);
    res = cyg_io_lookup( "/dev/adc04", &handle[4]);
    res = cyg_io_lookup( "/dev/adc05", &handle[5]);
    res = cyg_io_lookup( "/dev/adc06", &handle[6]);
    res = cyg_io_lookup( "/dev/adc07", &handle[7]);

    //
    // switch all channels to non blocking
    //
    for (i = 0; i < 8; ++i)
    {
        if (handle[i])
        {
            cfg_data = 0;
            len = sizeof(cfg_data);
            res = cyg_io_set_config(handle[i],
                                    CYG_IO_SET_CONFIG_READ_BLOCKING,
                                    &cfg_data,
                                    &len);
            if (ENOERR != res)
            {
                CYG_TEST_FAIL_FINISH("Error switching ADC channel to non blocking");
            }
            sample_cnt[i] = 0;
        } // if (handle[i])
    } // for (i = 0; i < 8; ++i)

    start_time = cyg_current_time();
    do
    {
        for (i = 0; i < 8; ++i)
        {
            if (handle[i])
            {
                cyg_adc_sample_t sample;

                // read a sample from the channel
                do
                {
                    cyg_uint32 len = sizeof(sample);
                    res = cyg_io_read( handle[i], &sample, &len );
                }
                while (-EAGAIN == res);
                if (ENOERR == res)
                {
                    sample_cnt[i]++;
                }
            } // if (handle[i])
        }
        //
        // print number of acquired samples - if one second is expired.
        // we expect that the number of acquired samples is nearly the
        // sample rate
        //
        end_time = cyg_current_time();
        if ((end_time - start_time) >= 100)
        {
            start_time = end_time;
            diag_printf("%d\t %d\t %d\t %d\t %d\t %d\t %d\t %d\n",
                        sample_cnt[0],
                        sample_cnt[1],
                        sample_cnt[2],
                        sample_cnt[3],
                        sample_cnt[4],
                        sample_cnt[5],
                        sample_cnt[6],
                        sample_cnt[7]);
            seconds++;
        } // if ((end_time - start_time) >= 100)
    } while (seconds < 10);

    //
    // Now stop all channels
    //
    for (i = 0; i < 8; ++i)
    {
        if (handle[i])
        {
            res = cyg_io_set_config(handle[i],
                                    CYG_IO_SET_CONFIG_ADC_DISABLE,
                                    0,
                                    0);
            if (ENOERR != res)
            {
                CYG_TEST_FAIL_FINISH("Error disabling ADC channel");
            }
        } // if (handle[i])
    }
    end_time = cyg_current_time();
    end_time = seconds * 1000 + (end_time - start_time) * 10;
    final_seconds = end_time / 1000.0;

    //
    // Now read all remaining samples from buffer
    //
    for (i = 0; i < 8; ++i)
    {
        if (handle[i])
        {
            do
            {
                cyg_adc_sample_t sample;
                cyg_uint32 len = sizeof(sample);
                res = cyg_io_read( handle[i], &sample, &len );
                if (ENOERR == res)
                {
                    sample_cnt[i]++;
                }
            } while (ENOERR == res);
        } // if (handle[i])
    }

    diag_printf("\n\n----------------------------------------\n");
    samples_expected = final_seconds * CYGNUM_DEVS_ADC_ARM_LPC24XX_DEFAULT_RATE;
    diag_printf("Samples expected after %d milliseconds: %d\n",
                end_time, samples_expected);
    diag_printf("Samples read (per channel):\n");
    diag_printf("%d\t %d\t %d\t %d\t %d\t %d\t %d\t %d\n",
                sample_cnt[0],
                sample_cnt[1],
                sample_cnt[2],
                sample_cnt[3],
                sample_cnt[4],
                sample_cnt[5],
                sample_cnt[6],
                sample_cnt[7]);

    CYG_TEST_PASS_FINISH("ADC test OK");
}