change endpoint and class handler
git-svn-id: https://rt-thread.googlecode.com/svn/trunk@2476 bbd45198-f89e-11dd-88c7-29a3b14d5316
This commit is contained in:
parent
834355c76b
commit
53efe928d6
|
@ -9,8 +9,12 @@
|
||||||
*
|
*
|
||||||
* Change Logs:
|
* Change Logs:
|
||||||
* Date Author Notes
|
* Date Author Notes
|
||||||
* 2012-10-03 Yi Qiu first version
|
* 2012-10-03 Yi Qiu first version
|
||||||
|
* 2012-12-12 heyuanjie87 add CDC endpoints collection
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifndef __CDC_H__
|
||||||
|
#define __CDC_H__
|
||||||
|
|
||||||
#define USB_CDC_PRODUCT_ID 0x5740 /* Product ID */
|
#define USB_CDC_PRODUCT_ID 0x5740 /* Product ID */
|
||||||
#define USB_CDC_BUFSIZE 0x40
|
#define USB_CDC_BUFSIZE 0x40
|
||||||
|
@ -153,5 +157,14 @@ struct ucdc_line_coding
|
||||||
};
|
};
|
||||||
typedef struct ucdc_line_coding* ucdc_line_coding_t;
|
typedef struct ucdc_line_coding* ucdc_line_coding_t;
|
||||||
|
|
||||||
|
struct cdc_eps
|
||||||
|
{
|
||||||
|
uep_t ep_out;
|
||||||
|
uep_t ep_in;
|
||||||
|
uep_t ep_cmd;
|
||||||
|
};
|
||||||
|
typedef struct cdc_eps* cdc_eps_t;
|
||||||
|
|
||||||
#pragma pack()
|
#pragma pack()
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -9,7 +9,8 @@
|
||||||
*
|
*
|
||||||
* Change Logs:
|
* Change Logs:
|
||||||
* Date Author Notes
|
* Date Author Notes
|
||||||
* 2012-10-02 Yi Qiu first version
|
* 2012-10-02 Yi Qiu first version
|
||||||
|
* 2012-12-12 heyuanjie87 change endpoints and class handler
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <rtthread.h>
|
#include <rtthread.h>
|
||||||
|
@ -19,9 +20,6 @@
|
||||||
|
|
||||||
#ifdef RT_USB_DEVICE_CDC
|
#ifdef RT_USB_DEVICE_CDC
|
||||||
|
|
||||||
static uclass_t cdc;
|
|
||||||
static uep_t ep_in, ep_out, ep_cmd;
|
|
||||||
|
|
||||||
#define CDC_RX_BUFSIZE 64
|
#define CDC_RX_BUFSIZE 64
|
||||||
#define CDC_TX_BUFSIZE 2048
|
#define CDC_TX_BUFSIZE 2048
|
||||||
static rt_uint8_t rx_pool[CDC_RX_BUFSIZE];
|
static rt_uint8_t rx_pool[CDC_RX_BUFSIZE];
|
||||||
|
@ -145,23 +143,26 @@ static struct ucdc_data_descriptor data_desc =
|
||||||
*
|
*
|
||||||
* @return RT_EOK.
|
* @return RT_EOK.
|
||||||
*/
|
*/
|
||||||
static rt_err_t _ep_in_handler(udevice_t device, rt_size_t size)
|
static rt_err_t _ep_in_handler(udevice_t device, uclass_t cls, rt_size_t size)
|
||||||
{
|
{
|
||||||
rt_uint32_t level;
|
rt_uint32_t level;
|
||||||
rt_size_t length;
|
rt_size_t length;
|
||||||
|
cdc_eps_t eps;
|
||||||
rt_size_t mps = ep_in->ep_desc->wMaxPacketSize;
|
rt_size_t mps;
|
||||||
|
|
||||||
|
eps = (cdc_eps_t)cls->eps;
|
||||||
|
mps = eps->ep_in->ep_desc->wMaxPacketSize;
|
||||||
size = RT_RINGBUFFER_SIZE(&tx_ringbuffer);
|
size = RT_RINGBUFFER_SIZE(&tx_ringbuffer);
|
||||||
if(size == 0) return RT_EOK;
|
if(size == 0) return RT_EOK;
|
||||||
|
|
||||||
length = size > mps ? mps : size;
|
length = size > mps ? mps : size;
|
||||||
|
|
||||||
level = rt_hw_interrupt_disable();
|
level = rt_hw_interrupt_disable();
|
||||||
rt_ringbuffer_get(&tx_ringbuffer, ep_in->buffer, length);
|
rt_ringbuffer_get(&tx_ringbuffer, eps->ep_in->buffer, length);
|
||||||
rt_hw_interrupt_enable(level);
|
rt_hw_interrupt_enable(level);
|
||||||
|
|
||||||
/* send data to host */
|
/* send data to host */
|
||||||
dcd_ep_write(device->dcd, ep_in, ep_in->buffer, length);
|
dcd_ep_write(device->dcd, eps->ep_in, eps->ep_in->buffer, length);
|
||||||
|
|
||||||
return RT_EOK;
|
return RT_EOK;
|
||||||
}
|
}
|
||||||
|
@ -174,22 +175,24 @@ static rt_err_t _ep_in_handler(udevice_t device, rt_size_t size)
|
||||||
*
|
*
|
||||||
* @return RT_EOK.
|
* @return RT_EOK.
|
||||||
*/
|
*/
|
||||||
static rt_err_t _ep_out_handler(udevice_t device, rt_size_t size)
|
static rt_err_t _ep_out_handler(udevice_t device, uclass_t cls, rt_size_t size)
|
||||||
{
|
{
|
||||||
rt_uint32_t level;
|
rt_uint32_t level;
|
||||||
|
cdc_eps_t eps;
|
||||||
|
|
||||||
RT_ASSERT(device != RT_NULL);
|
RT_ASSERT(device != RT_NULL);
|
||||||
|
|
||||||
|
eps = (cdc_eps_t)cls->eps;
|
||||||
/* receive data from USB VCOM */
|
/* receive data from USB VCOM */
|
||||||
level = rt_hw_interrupt_disable();
|
level = rt_hw_interrupt_disable();
|
||||||
rt_ringbuffer_put(&rx_ringbuffer, ep_out->buffer, size);
|
rt_ringbuffer_put(&rx_ringbuffer, eps->ep_out->buffer, size);
|
||||||
rt_hw_interrupt_enable(level);
|
rt_hw_interrupt_enable(level);
|
||||||
|
|
||||||
/* notify receive data */
|
/* notify receive data */
|
||||||
rt_hw_serial_isr(&vcom_serial);
|
rt_hw_serial_isr(&vcom_serial);
|
||||||
|
|
||||||
dcd_ep_read(device->dcd, ep_out, ep_out->buffer,
|
dcd_ep_read(device->dcd, eps->ep_out, eps->ep_out->buffer,
|
||||||
ep_out->ep_desc->wMaxPacketSize);
|
eps->ep_out->ep_desc->wMaxPacketSize);
|
||||||
|
|
||||||
return RT_EOK;
|
return RT_EOK;
|
||||||
}
|
}
|
||||||
|
@ -202,7 +205,7 @@ static rt_err_t _ep_out_handler(udevice_t device, rt_size_t size)
|
||||||
*
|
*
|
||||||
* @return RT_EOK.
|
* @return RT_EOK.
|
||||||
*/
|
*/
|
||||||
static rt_err_t _ep_cmd_handler(udevice_t device, rt_size_t size)
|
static rt_err_t _ep_cmd_handler(udevice_t device, uclass_t cls, rt_size_t size)
|
||||||
{
|
{
|
||||||
RT_ASSERT(device != RT_NULL);
|
RT_ASSERT(device != RT_NULL);
|
||||||
|
|
||||||
|
@ -223,7 +226,8 @@ static rt_err_t _cdc_get_line_coding(udevice_t device, ureq_t setup)
|
||||||
{
|
{
|
||||||
struct ucdc_line_coding data;
|
struct ucdc_line_coding data;
|
||||||
rt_uint16_t size;
|
rt_uint16_t size;
|
||||||
|
rt_err_t ret;
|
||||||
|
|
||||||
RT_ASSERT(device != RT_NULL);
|
RT_ASSERT(device != RT_NULL);
|
||||||
RT_ASSERT(setup != RT_NULL);
|
RT_ASSERT(setup != RT_NULL);
|
||||||
|
|
||||||
|
@ -232,8 +236,9 @@ static rt_err_t _cdc_get_line_coding(udevice_t device, ureq_t setup)
|
||||||
data.bDataBits = 8;
|
data.bDataBits = 8;
|
||||||
data.bParityType = 0;
|
data.bParityType = 0;
|
||||||
size = setup->length > 7 ? 7 : setup->length;
|
size = setup->length > 7 ? 7 : setup->length;
|
||||||
|
|
||||||
dcd_ep_write(device->dcd, 0, (void*)&data, size);
|
dcd_ep_write(device->dcd, 0, (void*)&data, size);
|
||||||
|
|
||||||
return RT_EOK;
|
return RT_EOK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -318,14 +323,15 @@ static rt_err_t _interface_handler(udevice_t device, ureq_t setup)
|
||||||
*
|
*
|
||||||
* @return RT_EOK on successful.
|
* @return RT_EOK on successful.
|
||||||
*/
|
*/
|
||||||
static rt_err_t _class_run(udevice_t device)
|
static rt_err_t _class_run(udevice_t device, uclass_t cls)
|
||||||
{
|
{
|
||||||
|
cdc_eps_t eps;
|
||||||
RT_ASSERT(device != RT_NULL);
|
RT_ASSERT(device != RT_NULL);
|
||||||
|
|
||||||
RT_DEBUG_LOG(RT_DEBUG_USB, ("cdc class run\n"));
|
RT_DEBUG_LOG(RT_DEBUG_USB, ("cdc class run\n"));
|
||||||
|
eps = (cdc_eps_t)cls->eps;
|
||||||
dcd_ep_read(device->dcd, ep_out, ep_out->buffer,
|
dcd_ep_read(device->dcd, eps->ep_out, eps->ep_out->buffer,
|
||||||
ep_out->ep_desc->wMaxPacketSize);
|
eps->ep_out->ep_desc->wMaxPacketSize);
|
||||||
|
|
||||||
return RT_EOK;
|
return RT_EOK;
|
||||||
}
|
}
|
||||||
|
@ -337,7 +343,7 @@ static rt_err_t _class_run(udevice_t device)
|
||||||
*
|
*
|
||||||
* @return RT_EOK on successful.
|
* @return RT_EOK on successful.
|
||||||
*/
|
*/
|
||||||
static rt_err_t _class_stop(udevice_t device)
|
static rt_err_t _class_stop(udevice_t device, uclass_t cls)
|
||||||
{
|
{
|
||||||
RT_ASSERT(device != RT_NULL);
|
RT_ASSERT(device != RT_NULL);
|
||||||
|
|
||||||
|
@ -353,17 +359,19 @@ static rt_err_t _class_stop(udevice_t device)
|
||||||
*
|
*
|
||||||
* @return RT_EOK on successful.
|
* @return RT_EOK on successful.
|
||||||
*/
|
*/
|
||||||
static rt_err_t _class_sof_handler(udevice_t device)
|
static rt_err_t _class_sof_handler(udevice_t device, uclass_t cls)
|
||||||
{
|
{
|
||||||
rt_uint32_t level;
|
rt_uint32_t level;
|
||||||
rt_size_t size;
|
rt_size_t size;
|
||||||
static rt_uint32_t frame_count = 0;
|
static rt_uint32_t frame_count = 0;
|
||||||
|
cdc_eps_t eps;
|
||||||
|
|
||||||
if(vcom_connected != RT_TRUE) return -RT_ERROR;
|
if(vcom_connected != RT_TRUE) return -RT_ERROR;
|
||||||
|
|
||||||
|
eps = (cdc_eps_t)cls->eps;
|
||||||
if (frame_count ++ == 5)
|
if (frame_count ++ == 5)
|
||||||
{
|
{
|
||||||
rt_size_t mps = ep_in->ep_desc->wMaxPacketSize;
|
rt_size_t mps = eps->ep_in->ep_desc->wMaxPacketSize;
|
||||||
|
|
||||||
/* reset the frame counter */
|
/* reset the frame counter */
|
||||||
frame_count = 0;
|
frame_count = 0;
|
||||||
|
@ -374,11 +382,11 @@ static rt_err_t _class_sof_handler(udevice_t device)
|
||||||
size = size > mps ? mps : size;
|
size = size > mps ? mps : size;
|
||||||
|
|
||||||
level = rt_hw_interrupt_disable();
|
level = rt_hw_interrupt_disable();
|
||||||
rt_ringbuffer_get(&tx_ringbuffer, ep_in->buffer, size);
|
rt_ringbuffer_get(&tx_ringbuffer, eps->ep_in->buffer, size);
|
||||||
rt_hw_interrupt_enable(level);
|
rt_hw_interrupt_enable(level);
|
||||||
|
|
||||||
/* send data to host */
|
/* send data to host */
|
||||||
dcd_ep_write(device->dcd, ep_in, ep_in->buffer, size);
|
dcd_ep_write(device->dcd, eps->ep_in, eps->ep_in->buffer, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
return RT_EOK;
|
return RT_EOK;
|
||||||
|
@ -420,6 +428,8 @@ static rt_err_t _cdc_descriptor_config(rt_uint8_t comm, rt_uint8_t data)
|
||||||
*/
|
*/
|
||||||
uclass_t rt_usbd_class_cdc_create(udevice_t device)
|
uclass_t rt_usbd_class_cdc_create(udevice_t device)
|
||||||
{
|
{
|
||||||
|
uclass_t cdc;
|
||||||
|
cdc_eps_t eps;
|
||||||
uintf_t intf_comm, intf_data;
|
uintf_t intf_comm, intf_data;
|
||||||
ualtsetting_t comm_setting, data_setting;
|
ualtsetting_t comm_setting, data_setting;
|
||||||
|
|
||||||
|
@ -428,6 +438,9 @@ uclass_t rt_usbd_class_cdc_create(udevice_t device)
|
||||||
|
|
||||||
/* create a cdc class */
|
/* create a cdc class */
|
||||||
cdc = rt_usbd_class_create(device, &dev_desc, &ops);
|
cdc = rt_usbd_class_create(device, &dev_desc, &ops);
|
||||||
|
/* create a cdc class endpoints collection */
|
||||||
|
eps = rt_malloc(sizeof(struct cdc_eps));
|
||||||
|
cdc->eps = (void*)eps;
|
||||||
|
|
||||||
/* create a cdc communication interface and a cdc data interface */
|
/* create a cdc communication interface and a cdc data interface */
|
||||||
intf_comm = rt_usbd_interface_create(device, _interface_handler);
|
intf_comm = rt_usbd_interface_create(device, _interface_handler);
|
||||||
|
@ -443,12 +456,12 @@ uclass_t rt_usbd_class_cdc_create(udevice_t device)
|
||||||
_cdc_descriptor_config(intf_comm->intf_num, intf_data->intf_num);
|
_cdc_descriptor_config(intf_comm->intf_num, intf_data->intf_num);
|
||||||
|
|
||||||
/* create a bulk in and a bulk endpoint */
|
/* create a bulk in and a bulk endpoint */
|
||||||
ep_out = rt_usbd_endpoint_create(&data_desc.ep_out_desc, _ep_out_handler);
|
eps->ep_out = rt_usbd_endpoint_create(&data_desc.ep_out_desc, _ep_out_handler);
|
||||||
ep_in = rt_usbd_endpoint_create(&data_desc.ep_in_desc, _ep_in_handler);
|
eps->ep_in = rt_usbd_endpoint_create(&data_desc.ep_in_desc, _ep_in_handler);
|
||||||
|
|
||||||
/* add the bulk out and bulk in endpoints to the data alternate setting */
|
/* add the bulk out and bulk in endpoints to the data alternate setting */
|
||||||
rt_usbd_altsetting_add_endpoint(data_setting, ep_in);
|
rt_usbd_altsetting_add_endpoint(data_setting, eps->ep_in);
|
||||||
rt_usbd_altsetting_add_endpoint(data_setting, ep_out);
|
rt_usbd_altsetting_add_endpoint(data_setting, eps->ep_out);
|
||||||
|
|
||||||
/* add the data alternate setting to the data interface
|
/* add the data alternate setting to the data interface
|
||||||
then set default setting of the interface */
|
then set default setting of the interface */
|
||||||
|
@ -459,10 +472,10 @@ uclass_t rt_usbd_class_cdc_create(udevice_t device)
|
||||||
rt_usbd_class_add_interface(cdc, intf_data);
|
rt_usbd_class_add_interface(cdc, intf_data);
|
||||||
|
|
||||||
/* create a command endpoint */
|
/* create a command endpoint */
|
||||||
ep_cmd = rt_usbd_endpoint_create(&comm_desc.ep_desc, _ep_cmd_handler);
|
eps->ep_cmd = rt_usbd_endpoint_create(&comm_desc.ep_desc, _ep_cmd_handler);
|
||||||
|
|
||||||
/* add the command endpoint to the cdc communication interface */
|
/* add the command endpoint to the cdc communication interface */
|
||||||
rt_usbd_altsetting_add_endpoint(comm_setting, ep_cmd);
|
rt_usbd_altsetting_add_endpoint(comm_setting, eps->ep_cmd);
|
||||||
|
|
||||||
/* add the communication alternate setting to the communication interface,
|
/* add the communication alternate setting to the communication interface,
|
||||||
then set default setting of the interface */
|
then set default setting of the interface */
|
||||||
|
|
|
@ -9,8 +9,9 @@
|
||||||
*
|
*
|
||||||
* Change Logs:
|
* Change Logs:
|
||||||
* Date Author Notes
|
* Date Author Notes
|
||||||
* 2012-10-01 Yi Qiu first version
|
* 2012-10-01 Yi Qiu first version
|
||||||
* 2012-11-25 Heyuanjie87 reduce the memory consumption
|
* 2012-11-25 Heyuanjie87 reduce the memory consumption
|
||||||
|
* 2012-12-09 Heyuanjie87 change class and endpoint handler
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <rtthread.h>
|
#include <rtthread.h>
|
||||||
|
@ -25,10 +26,6 @@
|
||||||
#define STATUS_RECEIVE 0x02
|
#define STATUS_RECEIVE 0x02
|
||||||
#define STATUS_SEND 0x03
|
#define STATUS_SEND 0x03
|
||||||
|
|
||||||
static uclass_t mstorage;
|
|
||||||
static uep_t ep_in, ep_out;
|
|
||||||
static rt_uint8_t *buffer;
|
|
||||||
static rt_uint8_t *write_ptr;
|
|
||||||
static int status = STATUS_CBW;
|
static int status = STATUS_CBW;
|
||||||
ALIGN(RT_ALIGN_SIZE)
|
ALIGN(RT_ALIGN_SIZE)
|
||||||
static struct ustorage_csw csw;
|
static struct ustorage_csw csw;
|
||||||
|
@ -90,7 +87,7 @@ static struct umass_descriptor mass_desc =
|
||||||
*
|
*
|
||||||
* @return the allocate instance on successful, or RT_NULL on failure.
|
* @return the allocate instance on successful, or RT_NULL on failure.
|
||||||
*/
|
*/
|
||||||
static rt_err_t _inquiry_cmd(udevice_t device)
|
static rt_err_t _inquiry_cmd(udevice_t device, uep_t ep_in)
|
||||||
{
|
{
|
||||||
rt_uint8_t data[36];
|
rt_uint8_t data[36];
|
||||||
|
|
||||||
|
@ -113,7 +110,7 @@ static rt_err_t _inquiry_cmd(udevice_t device)
|
||||||
*
|
*
|
||||||
* @return RT_EOK on successful.
|
* @return RT_EOK on successful.
|
||||||
*/
|
*/
|
||||||
static rt_err_t _request_sense(udevice_t device)
|
static rt_err_t _request_sense(udevice_t device, uep_t ep_in)
|
||||||
{
|
{
|
||||||
struct request_sense_data data;
|
struct request_sense_data data;
|
||||||
|
|
||||||
|
@ -140,7 +137,7 @@ static rt_err_t _request_sense(udevice_t device)
|
||||||
*
|
*
|
||||||
* @return RT_EOK on successful.
|
* @return RT_EOK on successful.
|
||||||
*/
|
*/
|
||||||
static rt_err_t _mode_sense_6(udevice_t device)
|
static rt_err_t _mode_sense_6(udevice_t device, uep_t ep_in)
|
||||||
{
|
{
|
||||||
rt_uint8_t data[4];
|
rt_uint8_t data[4];
|
||||||
|
|
||||||
|
@ -161,7 +158,7 @@ static rt_err_t _mode_sense_6(udevice_t device)
|
||||||
*
|
*
|
||||||
* @return RT_EOK on successful.
|
* @return RT_EOK on successful.
|
||||||
*/
|
*/
|
||||||
static rt_err_t _read_capacities(udevice_t device)
|
static rt_err_t _read_capacities(udevice_t device, uep_t ep_in)
|
||||||
{
|
{
|
||||||
rt_uint8_t data[12];
|
rt_uint8_t data[12];
|
||||||
rt_uint32_t sector_count, sector_size;
|
rt_uint32_t sector_count, sector_size;
|
||||||
|
@ -193,7 +190,7 @@ static rt_err_t _read_capacities(udevice_t device)
|
||||||
*
|
*
|
||||||
* @return RT_EOK on successful.
|
* @return RT_EOK on successful.
|
||||||
*/
|
*/
|
||||||
static rt_err_t _read_capacity(udevice_t device)
|
static rt_err_t _read_capacity(udevice_t device, uep_t ep_in)
|
||||||
{
|
{
|
||||||
rt_uint8_t data[8];
|
rt_uint8_t data[8];
|
||||||
rt_uint32_t sector_count, sector_size;
|
rt_uint32_t sector_count, sector_size;
|
||||||
|
@ -225,7 +222,7 @@ static rt_err_t _read_capacity(udevice_t device)
|
||||||
*
|
*
|
||||||
* @return RT_EOK on successful.
|
* @return RT_EOK on successful.
|
||||||
*/
|
*/
|
||||||
static rt_err_t _read_10(udevice_t device, ustorage_cbw_t cbw)
|
static rt_err_t _read_10(udevice_t device, ustorage_cbw_t cbw, uep_t ep_in)
|
||||||
{
|
{
|
||||||
RT_ASSERT(device != RT_NULL);
|
RT_ASSERT(device != RT_NULL);
|
||||||
RT_ASSERT(cbw != RT_NULL);
|
RT_ASSERT(cbw != RT_NULL);
|
||||||
|
@ -237,8 +234,8 @@ static rt_err_t _read_10(udevice_t device, ustorage_cbw_t cbw)
|
||||||
|
|
||||||
RT_ASSERT(_count < geometry.sector_count);
|
RT_ASSERT(_count < geometry.sector_count);
|
||||||
|
|
||||||
rt_device_read(disk, _block, buffer, 1);
|
rt_device_read(disk, _block, ep_in->buffer, 1);
|
||||||
dcd_ep_write(device->dcd, ep_in, buffer, geometry.bytes_per_sector);
|
dcd_ep_write(device->dcd, ep_in, ep_in->buffer, geometry.bytes_per_sector);
|
||||||
_count --;
|
_count --;
|
||||||
if (_count)
|
if (_count)
|
||||||
{
|
{
|
||||||
|
@ -261,7 +258,7 @@ static rt_err_t _read_10(udevice_t device, ustorage_cbw_t cbw)
|
||||||
*
|
*
|
||||||
* @return RT_EOK on successful.
|
* @return RT_EOK on successful.
|
||||||
*/
|
*/
|
||||||
static rt_err_t _write_10(udevice_t device, ustorage_cbw_t cbw)
|
static rt_err_t _write_10(udevice_t device, ustorage_cbw_t cbw, uep_t ep_out)
|
||||||
{
|
{
|
||||||
RT_ASSERT(device != RT_NULL);
|
RT_ASSERT(device != RT_NULL);
|
||||||
RT_ASSERT(cbw != RT_NULL);
|
RT_ASSERT(cbw != RT_NULL);
|
||||||
|
@ -271,12 +268,11 @@ static rt_err_t _write_10(udevice_t device, ustorage_cbw_t cbw)
|
||||||
_count = cbw->cb[7]<<8 | cbw->cb[8]<<0;
|
_count = cbw->cb[7]<<8 | cbw->cb[8]<<0;
|
||||||
csw.data_reside = cbw->xfer_len;
|
csw.data_reside = cbw->xfer_len;
|
||||||
_size = _count * geometry.bytes_per_sector;
|
_size = _count * geometry.bytes_per_sector;
|
||||||
write_ptr = buffer;
|
|
||||||
|
|
||||||
RT_DEBUG_LOG(RT_DEBUG_USB, ("_write_10 count 0x%x 0x%x\n",
|
RT_DEBUG_LOG(RT_DEBUG_USB, ("_write_10 count 0x%x 0x%x\n",
|
||||||
_count, geometry.sector_count));
|
_count, geometry.sector_count));
|
||||||
|
|
||||||
dcd_ep_read(device->dcd, ep_out, write_ptr, geometry.bytes_per_sector);
|
dcd_ep_read(device->dcd, ep_out, ep_out->buffer, geometry.bytes_per_sector);
|
||||||
|
|
||||||
return RT_EOK;
|
return RT_EOK;
|
||||||
}
|
}
|
||||||
|
@ -301,20 +297,23 @@ static rt_err_t _verify_10(udevice_t device)
|
||||||
*
|
*
|
||||||
* @return RT_EOK.
|
* @return RT_EOK.
|
||||||
*/
|
*/
|
||||||
static rt_err_t _ep_in_handler(udevice_t device, rt_size_t size)
|
static rt_err_t _ep_in_handler(udevice_t device, uclass_t cls, rt_size_t size)
|
||||||
{
|
{
|
||||||
|
mass_eps_t eps;
|
||||||
RT_ASSERT(device != RT_NULL);
|
RT_ASSERT(device != RT_NULL);
|
||||||
|
|
||||||
|
eps = cls->eps;
|
||||||
if(status == STATUS_CSW)
|
if(status == STATUS_CSW)
|
||||||
{
|
{
|
||||||
dcd_ep_write(device->dcd, ep_in, (rt_uint8_t*)&csw, SIZEOF_CSW);
|
dcd_ep_write(device->dcd, eps->ep_in, (rt_uint8_t*)&csw, SIZEOF_CSW);
|
||||||
status = STATUS_CBW;
|
status = STATUS_CBW;
|
||||||
dcd_ep_read(device->dcd, ep_out, ep_out->buffer, SIZEOF_CBW);
|
dcd_ep_read(device->dcd, eps->ep_out, eps->ep_out->buffer, SIZEOF_CBW);
|
||||||
}
|
}
|
||||||
if(status == STATUS_SEND)
|
if(status == STATUS_SEND)
|
||||||
{
|
{
|
||||||
rt_device_read(disk, _block, buffer, 1);
|
rt_device_read(disk, _block, eps->ep_in->buffer, 1);
|
||||||
dcd_ep_write(device->dcd, ep_in, buffer, geometry.bytes_per_sector);
|
dcd_ep_write(device->dcd, eps->ep_in, eps->ep_in->buffer,
|
||||||
|
geometry.bytes_per_sector);
|
||||||
_count --;
|
_count --;
|
||||||
if (_count)
|
if (_count)
|
||||||
{
|
{
|
||||||
|
@ -330,6 +329,7 @@ static rt_err_t _ep_in_handler(udevice_t device, rt_size_t size)
|
||||||
return RT_EOK;
|
return RT_EOK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef MASS_CBW_DUMP
|
||||||
static void cbw_dump(struct ustorage_cbw* cbw)
|
static void cbw_dump(struct ustorage_cbw* cbw)
|
||||||
{
|
{
|
||||||
RT_ASSERT(cbw != RT_NULL);
|
RT_ASSERT(cbw != RT_NULL);
|
||||||
|
@ -342,6 +342,7 @@ static void cbw_dump(struct ustorage_cbw* cbw)
|
||||||
RT_DEBUG_LOG(RT_DEBUG_USB, ("cb_len 0x%x\n", cbw->cb_len));
|
RT_DEBUG_LOG(RT_DEBUG_USB, ("cb_len 0x%x\n", cbw->cb_len));
|
||||||
RT_DEBUG_LOG(RT_DEBUG_USB, ("cb[0] 0x%x\n", cbw->cb[0]));
|
RT_DEBUG_LOG(RT_DEBUG_USB, ("cb[0] 0x%x\n", cbw->cb[0]));
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function will handle mass storage bulk out endpoint request.
|
* This function will handle mass storage bulk out endpoint request.
|
||||||
|
@ -351,16 +352,18 @@ static void cbw_dump(struct ustorage_cbw* cbw)
|
||||||
*
|
*
|
||||||
* @return RT_EOK.
|
* @return RT_EOK.
|
||||||
*/
|
*/
|
||||||
static rt_err_t _ep_out_handler(udevice_t device, rt_size_t size)
|
static rt_err_t _ep_out_handler(udevice_t device, uclass_t cls, rt_size_t size)
|
||||||
{
|
{
|
||||||
|
mass_eps_t eps;
|
||||||
RT_ASSERT(device != RT_NULL);
|
RT_ASSERT(device != RT_NULL);
|
||||||
|
|
||||||
|
eps = (mass_eps_t)cls->eps;
|
||||||
if(status == STATUS_CBW)
|
if(status == STATUS_CBW)
|
||||||
{
|
{
|
||||||
struct ustorage_cbw* cbw;
|
struct ustorage_cbw* cbw;
|
||||||
|
|
||||||
/* dump cbw information */
|
/* dump cbw information */
|
||||||
cbw = (struct ustorage_cbw*)ep_out->buffer;
|
cbw = (struct ustorage_cbw*)eps->ep_out->buffer;
|
||||||
|
|
||||||
if(cbw->signature == CBW_SIGNATURE)
|
if(cbw->signature == CBW_SIGNATURE)
|
||||||
{
|
{
|
||||||
|
@ -369,42 +372,44 @@ static rt_err_t _ep_out_handler(udevice_t device, rt_size_t size)
|
||||||
csw.data_reside = 0;
|
csw.data_reside = 0;
|
||||||
csw.status = 0;
|
csw.status = 0;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
return -RT_ERROR;
|
||||||
|
|
||||||
switch(cbw->cb[0])
|
switch(cbw->cb[0])
|
||||||
{
|
{
|
||||||
case SCSI_TEST_UNIT_READY:
|
case SCSI_TEST_UNIT_READY:
|
||||||
dcd_ep_write(device->dcd, ep_in, (rt_uint8_t*)&csw, SIZEOF_CSW);
|
dcd_ep_write(device->dcd, eps->ep_in, (rt_uint8_t*)&csw, SIZEOF_CSW);
|
||||||
dcd_ep_read(device->dcd, ep_out, ep_out->buffer, SIZEOF_CBW);
|
dcd_ep_read(device->dcd, eps->ep_out, eps->ep_out->buffer, SIZEOF_CBW);
|
||||||
break;
|
break;
|
||||||
case SCSI_REQUEST_SENSE:
|
case SCSI_REQUEST_SENSE:
|
||||||
_request_sense(device);
|
_request_sense(device, eps->ep_in);
|
||||||
status = STATUS_CSW;
|
status = STATUS_CSW;
|
||||||
break;
|
break;
|
||||||
case SCSI_INQUIRY_CMD:
|
case SCSI_INQUIRY_CMD:
|
||||||
_inquiry_cmd(device);
|
_inquiry_cmd(device, eps->ep_in);
|
||||||
status = STATUS_CSW;
|
status = STATUS_CSW;
|
||||||
break;
|
break;
|
||||||
case SCSI_MODE_SENSE_6:
|
case SCSI_MODE_SENSE_6:
|
||||||
_mode_sense_6(device);
|
_mode_sense_6(device, eps->ep_in);
|
||||||
status = STATUS_CSW;
|
status = STATUS_CSW;
|
||||||
break;
|
break;
|
||||||
case SCSI_ALLOW_MEDIUM_REMOVAL:
|
case SCSI_ALLOW_MEDIUM_REMOVAL:
|
||||||
dcd_ep_write(device->dcd, ep_in, (rt_uint8_t*)&csw, SIZEOF_CSW);
|
dcd_ep_write(device->dcd, eps->ep_in, (rt_uint8_t*)&csw, SIZEOF_CSW);
|
||||||
dcd_ep_read(device->dcd, ep_out, ep_out->buffer, SIZEOF_CBW);
|
dcd_ep_read(device->dcd, eps->ep_out, eps->ep_out->buffer, SIZEOF_CBW);
|
||||||
break;
|
break;
|
||||||
case SCSI_READ_CAPACITIES:
|
case SCSI_READ_CAPACITIES:
|
||||||
_read_capacities(device);
|
_read_capacities(device, eps->ep_in);
|
||||||
status = STATUS_CSW;
|
status = STATUS_CSW;
|
||||||
break;
|
break;
|
||||||
case SCSI_READ_CAPACITY:
|
case SCSI_READ_CAPACITY:
|
||||||
_read_capacity(device);
|
_read_capacity(device, eps->ep_in);
|
||||||
status = STATUS_CSW;
|
status = STATUS_CSW;
|
||||||
break;
|
break;
|
||||||
case SCSI_READ_10:
|
case SCSI_READ_10:
|
||||||
_read_10(device, cbw);
|
_read_10(device, cbw, eps->ep_in);
|
||||||
break;
|
break;
|
||||||
case SCSI_WRITE_10:
|
case SCSI_WRITE_10:
|
||||||
_write_10(device, cbw);
|
_write_10(device, cbw, eps->ep_out);
|
||||||
status = STATUS_RECEIVE;
|
status = STATUS_RECEIVE;
|
||||||
break;
|
break;
|
||||||
case SCSI_VERIFY_10:
|
case SCSI_VERIFY_10:
|
||||||
|
@ -420,17 +425,18 @@ static rt_err_t _ep_out_handler(udevice_t device, rt_size_t size)
|
||||||
_size -= size;
|
_size -= size;
|
||||||
csw.data_reside -= size;
|
csw.data_reside -= size;
|
||||||
|
|
||||||
rt_device_write(disk, _block, write_ptr, 1);
|
rt_device_write(disk, _block, eps->ep_in->buffer, 1);
|
||||||
_block ++;
|
_block ++;
|
||||||
if(_size == 0)
|
if(_size == 0)
|
||||||
{
|
{
|
||||||
dcd_ep_write(device->dcd, ep_in, (rt_uint8_t*)&csw, SIZEOF_CSW);
|
dcd_ep_write(device->dcd, eps->ep_in, (rt_uint8_t*)&csw, SIZEOF_CSW);
|
||||||
dcd_ep_read(device->dcd, ep_out, ep_out->buffer, SIZEOF_CBW);
|
dcd_ep_read(device->dcd, eps->ep_out, eps->ep_out->buffer, SIZEOF_CBW);
|
||||||
status = STATUS_CBW;
|
status = STATUS_CBW;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
dcd_ep_read(device->dcd, ep_out, write_ptr, geometry.bytes_per_sector);
|
dcd_ep_read(device->dcd, eps->ep_out, eps->ep_out->buffer,
|
||||||
|
geometry.bytes_per_sector);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -481,11 +487,14 @@ static rt_err_t _interface_handler(udevice_t device, ureq_t setup)
|
||||||
*
|
*
|
||||||
* @return RT_EOK on successful.
|
* @return RT_EOK on successful.
|
||||||
*/
|
*/
|
||||||
static rt_err_t _class_run(udevice_t device)
|
static rt_err_t _class_run(udevice_t device, uclass_t cls)
|
||||||
{
|
{
|
||||||
|
mass_eps_t eps;
|
||||||
|
rt_uint8_t *buffer;
|
||||||
RT_ASSERT(device != RT_NULL);
|
RT_ASSERT(device != RT_NULL);
|
||||||
|
|
||||||
RT_DEBUG_LOG(RT_DEBUG_USB, ("mass storage run\n"));
|
RT_DEBUG_LOG(RT_DEBUG_USB, ("mass storage run\n"));
|
||||||
|
eps = (mass_eps_t)cls->eps;
|
||||||
|
|
||||||
disk = rt_device_find(RT_USB_MSTORAGE_DISK_NAME);
|
disk = rt_device_find(RT_USB_MSTORAGE_DISK_NAME);
|
||||||
if(disk == RT_NULL)
|
if(disk == RT_NULL)
|
||||||
|
@ -499,7 +508,10 @@ static rt_err_t _class_run(udevice_t device)
|
||||||
buffer = (rt_uint8_t*)rt_malloc(geometry.bytes_per_sector);
|
buffer = (rt_uint8_t*)rt_malloc(geometry.bytes_per_sector);
|
||||||
if(buffer == RT_NULL)
|
if(buffer == RT_NULL)
|
||||||
return -RT_ENOMEM;
|
return -RT_ENOMEM;
|
||||||
dcd_ep_read(device->dcd, ep_out, ep_out->buffer, SIZEOF_CBW);
|
eps->ep_out->buffer = buffer;
|
||||||
|
eps->ep_in->buffer = buffer;
|
||||||
|
|
||||||
|
dcd_ep_read(device->dcd, eps->ep_out, eps->ep_out->buffer, SIZEOF_CBW);
|
||||||
|
|
||||||
return RT_EOK;
|
return RT_EOK;
|
||||||
}
|
}
|
||||||
|
@ -511,13 +523,17 @@ static rt_err_t _class_run(udevice_t device)
|
||||||
*
|
*
|
||||||
* @return RT_EOK on successful.
|
* @return RT_EOK on successful.
|
||||||
*/
|
*/
|
||||||
static rt_err_t _class_stop(udevice_t device)
|
static rt_err_t _class_stop(udevice_t device, uclass_t cls)
|
||||||
{
|
{
|
||||||
|
mass_eps_t eps;
|
||||||
RT_ASSERT(device != RT_NULL);
|
RT_ASSERT(device != RT_NULL);
|
||||||
|
|
||||||
RT_DEBUG_LOG(RT_DEBUG_USB, ("mass storage stop\n"));
|
RT_DEBUG_LOG(RT_DEBUG_USB, ("mass storage stop\n"));
|
||||||
|
eps = (mass_eps_t)cls->eps;
|
||||||
|
rt_free(eps->ep_in->buffer);
|
||||||
|
eps->ep_out->buffer = RT_NULL;
|
||||||
|
eps->ep_in->buffer = RT_NULL;
|
||||||
|
|
||||||
rt_free(buffer);
|
|
||||||
return RT_EOK;
|
return RT_EOK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -538,6 +554,8 @@ static struct uclass_ops ops =
|
||||||
uclass_t rt_usbd_class_mstorage_create(udevice_t device)
|
uclass_t rt_usbd_class_mstorage_create(udevice_t device)
|
||||||
{
|
{
|
||||||
uintf_t intf;
|
uintf_t intf;
|
||||||
|
mass_eps_t eps;
|
||||||
|
uclass_t mstorage;
|
||||||
ualtsetting_t setting;
|
ualtsetting_t setting;
|
||||||
|
|
||||||
/* parameter check */
|
/* parameter check */
|
||||||
|
@ -545,21 +563,24 @@ uclass_t rt_usbd_class_mstorage_create(udevice_t device)
|
||||||
|
|
||||||
/* create a mass storage class */
|
/* create a mass storage class */
|
||||||
mstorage = rt_usbd_class_create(device, &dev_desc, &ops);
|
mstorage = rt_usbd_class_create(device, &dev_desc, &ops);
|
||||||
|
/* create a mass storage endpoints collection */
|
||||||
|
eps = (mass_eps_t)rt_malloc(sizeof(struct mass_eps));
|
||||||
|
mstorage->eps = (void*)eps;
|
||||||
|
|
||||||
/* create an interface */
|
/* create an interface */
|
||||||
intf = rt_usbd_interface_create(device, _interface_handler);
|
intf = rt_usbd_interface_create(device, _interface_handler);
|
||||||
|
|
||||||
/* create a bulk out and a bulk in endpoint */
|
/* create a bulk out and a bulk in endpoint */
|
||||||
ep_in = rt_usbd_endpoint_create(&mass_desc.ep_in_desc, _ep_in_handler);
|
eps->ep_in = rt_usbd_endpoint_create(&mass_desc.ep_in_desc, _ep_in_handler);
|
||||||
ep_out = rt_usbd_endpoint_create(&mass_desc.ep_out_desc, _ep_out_handler);
|
eps->ep_out = rt_usbd_endpoint_create(&mass_desc.ep_out_desc, _ep_out_handler);
|
||||||
|
|
||||||
/* create an alternate setting */
|
/* create an alternate setting */
|
||||||
setting = rt_usbd_altsetting_create(&mass_desc.intf_desc,
|
setting = rt_usbd_altsetting_create(&mass_desc.intf_desc,
|
||||||
sizeof(struct umass_descriptor));
|
sizeof(struct umass_descriptor));
|
||||||
|
|
||||||
/* add the bulk out and bulk in endpoint to the alternate setting */
|
/* add the bulk out and bulk in endpoint to the alternate setting */
|
||||||
rt_usbd_altsetting_add_endpoint(setting, ep_out);
|
rt_usbd_altsetting_add_endpoint(setting, eps->ep_out);
|
||||||
rt_usbd_altsetting_add_endpoint(setting, ep_in);
|
rt_usbd_altsetting_add_endpoint(setting, eps->ep_in);
|
||||||
|
|
||||||
/* add the alternate setting to the interface, then set default setting */
|
/* add the alternate setting to the interface, then set default setting */
|
||||||
rt_usbd_interface_add_altsetting(intf, setting);
|
rt_usbd_interface_add_altsetting(intf, setting);
|
||||||
|
|
|
@ -9,8 +9,13 @@
|
||||||
*
|
*
|
||||||
* Change Logs:
|
* Change Logs:
|
||||||
* Date Author Notes
|
* Date Author Notes
|
||||||
* 2012-10-01 Yi Qiu first version
|
* 2012-10-01 Yi Qiu first version
|
||||||
|
* 2012-12-12 heyuanjie87 add MASS endpoints collection
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifndef __MSTORAGE_H__
|
||||||
|
#define __MSTORAGE_H__
|
||||||
|
|
||||||
#include <rtthread.h>
|
#include <rtthread.h>
|
||||||
|
|
||||||
#define USBREQ_GET_MAX_LUN 0xfe
|
#define USBREQ_GET_MAX_LUN 0xfe
|
||||||
|
@ -49,5 +54,13 @@ struct request_sense_data
|
||||||
rt_uint8_t Reserved4[4];
|
rt_uint8_t Reserved4[4];
|
||||||
}request_sense_data_t;
|
}request_sense_data_t;
|
||||||
|
|
||||||
|
struct mass_eps
|
||||||
|
{
|
||||||
|
uep_t ep_in;
|
||||||
|
uep_t ep_out;
|
||||||
|
};
|
||||||
|
typedef struct mass_eps* mass_eps_t;
|
||||||
|
|
||||||
#pragma pack()
|
#pragma pack()
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue