📄 usbs.c
字号:
//==========================================================================
//
// usbs.c
//
// Generic USB slave-side support
//
//==========================================================================
//####COPYRIGHTBEGIN####
//
// -------------------------------------------
// The contents of this file are subject to the Red Hat eCos Public License
// Version 1.1 (the "License"); you may not use this file except in
// compliance with the License. You may obtain a copy of the License at
// http://www.redhat.com/
//
// Software distributed under the License is distributed on an "AS IS"
// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
// License for the specific language governing rights and limitations under
// the License.
//
// The Original Code is eCos - Embedded Configurable Operating System,
// released September 30, 1998.
//
// The Initial Developer of the Original Code is Red Hat.
// Portions created by Red Hat are
// Copyright (C) 2000, 2001 Red Hat, Inc.
// All Rights Reserved.
// -------------------------------------------
//
//####COPYRIGHTEND####
//==========================================================================
//#####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);
while (!wait.completed) {
cyg_drv_cond_wait(&wait.signal);
}
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);
while (!wait.completed) {
cyg_drv_cond_wait(&wait.signal);
}
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;
endpoint->complete_fn = callback_fn;
endpoint->complete_data = callback_arg;
(*endpoint->start_tx_fn)(endpoint);
}
void
usbs_start(usbs_control_endpoint* endpoint)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -