Esempio n. 1
0
static Cyg_ErrNo 
termios_write(cyg_io_handle_t handle, const void *_buf, cyg_uint32 *len)
{
    cyg_devtab_entry_t *t = (cyg_devtab_entry_t *)handle;
    struct termios_private_info *priv = (struct termios_private_info *)t->priv;
    cyg_io_handle_t chan = (cyg_io_handle_t)priv->dev_handle;
    cyg_int32 xbufsize, input_bytes_read;
    cyg_uint8 xbuf[WRITE_BUFSIZE];
    cyg_uint8 *buf = (cyg_uint8 *)_buf;
    Cyg_ErrNo res;

    xbufsize = input_bytes_read = 0;
    while (input_bytes_read++ < *len) {
        if ( (*buf == '\n') && (priv->termios.c_oflag & (OPOST|ONLCR)) ) {
            xbuf[xbufsize++] = '\r';
        }
        xbuf[xbufsize++] = *buf;
        if ((xbufsize >= (WRITE_BUFSIZE-1)) || (input_bytes_read == *len) ||
            (*buf == '\n'))
        {
            cyg_int32 size = xbufsize;
            res = cyg_io_write(chan, xbuf, &size);
            if (res != ENOERR) {
                *len = input_bytes_read - (xbufsize - size);
                return res;
            }
            xbufsize = 0;
        }
        buf++;
    }
    // Everything sent, so *len is correct.
    return ENOERR;
}
Esempio n. 2
0
static Cyg_ErrNo 
termios_write(cyg_io_handle_t handle, const void *_buf, cyg_uint32 *len)
{
    cyg_devtab_entry_t *t = (cyg_devtab_entry_t *)handle;
    struct termios_private_info *priv = (struct termios_private_info *)t->priv;
    cyg_io_handle_t chan = (cyg_io_handle_t)priv->dev_handle;
    cyg_int32 size, bytes_successful, actually_written;
    cyg_uint8 xbuf[WRITE_BUFSIZE];
    cyg_uint8 *buf = (cyg_uint8 *)_buf;
    Cyg_ErrNo res;

    size = 0;
    bytes_successful = 0;
    actually_written = 0;
    while (bytes_successful++ < *len) {
        xbuf[size] = *buf++;
        if ( (xbuf[size] == '\n') && (priv->termios.c_oflag & ONLCR) ) {
            xbuf[size] = '\r';
        }
        size++;
        if ((size == (WRITE_BUFSIZE-1)) ||
            (bytes_successful == *len)) {
            res = cyg_io_write(chan, xbuf, &size);
            if (res != ENOERR) {
                *len = actually_written;
                return res;
            }
            actually_written += size;
            size = 0;
        }
    }
    *len = actually_written;
    return ENOERR;
}
Esempio n. 3
0
//===========================================================================
// Thread 1
//===========================================================================
void can_tx_thread(cyg_addrword_t data)
{
    cyg_uint32      len;
    cyg_can_message tx_msg;
    cyg_uint32      msg_cnt = 0;
    cyg_uint8       i;

    
    CYG_CAN_MSG_SET_PARAM(tx_msg, 0, CYGNUM_CAN_ID_STD, 0, CYGNUM_CAN_FRAME_DATA);
    
    //
    // Prepare CAN message with a known CAN state
    //
    for (i = 0; i < 8; ++i)
    {
        tx_msg.data.bytes[i] = i; 
    }
    
    while (msg_cnt < 0xF0)
    {
        tx_msg.id = msg_cnt;
        len = sizeof(tx_msg);
        if (ENOERR != cyg_io_write(hCAN_Tbl[0], &tx_msg, &len))
        {
            CYG_TEST_FAIL_FINISH("Error writing to channel 0");    
        }
        
        
        tx_msg.id = msg_cnt;
        len = sizeof(tx_msg);
        if (ENOERR != cyg_io_write(hLoopCAN_Tbl[0], &tx_msg, &len))
        {
            CYG_TEST_FAIL_FINISH("Error writing to channel 1");    
        }
        
        //
        // Increment data in each single data byte
        //
        for (i = 0; i < 8; ++i)
        {
            tx_msg.data.bytes[i] += 1;    
        }
        
        msg_cnt++;
        tx_msg.dlc = (tx_msg.dlc + 1) % 9;
    } // while (msg_cnt < 0x100)
}
Esempio n. 4
0
/*
 * Sends a single character to the serial device.
 */
void sio_send(u8_t c, sio_fd_t fd)
{
    cyg_uint32 len = 1;
    
#ifdef CYGDBG_LWIP_DEBUG_SIO
    diag_printf("sio_send(c=0x%02x,fd=%p)\n", c, fd);
#endif
    
	cyg_io_write((cyg_io_handle_t) fd, &c, &len);
}
Esempio n. 5
0
static void
uart_putchar(void *base, char c)
{
    char buf;
    int len;
    struct BSP_IO *io = (struct BSP_IO *)base;
    if (io->chan) {
        len = 1;
        buf = c;
        cyg_io_write(io->chan, &buf, &len);
    }
}
Esempio n. 6
0
// This function is mostly used by the 'write()' system call
static void
uart_write(void *base, const char *buf, int len)
{
    struct BSP_IO *io = (struct BSP_IO *)base;
    if (io->chan) {
        if (stub_is_active) {
            // We are running in 'GDB' mode
            __output_gdb_string(buf, len);
        } else {
            cyg_io_write(io->chan, buf, &len);
        }
    }
}
Esempio n. 7
0
int hci_uart_tx_wakeup(struct hci_uart *hu)
{
	cyg_io_handle_t serial = hu->tty;
	struct hci_dev *hdev = &hu->hdev;
	struct sk_buff *skb;
	
	if (test_and_set_bit(HCI_UART_SENDING, &hu->tx_state)) {
		set_bit(HCI_UART_TX_WAKEUP, &hu->tx_state);
		return 0;
	}

//	BT_DBG("");

restart:
	clear_bit(HCI_UART_TX_WAKEUP, &hu->tx_state);
	while ((skb = hci_uart_dequeue(hu))) {
		int len = skb->len;
		int ret;
	
		//set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
		//len = tty->driver.write(tty, 0, skb->data, skb->len);//UART write
		//diag_printf("write skb = %x\n",skb);
		//diag_printf("data[0] %x %x %x %x\n",skb->data[0],skb->data[1],skb->data[2],skb->data[3]);
		ret = (int)cyg_io_write(serial, skb->data, (cyg_uint32*)&len);
		if(ret != ENOERR)
			break;

		hdev->stat.byte_tx += len;

		skb_pull(skb, len);
		if (skb->len) {
			hu->tx_skb = skb;
			break;
		}
	
		hci_uart_tx_complete(hu, skb->pkt_type);
		kfree_skb(skb);
	} 
	
	if (test_bit(HCI_UART_TX_WAKEUP, &hu->tx_state))
		goto restart;

	clear_bit(HCI_UART_SENDING, &hu->tx_state);
	return 0;
}
Esempio n. 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);
}
Esempio n. 9
0
static void simple_prog(CYG_ADDRESS data)
{
    cyg_io_handle_t handle;
    Cyg_ErrNo err;
    const char test_string[] = "serial example is working correctly!\n";
    cyg_uint32 len = strlen(test_string);

    printf("Starting serial example\n");

    err = cyg_io_lookup( "/dev/haldiag", &handle );

    if (ENOERR == err) {
        printf("Found /dev/haldiag. Writing string....\n");
        err = cyg_io_write( handle, test_string, &len );
    }
        
    if (ENOERR == err) {
        printf("I think I wrote the string. Did you see it?\n");
    }
    
    printf("Serial example finished\n");

}
Esempio n. 10
0
/*
 * Writes to the serial device.
 */
u32_t sio_write(sio_fd_t fd, u8_t *data, u32_t len)
{
    Cyg_ErrNo ret;
    cyg_uint32 count = 0;
    cyg_uint32 chunk;
    
#ifdef CYGDBG_LWIP_DEBUG_SIO
    diag_printf("sio_write(fd=%p,data=%p,len=%lu:)\n", fd, data, len);
    diag_printf("sio_write: ");
    diag_dump_buf(data, len);
#endif

    while (count < len) {
        chunk = len - count;
        ret = cyg_io_write((cyg_io_handle_t) fd, data, &chunk);
        if (ret != ENOERR)
            break;
        data += chunk;
        count += chunk;
    }
    
	return count;
}
Esempio n. 11
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);
}
Esempio n. 12
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;
}
Esempio n. 13
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)
}
Esempio n. 14
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");
}
Esempio n. 15
0
/*-------------------------------------------------------------------------+
| function: enviar mensagem (em buffer hexadecimal) para o PIC
+--------------------------------------------------------------------------*/
Cyg_ErrNo send_buffer (char msgToSend[], unsigned int length) {
	printf("%d\n", length); 
	err = cyg_io_write(serH, msgToSend, &length);
	return err;
}
Esempio n. 16
0
//===========================================================================
//                             READER THREAD 
//===========================================================================
void can_thread(cyg_addrword_t data)
{
    cyg_uint32              len;
    cyg_can_message         tx_msg;
    cyg_can_info_t          can_info;
    cyg_can_baud_rate_t     baud;
    cyg_uint8               i = 0;
    cyg_uint8               j = 0;

    //
    // Check that all cannels have the same baudrate
    //
#ifdef CYGPKG_DEVS_CAN_LPC2XXX_CAN0
    len = sizeof(can_info);
    if (ENOERR != cyg_io_get_config(hCAN_Tbl[0], CYG_IO_GET_CONFIG_CAN_INFO, &can_info, &len))
    {
        CYG_TEST_FAIL_FINISH("Error reading baudrate of CAN channel 0");    
    } 
    else
    {
        baud = can_info.baud;
        ++i;
    }
#endif
    
#ifdef CYGPKG_DEVS_CAN_LPC2XXX_CAN1
    len = sizeof(can_info);
    if (ENOERR != cyg_io_get_config(hCAN_Tbl[1], CYG_IO_GET_CONFIG_CAN_INFO, &can_info, &len))
    {
        CYG_TEST_FAIL_FINISH("Error reading baudrate of CAN channel 1");    
    }
    else
    {
        if (i && (baud != can_info.baud))
        {
            CYG_TEST_FAIL_FINISH("Error - different baudrates for CAN channel 0 and 1");               
        }
        baud = can_info.baud;
        ++i;
    }
#endif
    
#ifdef CYGPKG_DEVS_CAN_LPC2XXX_CAN2
    len = sizeof(can_info);
    if (ENOERR != cyg_io_get_config(hCAN_Tbl[2], CYG_IO_GET_CONFIG_CAN_INFO, &can_info, &len))
    {
        CYG_TEST_FAIL_FINISH("Error reading baudrate of CAN channel 2");    
    } 
    else
    {
        if (i && (baud != can_info.baud))
        {
            CYG_TEST_FAIL_FINISH("Error - different baudrates for CAN channel 1 and 2");               
        }
        baud = can_info.baud;
        ++i;
    }
#endif
    
#ifdef CYGPKG_DEVS_CAN_LPC2XXX_CAN3
    len = sizeof(can_info);
    if (ENOERR != cyg_io_get_config(hCAN_Tbl[3], CYG_IO_GET_CONFIG_CAN_INFO, &can_info, &len))
    {
        CYG_TEST_FAIL_FINISH("Error reading baudrate of CAN channel 3");    
    }
    else
    {
        if (i && (baud != can_info.baud))
        {
            CYG_TEST_FAIL_FINISH("Error - different baudrates for CAN channel 2 and 3");               
        }
        baud = can_info.baud;
        ++i;
    }
#endif
    
    diag_printf("\n\nYou should no receive 4 CAN messages from each active CAN channel\n");
    
    //
    // Now each CAN channel sends 10 CAN messages
    //
    for (i = 0; i < 4; ++i)
    {
        if (hCAN_Tbl[i])
        {
            CYG_CAN_MSG_SET_PARAM(tx_msg, i * 0x100, CYGNUM_CAN_ID_STD, 4, CYGNUM_CAN_FRAME_DATA);
            tx_msg.data.dwords[0] = 0;
            tx_msg.data.dwords[1] = 0;
            char err_msg[64];
            diag_snprintf(err_msg, sizeof(err_msg), "Error sending TX using CAN channel %d", i);
            for (j = 0; j < 4; ++j)
            {
                tx_msg.id = i * 0x100 + j; 
                tx_msg.data.bytes[0] = j;
                len = sizeof(tx_msg);
                if (ENOERR != cyg_io_write(hCAN_Tbl[i], &tx_msg, &len))
                {
                    CYG_TEST_FAIL_FINISH(err_msg);     
                }
            }
        } //  if (hCAN_Tbl[i])
    } // for (i = 0; i < 4; ++i)
    
    CYG_TEST_PASS_FINISH("LPC2xxx CAN multi channel TX test OK");
}
Esempio n. 17
0
//===========================================================================
//                             READER THREAD 
//===========================================================================
void can_thread(cyg_addrword_t data)
{
    cyg_uint32              len;
    cyg_can_callback_cfg    callback_cfg;
    cyg_can_message         tx_msg;
    cyg_bool_t              wait_res;
    
    //
    // open CAN0 device driver
    //
    if (ENOERR != cyg_io_lookup("/dev/can0", &hCAN0)) 
    {
        CYG_TEST_FAIL_FINISH("Error opening /dev/can0");
    }
    
    //
    // open CAN1 device driver
    //
    if (ENOERR != cyg_io_lookup("/dev/can1", &hCAN1)) 
    {
        CYG_TEST_FAIL_FINISH("Error opening /dev/can1");
    }
    
    //
    // configure CAN0 callback
    //
    len = sizeof(callback_cfg);
    callback_cfg.flag_mask = 0xFFFF;
    callback_cfg.data = (CYG_ADDRWORD) hCAN0;
    callback_cfg.callback_func = callback_func;
    
    if (ENOERR != cyg_io_set_config(hCAN0, CYG_IO_SET_CONFIG_CAN_CALLBACK,
            &callback_cfg, &len))
    {
        CYG_TEST_FAIL_FINISH("Error writing config of /dev/can0");
    }
    
    //
    // transmit message from CAN1 to CAN0
    //
    tx_msg.id  = 0x001;
    tx_msg.ext = CYGNUM_CAN_ID_STD;
    tx_msg.rtr = CYGNUM_CAN_FRAME_DATA;
    tx_msg.dlc = 0;
    len = sizeof(tx_msg); 
    
    if (ENOERR != cyg_io_write(hCAN1, &tx_msg, &len))
    {
        CYG_TEST_FAIL_FINISH("Error writing message to /dev/can1");
    }
    
    //
    // Wait CAN0 callback
    //
    cyg_mutex_lock(&can_lock);
    
    wait_res = cyg_cond_timed_wait(&can_wait, 100);
    
    cyg_mutex_unlock(&can_lock);
    
    //
    // If result of wait is a signal operation, test is successed
    // If timeout - test is failed, because callback_func() hasn't been
    // called with correct parameters
    //
    if(wait_res)
    {
        CYG_TEST_PASS_FINISH("can_callback test OK");
    }
    else
    {
        CYG_TEST_FAIL_FINISH("can_callback test FAILED");
    }
}
Esempio n. 18
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");                     
}
Esempio n. 19
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());                 
}
Esempio n. 20
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)  
        }
        
    }
}