📄 usbs.c
字号:
//==========================================================================
//
// usbs.c
//
// Generic USB slave-side support
//
//==========================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
//
// eCos is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 or (at your option) any later version.
//
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with eCos; if not, write to the Free Software Foundation, Inc.,
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
//
// As a special exception, if other files instantiate templates or use macros
// or inline functions from this file, or you compile this file and link it
// with other works to produce a work based on this file, this file does not
// by itself cause the resulting work to be covered by the GNU General Public
// License. However the source code for this file must still be made available
// in accordance with section (3) of the GNU General Public License.
//
// This exception does not invalidate any other reasons why a work based on
// this file might be covered by the GNU General Public License.
//
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
// at http://sources.redhat.com/ecos/ecos-license/
// -------------------------------------------
//####ECOSGPLCOPYRIGHTEND####
//==========================================================================
//#####DESCRIPTIONBEGIN####
//
// Author(s): bartv
// Contributors: bartv
// Date: 2000-10-04
//
//####DESCRIPTIONEND####
//
//==========================================================================
#include <pkgconf/system.h>
#include <cyg/infra/cyg_type.h>
#include <cyg/infra/cyg_ass.h>
#include <cyg/infra/cyg_trac.h>
#include <cyg/infra/diag.h>
#include <cyg/io/usb/usbs.h>
#include <cyg/hal/drv_api.h>
// ----------------------------------------------------------------------------
// Devtab entry support. This code can be compiled with no overheads as
// long as the necessary support package is in place.
#ifdef CYGPKG_IO
# include <cyg/io/io.h>
# include <cyg/io/devtab.h>
// ----------------------------------------------------------------------------
// read()/write() functions applied to USB endpoints. These just
// indirect via the usbs_endpoint structures and wait for the
// callback to happen.
typedef struct usbs_callback_data {
bool completed;
int result;
cyg_drv_mutex_t lock;
cyg_drv_cond_t signal;
} usbs_callback_data;
static void
usbs_devtab_callback(void* arg, int result)
{
usbs_callback_data* callback_data = (usbs_callback_data*) arg;
callback_data->result = result;
callback_data->completed = true;
cyg_drv_cond_signal(&(callback_data->signal));
}
Cyg_ErrNo
usbs_devtab_cwrite(cyg_io_handle_t handle, const void* buf, cyg_uint32* size)
{
usbs_callback_data wait;
cyg_devtab_entry_t* devtab_entry;
usbs_tx_endpoint* endpoint;
int result = ENOERR;
CYG_REPORT_FUNCTION();
wait.completed = 0;
cyg_drv_mutex_init(&wait.lock);
cyg_drv_cond_init(&wait.signal, &wait.lock);
devtab_entry = (cyg_devtab_entry_t*) handle;
CYG_CHECK_DATA_PTR( devtab_entry, "A valid endpoint must be supplied");
endpoint = (usbs_tx_endpoint*) devtab_entry->priv;
CYG_CHECK_DATA_PTR( endpoint, "The handle must correspond to a USB endpoint");
CYG_CHECK_FUNC_PTR( endpoint->start_tx_fn, "The endpoint must have a start_tx function");
endpoint->buffer = (unsigned char*) buf;
endpoint->buffer_size = (int) *size;
endpoint->complete_fn = &usbs_devtab_callback;
endpoint->complete_data = (void*) &wait;
(*endpoint->start_tx_fn)(endpoint);
cyg_drv_mutex_lock(&wait.lock);
cyg_drv_dsr_lock();
while (!wait.completed) {
cyg_drv_cond_wait(&wait.signal);
}
cyg_drv_dsr_unlock();
cyg_drv_mutex_unlock(&wait.lock);
if (wait.result < 0) {
result = wait.result;
} else {
*size = wait.result;
}
cyg_drv_cond_destroy(&wait.signal);
cyg_drv_mutex_destroy(&wait.lock);
CYG_REPORT_RETURN();
return result;
}
Cyg_ErrNo
usbs_devtab_cread(cyg_io_handle_t handle, void* buf, cyg_uint32* size)
{
usbs_callback_data wait;
cyg_devtab_entry_t* devtab_entry;
usbs_rx_endpoint* endpoint;
int result = ENOERR;
CYG_REPORT_FUNCTION();
wait.completed = 0;
cyg_drv_mutex_init(&wait.lock);
cyg_drv_cond_init(&wait.signal, &wait.lock);
devtab_entry = (cyg_devtab_entry_t*) handle;
CYG_CHECK_DATA_PTR( devtab_entry, "A valid endpoint must be supplied");
endpoint = (usbs_rx_endpoint*) devtab_entry->priv;
CYG_CHECK_DATA_PTR( endpoint, "The handle must correspond to a USB endpoint");
CYG_CHECK_FUNC_PTR( endpoint->start_rx_fn, "The endpoint must have a start_rx function");
endpoint->buffer = (unsigned char*) buf;
endpoint->buffer_size = (int) *size;
endpoint->complete_fn = &usbs_devtab_callback;
endpoint->complete_data = (void*) &wait;
(*endpoint->start_rx_fn)(endpoint);
cyg_drv_mutex_lock(&wait.lock);
cyg_drv_dsr_lock();
while (!wait.completed) {
cyg_drv_cond_wait(&wait.signal);
}
cyg_drv_dsr_unlock();
cyg_drv_mutex_unlock(&wait.lock);
if (wait.result < 0) {
result = wait.result;
} else {
*size = wait.result;
}
cyg_drv_cond_destroy(&wait.signal);
cyg_drv_mutex_destroy(&wait.lock);
CYG_REPORT_RETURN();
return result;
}
// ----------------------------------------------------------------------------
// More devtab functions, this time related to ioctl() style operations.
Cyg_ErrNo
usbs_devtab_get_config(cyg_io_handle_t handle, cyg_uint32 code, void* buf, cyg_uint32* size)
{
return -EINVAL;
}
Cyg_ErrNo
usbs_devtab_set_config(cyg_io_handle_t handle, cyg_uint32 code, const void* buf, cyg_uint32* size)
{
return -EINVAL;
}
#endif // CYGPKG_IO
// ----------------------------------------------------------------------------
// USB-specific functions that are useful for applications/packages which
// do not want to use the devtab interface. These may get called in DSR
// context.
void
usbs_start_rx(usbs_rx_endpoint* endpoint)
{
CYG_CHECK_DATA_PTR( endpoint, "A valid USB endpoint must be supplied");
CYG_CHECK_FUNC_PTR( endpoint->start_rx_fn, "The USB endpoint must support receive operations");
(*endpoint->start_rx_fn)(endpoint);
}
void
usbs_start_rx_buffer(usbs_rx_endpoint* endpoint,
unsigned char* buf, int size,
void (*callback_fn)(void *, int), void* callback_arg)
{
CYG_CHECK_DATA_PTR( endpoint, "A valid USB endpoint must be supplied");
CYG_CHECK_FUNC_PTR( endpoint->start_rx_fn, "The USB endpoint must support receive operations");
endpoint->buffer = buf;
endpoint->buffer_size = size;
endpoint->complete_fn = callback_fn;
endpoint->complete_data = callback_arg;
(*endpoint->start_rx_fn)(endpoint);
}
void
usbs_start_tx(usbs_tx_endpoint* endpoint)
{
CYG_CHECK_DATA_PTR( endpoint, "A valid USB endpoint must be supplied");
CYG_CHECK_FUNC_PTR( endpoint->start_tx_fn, "The USB endpoint must support receive operations");
(*endpoint->start_tx_fn)(endpoint);
}
void
usbs_start_tx_buffer(usbs_tx_endpoint* endpoint,
const unsigned char* buf, int size,
void (*callback_fn)(void*, int), void *callback_arg)
{
CYG_CHECK_DATA_PTR( endpoint, "A valid USB endpoint must be supplied");
CYG_CHECK_FUNC_PTR( endpoint->start_tx_fn, "The USB endpoint must support receive operations");
endpoint->buffer = buf;
endpoint->buffer_size = size;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -