update USB driver
This commit is contained in:
@@ -1,3 +1,9 @@
|
|||||||
|
2015-07-28 Niibe Yutaka <gniibe@fsij.org>
|
||||||
|
|
||||||
|
* example-cdc/usb_stm32f103.c: Update from Gnuk.
|
||||||
|
* example-cdc/usb_lld.h: Ditto.
|
||||||
|
* example-cdc/usb-cdc.c: Follow the change.
|
||||||
|
|
||||||
2015-07-15 Niibe Yutaka <gniibe@fsij.org>
|
2015-07-15 Niibe Yutaka <gniibe@fsij.org>
|
||||||
|
|
||||||
* VERSION: 0.07.
|
* VERSION: 0.07.
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ static const uint8_t vcom_device_desc[18] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* Configuration Descriptor tree for a CDC.*/
|
/* Configuration Descriptor tree for a CDC.*/
|
||||||
static const uint8_t vcom_configuration_desc[67] = {
|
static const uint8_t vcom_config_desc[67] = {
|
||||||
9,
|
9,
|
||||||
USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bDescriptorType: Configuration */
|
USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bDescriptorType: Configuration */
|
||||||
/* Configuration Descriptor.*/
|
/* Configuration Descriptor.*/
|
||||||
@@ -167,7 +167,7 @@ usb_cb_device_reset (void)
|
|||||||
usb_lld_set_configuration (0);
|
usb_lld_set_configuration (0);
|
||||||
|
|
||||||
/* Current Feature initialization */
|
/* Current Feature initialization */
|
||||||
usb_lld_set_feature (vcom_configuration_desc[7]);
|
usb_lld_set_feature (vcom_config_desc[7]);
|
||||||
|
|
||||||
usb_lld_reset ();
|
usb_lld_reset ();
|
||||||
|
|
||||||
@@ -177,14 +177,12 @@ usb_cb_device_reset (void)
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
usb_cb_ctrl_write_finish (uint8_t req, uint8_t req_no, uint16_t value,
|
usb_cb_ctrl_write_finish (uint8_t req, uint8_t req_no, uint16_t value)
|
||||||
uint16_t index, uint16_t len)
|
|
||||||
{
|
{
|
||||||
uint8_t type_rcp = req & (REQUEST_TYPE|RECIPIENT);
|
uint8_t type_rcp = req & (REQUEST_TYPE|RECIPIENT);
|
||||||
|
|
||||||
if (type_rcp == (CLASS_REQUEST | INTERFACE_RECIPIENT)
|
if (type_rcp == (CLASS_REQUEST | INTERFACE_RECIPIENT)
|
||||||
&& index == 0 && USB_SETUP_SET (req) && len == 0
|
&& USB_SETUP_SET (req) && req_no == USB_CDC_REQ_SET_CONTROL_LINE_STATE)
|
||||||
&& req_no == USB_CDC_REQ_SET_CONTROL_LINE_STATE)
|
|
||||||
{
|
{
|
||||||
/* Open/close the connection. */
|
/* Open/close the connection. */
|
||||||
chopstx_mutex_lock (&usb_mtx);
|
chopstx_mutex_lock (&usb_mtx);
|
||||||
@@ -211,22 +209,17 @@ static struct line_coding line_coding = {
|
|||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
vcom_port_data_setup (uint8_t req, uint8_t req_no, uint16_t value, uint16_t len)
|
vcom_port_data_setup (uint8_t req, uint8_t req_no, struct control_info *detail)
|
||||||
{
|
{
|
||||||
(void)value;
|
|
||||||
if (USB_SETUP_GET (req))
|
if (USB_SETUP_GET (req))
|
||||||
{
|
{
|
||||||
if (req_no == USB_CDC_REQ_GET_LINE_CODING
|
if (req_no == USB_CDC_REQ_GET_LINE_CODING)
|
||||||
&& len == sizeof (line_coding))
|
return usb_lld_reply_request (&line_coding, sizeof(line_coding), detail);
|
||||||
{
|
|
||||||
usb_lld_set_data_to_send (&line_coding, sizeof (line_coding));
|
|
||||||
return USB_SUCCESS;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else /* USB_SETUP_SET (req) */
|
else /* USB_SETUP_SET (req) */
|
||||||
{
|
{
|
||||||
if (req_no == USB_CDC_REQ_SET_LINE_CODING
|
if (req_no == USB_CDC_REQ_SET_LINE_CODING
|
||||||
&& len == sizeof (line_coding))
|
&& detail->len == sizeof (line_coding))
|
||||||
{
|
{
|
||||||
usb_lld_set_data_to_recv (&line_coding, sizeof (line_coding));
|
usb_lld_set_data_to_recv (&line_coding, sizeof (line_coding));
|
||||||
return USB_SUCCESS;
|
return USB_SUCCESS;
|
||||||
@@ -239,38 +232,29 @@ vcom_port_data_setup (uint8_t req, uint8_t req_no, uint16_t value, uint16_t len)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
usb_cb_setup (uint8_t req, uint8_t req_no,
|
usb_cb_setup (uint8_t req, uint8_t req_no, struct control_info *detail)
|
||||||
uint16_t value, uint16_t index, uint16_t len)
|
|
||||||
{
|
{
|
||||||
uint8_t type_rcp = req & (REQUEST_TYPE|RECIPIENT);
|
uint8_t type_rcp = req & (REQUEST_TYPE|RECIPIENT);
|
||||||
|
|
||||||
(void)len;
|
if (type_rcp == (CLASS_REQUEST | INTERFACE_RECIPIENT) && detail->index == 0)
|
||||||
if (type_rcp == (CLASS_REQUEST | INTERFACE_RECIPIENT))
|
return vcom_port_data_setup (req, req_no, detail);
|
||||||
if (index == 0)
|
|
||||||
return vcom_port_data_setup (req, req_no, value, len);
|
|
||||||
|
|
||||||
return USB_UNSUPPORT;
|
return USB_UNSUPPORT;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
usb_cb_get_descriptor (uint8_t rcp, uint8_t desc_type, uint8_t desc_index,
|
usb_cb_get_descriptor (uint8_t rcp, uint8_t desc_type, uint8_t desc_index,
|
||||||
uint16_t index)
|
struct control_info *detail)
|
||||||
{
|
{
|
||||||
(void)index;
|
|
||||||
if (rcp != DEVICE_RECIPIENT)
|
if (rcp != DEVICE_RECIPIENT)
|
||||||
return USB_UNSUPPORT;
|
return USB_UNSUPPORT;
|
||||||
|
|
||||||
if (desc_type == DEVICE_DESCRIPTOR)
|
if (desc_type == DEVICE_DESCRIPTOR)
|
||||||
{
|
return usb_lld_reply_request (vcom_device_desc, sizeof (vcom_device_desc),
|
||||||
usb_lld_set_data_to_send (vcom_device_desc, sizeof (vcom_device_desc));
|
detail);
|
||||||
return USB_SUCCESS;
|
|
||||||
}
|
|
||||||
else if (desc_type == CONFIG_DESCRIPTOR)
|
else if (desc_type == CONFIG_DESCRIPTOR)
|
||||||
{
|
return usb_lld_reply_request (vcom_config_desc, sizeof (vcom_config_desc),
|
||||||
usb_lld_set_data_to_send (vcom_configuration_desc,
|
detail);
|
||||||
sizeof (vcom_configuration_desc));
|
|
||||||
return USB_SUCCESS;
|
|
||||||
}
|
|
||||||
else if (desc_type == STRING_DESCRIPTOR)
|
else if (desc_type == STRING_DESCRIPTOR)
|
||||||
{
|
{
|
||||||
const uint8_t *str;
|
const uint8_t *str;
|
||||||
@@ -298,8 +282,7 @@ usb_cb_get_descriptor (uint8_t rcp, uint8_t desc_type, uint8_t desc_index,
|
|||||||
return USB_UNSUPPORT;
|
return USB_UNSUPPORT;
|
||||||
}
|
}
|
||||||
|
|
||||||
usb_lld_set_data_to_send (str, size);
|
return usb_lld_reply_request (str, size, detail);
|
||||||
return USB_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return USB_UNSUPPORT;
|
return USB_UNSUPPORT;
|
||||||
@@ -374,9 +357,11 @@ int usb_cb_handle_event (uint8_t event_type, uint16_t value)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int usb_cb_interface (uint8_t cmd, uint16_t interface, uint16_t alt)
|
int usb_cb_interface (uint8_t cmd, struct control_info *detail)
|
||||||
{
|
{
|
||||||
static uint8_t zero = 0;
|
const uint8_t zero = 0;
|
||||||
|
uint16_t interface = detail->index;
|
||||||
|
uint16_t alt = detail->value;
|
||||||
|
|
||||||
if (interface >= NUM_INTERFACES)
|
if (interface >= NUM_INTERFACES)
|
||||||
return USB_UNSUPPORT;
|
return USB_UNSUPPORT;
|
||||||
@@ -393,8 +378,7 @@ int usb_cb_interface (uint8_t cmd, uint16_t interface, uint16_t alt)
|
|||||||
}
|
}
|
||||||
|
|
||||||
case USB_GET_INTERFACE:
|
case USB_GET_INTERFACE:
|
||||||
usb_lld_set_data_to_send (&zero, 1);
|
return usb_lld_reply_request (&zero, 1, detail);
|
||||||
return USB_SUCCESS;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
case USB_QUERY_INTERFACE:
|
case USB_QUERY_INTERFACE:
|
||||||
|
|||||||
@@ -55,15 +55,19 @@ enum
|
|||||||
USB_SUCCESS = 1,
|
USB_SUCCESS = 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct control_info {
|
||||||
|
uint16_t value;
|
||||||
|
uint16_t index;
|
||||||
|
uint16_t len;
|
||||||
|
};
|
||||||
|
|
||||||
void usb_cb_device_reset (void);
|
void usb_cb_device_reset (void);
|
||||||
void usb_cb_ctrl_write_finish (uint8_t req, uint8_t req_no,
|
int usb_cb_setup (uint8_t req, uint8_t req_no, struct control_info *detail);
|
||||||
uint16_t value, uint16_t index, uint16_t len);
|
int usb_cb_interface (uint8_t cmd, struct control_info *detail);
|
||||||
int usb_cb_setup (uint8_t req, uint8_t req_no, uint16_t value,
|
|
||||||
uint16_t index, uint16_t len);
|
|
||||||
int usb_cb_get_descriptor (uint8_t rcp, uint8_t desc_type, uint8_t desc_index,
|
int usb_cb_get_descriptor (uint8_t rcp, uint8_t desc_type, uint8_t desc_index,
|
||||||
uint16_t index);
|
struct control_info *detail);
|
||||||
int usb_cb_handle_event (uint8_t event_type, uint16_t value);
|
int usb_cb_handle_event (uint8_t event_type, uint16_t value);
|
||||||
int usb_cb_interface (uint8_t cmd, uint16_t interface, uint16_t value);
|
void usb_cb_ctrl_write_finish (uint8_t req, uint8_t req_no, uint16_t value);
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
USB_EVENT_ADDRESS,
|
USB_EVENT_ADDRESS,
|
||||||
@@ -89,51 +93,30 @@ enum DEVICE_STATE
|
|||||||
CONFIGURED
|
CONFIGURED
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void usb_lld_init (uint8_t feature);
|
||||||
|
void usb_lld_to_pmabuf (const void *src, uint16_t addr, size_t n);
|
||||||
|
void usb_lld_from_pmabuf (void *dst, uint16_t addr, size_t n);
|
||||||
|
void usb_lld_stall_tx (int ep_num);
|
||||||
|
void usb_lld_stall_rx (int ep_num);
|
||||||
|
int usb_lld_tx_data_len (int ep_num);
|
||||||
|
void usb_lld_txcpy (const void *src, int ep_num, int offset, size_t len);
|
||||||
|
void usb_lld_tx_enable (int ep_num, size_t len);
|
||||||
|
void usb_lld_write (uint8_t ep_num, const void *buf, size_t len);
|
||||||
|
int usb_lld_reply_request (const void *buf, size_t buflen,
|
||||||
|
struct control_info *ctrl);
|
||||||
|
void usb_lld_rx_enable (int ep_num);
|
||||||
|
int usb_lld_rx_data_len (int ep_num);
|
||||||
|
void usb_lld_rxcpy (uint8_t *dst, int ep_num, int offset, size_t len);
|
||||||
|
void usb_lld_reset (void);
|
||||||
|
void usb_lld_setup_endpoint (int ep_num, int ep_type, int ep_kind,
|
||||||
|
int ep_rx_addr, int ep_tx_addr,
|
||||||
|
int ep_rx_memory_size);
|
||||||
|
void usb_lld_set_configuration (uint8_t config);
|
||||||
|
uint8_t usb_lld_current_configuration (void);
|
||||||
|
void usb_lld_set_feature (uint8_t feature);
|
||||||
|
void usb_lld_set_data_to_recv (const void *p, size_t len);
|
||||||
|
|
||||||
extern void usb_lld_init (uint8_t feature);
|
void usb_lld_prepare_shutdown (void);
|
||||||
|
void usb_lld_shutdown (void);
|
||||||
|
|
||||||
extern void usb_lld_to_pmabuf (const void *src, uint16_t addr, size_t n);
|
void usb_interrupt_handler (void);
|
||||||
|
|
||||||
extern void usb_lld_from_pmabuf (void *dst, uint16_t addr, size_t n);
|
|
||||||
|
|
||||||
extern void usb_lld_stall_tx (int ep_num);
|
|
||||||
|
|
||||||
extern void usb_lld_stall_rx (int ep_num);
|
|
||||||
|
|
||||||
extern int usb_lld_tx_data_len (int ep_num);
|
|
||||||
|
|
||||||
extern void usb_lld_txcpy (const void *src, int ep_num, int offset, size_t len);
|
|
||||||
|
|
||||||
extern void usb_lld_tx_enable (int ep_num, size_t len);
|
|
||||||
|
|
||||||
extern void usb_lld_write (uint8_t ep_num, const void *buf, size_t len);
|
|
||||||
|
|
||||||
extern void usb_lld_rx_enable (int ep_num);
|
|
||||||
|
|
||||||
extern int usb_lld_rx_data_len (int ep_num);
|
|
||||||
|
|
||||||
extern void usb_lld_rxcpy (uint8_t *dst, int ep_num, int offset, size_t len);
|
|
||||||
|
|
||||||
extern void usb_lld_reset (void);
|
|
||||||
|
|
||||||
extern void usb_lld_setup_endpoint (int ep_num, int ep_type, int ep_kind,
|
|
||||||
int ep_rx_addr, int ep_tx_addr,
|
|
||||||
int ep_rx_memory_size);
|
|
||||||
|
|
||||||
extern void usb_lld_set_configuration (uint8_t config);
|
|
||||||
|
|
||||||
extern uint8_t usb_lld_current_configuration (void);
|
|
||||||
|
|
||||||
extern void usb_lld_set_feature (uint8_t feature);
|
|
||||||
|
|
||||||
extern void usb_lld_set_data_to_send (const void *p, size_t len);
|
|
||||||
|
|
||||||
extern inline void usb_lld_set_data_to_recv (void *p, size_t len)
|
|
||||||
{
|
|
||||||
usb_lld_set_data_to_send ((const void *)p, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
extern void usb_lld_prepare_shutdown (void);
|
|
||||||
extern void usb_lld_shutdown (void);
|
|
||||||
|
|
||||||
extern void usb_interrupt_handler (void);
|
|
||||||
|
|||||||
@@ -1,9 +1,6 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#define TRUE 1
|
|
||||||
#define FALSE 0
|
|
||||||
|
|
||||||
#include "sys.h"
|
#include "sys.h"
|
||||||
#include "usb_lld.h"
|
#include "usb_lld.h"
|
||||||
|
|
||||||
@@ -49,33 +46,27 @@ enum FEATURE_SELECTOR
|
|||||||
|
|
||||||
struct DATA_INFO
|
struct DATA_INFO
|
||||||
{
|
{
|
||||||
uint16_t len;
|
|
||||||
uint16_t offset;
|
|
||||||
uint8_t *addr;
|
uint8_t *addr;
|
||||||
|
uint16_t len;
|
||||||
uint8_t require_zlp;
|
uint8_t require_zlp;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CONTROL_INFO
|
|
||||||
{
|
|
||||||
uint8_t bmRequestType;
|
|
||||||
uint8_t bRequest;
|
|
||||||
uint16_t wValue;
|
|
||||||
uint16_t wIndex;
|
|
||||||
uint16_t wLength;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct DEVICE_INFO
|
struct DEVICE_INFO
|
||||||
{
|
{
|
||||||
uint8_t current_configuration;
|
uint8_t current_configuration;
|
||||||
uint8_t current_feature;
|
uint8_t current_feature;
|
||||||
uint8_t state;
|
uint8_t state;
|
||||||
|
/**/
|
||||||
|
uint8_t bmRequestType;
|
||||||
|
uint8_t bRequest;
|
||||||
|
/**/
|
||||||
|
uint16_t value;
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct CONTROL_INFO control_info;
|
|
||||||
static struct DEVICE_INFO device_info;
|
static struct DEVICE_INFO device_info;
|
||||||
static struct DATA_INFO data_info;
|
static struct DATA_INFO data_info;
|
||||||
|
|
||||||
static struct CONTROL_INFO *const ctrl_p = &control_info;
|
|
||||||
static struct DEVICE_INFO *const dev_p = &device_info;
|
static struct DEVICE_INFO *const dev_p = &device_info;
|
||||||
static struct DATA_INFO *const data_p = &data_info;
|
static struct DATA_INFO *const data_p = &data_info;
|
||||||
|
|
||||||
@@ -412,16 +403,14 @@ static void handle_datastage_out (void)
|
|||||||
{
|
{
|
||||||
if (data_p->addr && data_p->len)
|
if (data_p->addr && data_p->len)
|
||||||
{
|
{
|
||||||
uint8_t *buf;
|
|
||||||
uint32_t len = st103_get_rx_count (ENDP0);
|
uint32_t len = st103_get_rx_count (ENDP0);
|
||||||
|
|
||||||
if (len > data_p->len)
|
if (len > data_p->len)
|
||||||
len = data_p->len;
|
len = data_p->len;
|
||||||
|
|
||||||
buf = data_p->addr + data_p->offset;
|
usb_lld_from_pmabuf (data_p->addr, st103_get_rx_addr (ENDP0), len);
|
||||||
usb_lld_from_pmabuf (buf, st103_get_rx_addr (ENDP0), len);
|
|
||||||
data_p->len -= len;
|
data_p->len -= len;
|
||||||
data_p->offset += len;
|
data_p->addr += len;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data_p->len == 0)
|
if (data_p->len == 0)
|
||||||
@@ -440,13 +429,12 @@ static void handle_datastage_out (void)
|
|||||||
static void handle_datastage_in (void)
|
static void handle_datastage_in (void)
|
||||||
{
|
{
|
||||||
uint32_t len = USB_MAX_PACKET_SIZE;;
|
uint32_t len = USB_MAX_PACKET_SIZE;;
|
||||||
const uint8_t *buf;
|
|
||||||
|
|
||||||
if ((data_p->len == 0) && (dev_p->state == LAST_IN_DATA))
|
if ((data_p->len == 0) && (dev_p->state == LAST_IN_DATA))
|
||||||
{
|
{
|
||||||
if (data_p->require_zlp == TRUE)
|
if (data_p->require_zlp)
|
||||||
{
|
{
|
||||||
data_p->require_zlp = FALSE;
|
data_p->require_zlp = 0;
|
||||||
|
|
||||||
/* No more data to send. Send empty packet */
|
/* No more data to send. Send empty packet */
|
||||||
st103_set_tx_count (ENDP0, 0);
|
st103_set_tx_count (ENDP0, 0);
|
||||||
@@ -467,40 +455,33 @@ static void handle_datastage_in (void)
|
|||||||
if (len > data_p->len)
|
if (len > data_p->len)
|
||||||
len = data_p->len;
|
len = data_p->len;
|
||||||
|
|
||||||
buf = (const uint8_t *)data_p->addr + data_p->offset;
|
usb_lld_to_pmabuf (data_p->addr, st103_get_tx_addr (ENDP0), len);
|
||||||
usb_lld_to_pmabuf (buf, st103_get_tx_addr (ENDP0), len);
|
|
||||||
data_p->len -= len;
|
data_p->len -= len;
|
||||||
data_p->offset += len;
|
data_p->addr += len;
|
||||||
st103_set_tx_count (ENDP0, len);
|
st103_set_tx_count (ENDP0, len);
|
||||||
st103_ep_set_tx_status (ENDP0, EP_TX_VALID);
|
st103_ep_set_tx_status (ENDP0, EP_TX_VALID);
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef int (*HANDLER) (uint8_t req,
|
typedef int (*HANDLER) (uint8_t req, struct control_info *detail);
|
||||||
uint16_t value, uint16_t index, uint16_t length);
|
|
||||||
|
|
||||||
static int std_none (uint8_t req,
|
static int std_none (uint8_t req, struct control_info *detail)
|
||||||
uint16_t value, uint16_t index, uint16_t length)
|
|
||||||
{
|
{
|
||||||
(void)req; (void)value; (void)index; (void)length;
|
(void)req; (void)detail;
|
||||||
return USB_UNSUPPORT;
|
return USB_UNSUPPORT;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int std_get_status (uint8_t req,
|
static int std_get_status (uint8_t req, struct control_info *detail)
|
||||||
uint16_t value, uint16_t index, uint16_t length)
|
|
||||||
{
|
{
|
||||||
static uint16_t status_info;
|
|
||||||
uint8_t rcp = req & RECIPIENT;
|
uint8_t rcp = req & RECIPIENT;
|
||||||
|
uint16_t status_info = 0;
|
||||||
|
|
||||||
status_info = 0; /* Reset Status Information */
|
if (detail->value != 0 || detail->len != 2 || (detail->index >> 8) != 0
|
||||||
data_p->addr = (uint8_t *)&status_info;
|
|
||||||
|
|
||||||
if (value != 0 || length != 2 || (index >> 8) != 0
|
|
||||||
|| (req & REQUEST_DIR) == 0)
|
|| (req & REQUEST_DIR) == 0)
|
||||||
return USB_UNSUPPORT;
|
return USB_UNSUPPORT;
|
||||||
|
|
||||||
if (rcp == DEVICE_RECIPIENT)
|
if (rcp == DEVICE_RECIPIENT)
|
||||||
{
|
{
|
||||||
if (index == 0)
|
if (detail->index == 0)
|
||||||
{
|
{
|
||||||
/* Get Device Status */
|
/* Get Device Status */
|
||||||
uint8_t feature = dev_p->current_feature;
|
uint8_t feature = dev_p->current_feature;
|
||||||
@@ -517,8 +498,7 @@ static int std_get_status (uint8_t req,
|
|||||||
else /* Self-powered */
|
else /* Self-powered */
|
||||||
status_info &= ~1;
|
status_info &= ~1;
|
||||||
|
|
||||||
data_p->len = 2;
|
return usb_lld_reply_request (&status_info, 2, detail);
|
||||||
return USB_SUCCESS;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (rcp == INTERFACE_RECIPIENT)
|
else if (rcp == INTERFACE_RECIPIENT)
|
||||||
@@ -528,22 +508,21 @@ static int std_get_status (uint8_t req,
|
|||||||
if (dev_p->current_configuration == 0)
|
if (dev_p->current_configuration == 0)
|
||||||
return USB_UNSUPPORT;
|
return USB_UNSUPPORT;
|
||||||
|
|
||||||
r = usb_cb_interface (USB_QUERY_INTERFACE, index, 0);
|
r = usb_cb_interface (USB_QUERY_INTERFACE, detail);
|
||||||
if (r != USB_SUCCESS)
|
if (r != USB_SUCCESS)
|
||||||
return USB_UNSUPPORT;
|
return USB_UNSUPPORT;
|
||||||
|
|
||||||
data_p->len = 2;
|
return usb_lld_reply_request (&status_info, 2, detail);
|
||||||
return USB_SUCCESS;
|
|
||||||
}
|
}
|
||||||
else if (rcp == ENDPOINT_RECIPIENT)
|
else if (rcp == ENDPOINT_RECIPIENT)
|
||||||
{
|
{
|
||||||
uint8_t endpoint = (index & 0x0f);
|
uint8_t endpoint = (detail->index & 0x0f);
|
||||||
uint16_t status;
|
uint16_t status;
|
||||||
|
|
||||||
if ((index & 0x70) || endpoint == ENDP0)
|
if ((detail->index & 0x70) || endpoint == ENDP0)
|
||||||
return USB_UNSUPPORT;
|
return USB_UNSUPPORT;
|
||||||
|
|
||||||
if ((index & 0x80))
|
if ((detail->index & 0x80))
|
||||||
{
|
{
|
||||||
status = st103_ep_get_tx_status (endpoint);
|
status = st103_ep_get_tx_status (endpoint);
|
||||||
if (status == 0) /* Disabled */
|
if (status == 0) /* Disabled */
|
||||||
@@ -560,15 +539,13 @@ static int std_get_status (uint8_t req,
|
|||||||
status_info |= 1; /* OUT Endpoint stalled */
|
status_info |= 1; /* OUT Endpoint stalled */
|
||||||
}
|
}
|
||||||
|
|
||||||
data_p->len = 2;
|
return usb_lld_reply_request (&status_info, 2, detail);
|
||||||
return USB_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return USB_UNSUPPORT;
|
return USB_UNSUPPORT;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int std_clear_feature (uint8_t req, uint16_t value,
|
static int std_clear_feature (uint8_t req, struct control_info *detail)
|
||||||
uint16_t index, uint16_t length)
|
|
||||||
{
|
{
|
||||||
uint8_t rcp = req & RECIPIENT;
|
uint8_t rcp = req & RECIPIENT;
|
||||||
|
|
||||||
@@ -577,10 +554,10 @@ static int std_clear_feature (uint8_t req, uint16_t value,
|
|||||||
|
|
||||||
if (rcp == DEVICE_RECIPIENT)
|
if (rcp == DEVICE_RECIPIENT)
|
||||||
{
|
{
|
||||||
if (length != 0 || index != 0)
|
if (detail->len != 0 || detail->index != 0)
|
||||||
return USB_UNSUPPORT;
|
return USB_UNSUPPORT;
|
||||||
|
|
||||||
if (value == DEVICE_REMOTE_WAKEUP)
|
if (detail->value == DEVICE_REMOTE_WAKEUP)
|
||||||
{
|
{
|
||||||
dev_p->current_feature &= ~(1 << 5);
|
dev_p->current_feature &= ~(1 << 5);
|
||||||
return USB_SUCCESS;
|
return USB_SUCCESS;
|
||||||
@@ -588,17 +565,17 @@ static int std_clear_feature (uint8_t req, uint16_t value,
|
|||||||
}
|
}
|
||||||
else if (rcp == ENDPOINT_RECIPIENT)
|
else if (rcp == ENDPOINT_RECIPIENT)
|
||||||
{
|
{
|
||||||
uint8_t endpoint = (index & 0x0f);
|
uint8_t endpoint = (detail->index & 0x0f);
|
||||||
uint16_t status;
|
uint16_t status;
|
||||||
|
|
||||||
if (dev_p->current_configuration == 0)
|
if (dev_p->current_configuration == 0)
|
||||||
return USB_UNSUPPORT;
|
return USB_UNSUPPORT;
|
||||||
|
|
||||||
if (length != 0 || (index >> 8) != 0 || value != ENDPOINT_STALL
|
if (detail->len != 0 || (detail->index >> 8) != 0
|
||||||
|| endpoint == ENDP0)
|
|| detail->value != ENDPOINT_STALL || endpoint == ENDP0)
|
||||||
return USB_UNSUPPORT;
|
return USB_UNSUPPORT;
|
||||||
|
|
||||||
if ((index & 0x80))
|
if ((detail->index & 0x80))
|
||||||
status = st103_ep_get_tx_status (endpoint);
|
status = st103_ep_get_tx_status (endpoint);
|
||||||
else
|
else
|
||||||
status = st103_ep_get_rx_status (endpoint);
|
status = st103_ep_get_rx_status (endpoint);
|
||||||
@@ -606,7 +583,7 @@ static int std_clear_feature (uint8_t req, uint16_t value,
|
|||||||
if (status == 0) /* Disabled */
|
if (status == 0) /* Disabled */
|
||||||
return USB_UNSUPPORT;
|
return USB_UNSUPPORT;
|
||||||
|
|
||||||
if (index & 0x80) /* IN endpoint */
|
if (detail->index & 0x80) /* IN endpoint */
|
||||||
st103_ep_clear_dtog_tx (endpoint);
|
st103_ep_clear_dtog_tx (endpoint);
|
||||||
else /* OUT endpoint */
|
else /* OUT endpoint */
|
||||||
st103_ep_clear_dtog_rx (endpoint);
|
st103_ep_clear_dtog_rx (endpoint);
|
||||||
@@ -618,8 +595,7 @@ static int std_clear_feature (uint8_t req, uint16_t value,
|
|||||||
return USB_UNSUPPORT;
|
return USB_UNSUPPORT;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int std_set_feature (uint8_t req, uint16_t value,
|
static int std_set_feature (uint8_t req, struct control_info *detail)
|
||||||
uint16_t index, uint16_t length)
|
|
||||||
{
|
{
|
||||||
uint8_t rcp = req & RECIPIENT;
|
uint8_t rcp = req & RECIPIENT;
|
||||||
|
|
||||||
@@ -628,10 +604,10 @@ static int std_set_feature (uint8_t req, uint16_t value,
|
|||||||
|
|
||||||
if (rcp == DEVICE_RECIPIENT)
|
if (rcp == DEVICE_RECIPIENT)
|
||||||
{
|
{
|
||||||
if (length != 0 || index != 0)
|
if (detail->len != 0 || detail->index != 0)
|
||||||
return USB_UNSUPPORT;
|
return USB_UNSUPPORT;
|
||||||
|
|
||||||
if (value == DEVICE_REMOTE_WAKEUP)
|
if (detail->value == DEVICE_REMOTE_WAKEUP)
|
||||||
{
|
{
|
||||||
dev_p->current_feature |= 1 << 5;
|
dev_p->current_feature |= 1 << 5;
|
||||||
// event??
|
// event??
|
||||||
@@ -640,16 +616,17 @@ static int std_set_feature (uint8_t req, uint16_t value,
|
|||||||
}
|
}
|
||||||
else if (rcp == ENDPOINT_RECIPIENT)
|
else if (rcp == ENDPOINT_RECIPIENT)
|
||||||
{
|
{
|
||||||
uint8_t endpoint = (index & 0x0f);
|
uint8_t endpoint = (detail->index & 0x0f);
|
||||||
uint32_t status;
|
uint32_t status;
|
||||||
|
|
||||||
if (dev_p->current_configuration == 0)
|
if (dev_p->current_configuration == 0)
|
||||||
return USB_UNSUPPORT;
|
return USB_UNSUPPORT;
|
||||||
|
|
||||||
if (length != 0 || (index >> 8) != 0 || value != 0 || endpoint == ENDP0)
|
if (detail->len != 0 || (detail->index >> 8) != 0
|
||||||
|
|| detail->value != 0 || endpoint == ENDP0)
|
||||||
return USB_UNSUPPORT;
|
return USB_UNSUPPORT;
|
||||||
|
|
||||||
if ((index & 0x80))
|
if ((detail->index & 0x80))
|
||||||
status = st103_ep_get_tx_status (endpoint);
|
status = st103_ep_get_tx_status (endpoint);
|
||||||
else
|
else
|
||||||
status = st103_ep_get_rx_status (endpoint);
|
status = st103_ep_get_rx_status (endpoint);
|
||||||
@@ -657,7 +634,7 @@ static int std_set_feature (uint8_t req, uint16_t value,
|
|||||||
if (status == 0) /* Disabled */
|
if (status == 0) /* Disabled */
|
||||||
return USB_UNSUPPORT;
|
return USB_UNSUPPORT;
|
||||||
|
|
||||||
if (index & 0x80)
|
if (detail->index & 0x80)
|
||||||
/* IN endpoint */
|
/* IN endpoint */
|
||||||
st103_ep_set_tx_status (endpoint, EP_TX_STALL);
|
st103_ep_set_tx_status (endpoint, EP_TX_STALL);
|
||||||
else
|
else
|
||||||
@@ -671,77 +648,59 @@ static int std_set_feature (uint8_t req, uint16_t value,
|
|||||||
return USB_UNSUPPORT;
|
return USB_UNSUPPORT;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int std_set_address (uint8_t req, uint16_t value,
|
static int std_set_address (uint8_t req, struct control_info *detail)
|
||||||
uint16_t index, uint16_t length)
|
|
||||||
{
|
{
|
||||||
uint8_t rcp = req & RECIPIENT;
|
uint8_t rcp = req & RECIPIENT;
|
||||||
|
|
||||||
if ((req & REQUEST_DIR) == 1)
|
if ((req & REQUEST_DIR) == 1)
|
||||||
return USB_UNSUPPORT;
|
return USB_UNSUPPORT;
|
||||||
|
|
||||||
if (rcp == DEVICE_RECIPIENT)
|
if (rcp == DEVICE_RECIPIENT && detail->len == 0 && detail->value <= 127
|
||||||
{
|
&& detail->index == 0 && dev_p->current_configuration == 0)
|
||||||
if (length == 0 && value <= 127 && index == 0
|
return USB_SUCCESS;
|
||||||
&& dev_p->current_configuration == 0)
|
|
||||||
return USB_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
return USB_UNSUPPORT;
|
return USB_UNSUPPORT;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int std_get_descriptor (uint8_t req, uint16_t value,
|
static int std_get_descriptor (uint8_t req, struct control_info *detail)
|
||||||
uint16_t index, uint16_t length)
|
|
||||||
{
|
{
|
||||||
uint8_t rcp = req & RECIPIENT;
|
uint8_t rcp = req & RECIPIENT;
|
||||||
|
|
||||||
if ((req & REQUEST_DIR) == 0)
|
if ((req & REQUEST_DIR) == 0)
|
||||||
return USB_UNSUPPORT;
|
return USB_UNSUPPORT;
|
||||||
|
|
||||||
(void)length;
|
return usb_cb_get_descriptor (rcp, (detail->value >> 8),
|
||||||
return usb_cb_get_descriptor (rcp, (value >> 8), (value & 0xff), index);
|
(detail->value & 0xff), detail);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int std_get_configuration (uint8_t req, uint16_t value,
|
static int std_get_configuration (uint8_t req, struct control_info *detail)
|
||||||
uint16_t index, uint16_t length)
|
|
||||||
{
|
{
|
||||||
uint8_t rcp = req & RECIPIENT;
|
uint8_t rcp = req & RECIPIENT;
|
||||||
|
|
||||||
|
(void)detail;
|
||||||
if ((req & REQUEST_DIR) == 0)
|
if ((req & REQUEST_DIR) == 0)
|
||||||
return USB_UNSUPPORT;
|
return USB_UNSUPPORT;
|
||||||
|
|
||||||
(void)value; (void)index; (void)length;
|
|
||||||
if (rcp == DEVICE_RECIPIENT)
|
if (rcp == DEVICE_RECIPIENT)
|
||||||
{
|
return usb_lld_reply_request (&dev_p->current_configuration, 1, detail);
|
||||||
data_p->addr = &dev_p->current_configuration;
|
|
||||||
data_p->len = 1;
|
|
||||||
return USB_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
return USB_UNSUPPORT;
|
return USB_UNSUPPORT;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int std_set_configuration (uint8_t req, uint16_t value,
|
static int std_set_configuration (uint8_t req, struct control_info *detail)
|
||||||
uint16_t index, uint16_t length)
|
|
||||||
{
|
{
|
||||||
uint8_t rcp = req & RECIPIENT;
|
uint8_t rcp = req & RECIPIENT;
|
||||||
|
|
||||||
if ((req & REQUEST_DIR) == 1)
|
if ((req & REQUEST_DIR) == 1)
|
||||||
return USB_UNSUPPORT;
|
return USB_UNSUPPORT;
|
||||||
|
|
||||||
if (rcp == DEVICE_RECIPIENT && index == 0 && length == 0)
|
if (rcp == DEVICE_RECIPIENT && detail->index == 0 && detail->len == 0)
|
||||||
{
|
return usb_cb_handle_event (USB_EVENT_CONFIG, detail->value);
|
||||||
int r;
|
|
||||||
|
|
||||||
r = usb_cb_handle_event (USB_EVENT_CONFIG, value);
|
|
||||||
if (r == USB_SUCCESS)
|
|
||||||
return USB_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
return USB_UNSUPPORT;
|
return USB_UNSUPPORT;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int std_get_interface (uint8_t req, uint16_t value,
|
static int std_get_interface (uint8_t req, struct control_info *detail)
|
||||||
uint16_t index, uint16_t length)
|
|
||||||
{
|
{
|
||||||
uint8_t rcp = req & RECIPIENT;
|
uint8_t rcp = req & RECIPIENT;
|
||||||
|
|
||||||
@@ -750,74 +709,61 @@ static int std_get_interface (uint8_t req, uint16_t value,
|
|||||||
|
|
||||||
if (rcp == INTERFACE_RECIPIENT)
|
if (rcp == INTERFACE_RECIPIENT)
|
||||||
{
|
{
|
||||||
if (value != 0 || (index >> 8) != 0 || length != 1)
|
if (detail->value != 0 || (detail->index >> 8) != 0 || detail->len != 1)
|
||||||
return USB_UNSUPPORT;
|
return USB_UNSUPPORT;
|
||||||
|
|
||||||
if (dev_p->current_configuration == 0)
|
if (dev_p->current_configuration == 0)
|
||||||
return USB_UNSUPPORT;
|
return USB_UNSUPPORT;
|
||||||
|
|
||||||
return usb_cb_interface (USB_GET_INTERFACE, index, 0);
|
return usb_cb_interface (USB_GET_INTERFACE, detail);
|
||||||
}
|
}
|
||||||
|
|
||||||
return USB_UNSUPPORT;
|
return USB_UNSUPPORT;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int std_set_interface (uint8_t req, uint16_t value,
|
static int std_set_interface (uint8_t req, struct control_info *detail)
|
||||||
uint16_t index, uint16_t length)
|
|
||||||
{
|
{
|
||||||
uint8_t rcp = req & RECIPIENT;
|
uint8_t rcp = req & RECIPIENT;
|
||||||
|
|
||||||
if ((req & REQUEST_DIR) == 1)
|
if ((req & REQUEST_DIR) == 1 || rcp != INTERFACE_RECIPIENT
|
||||||
|
|| detail->len != 0 || (detail->index >> 8) != 0
|
||||||
|
|| (detail->value >> 8) != 0 || dev_p->current_configuration != 0)
|
||||||
return USB_UNSUPPORT;
|
return USB_UNSUPPORT;
|
||||||
|
|
||||||
if (rcp == INTERFACE_RECIPIENT)
|
return usb_cb_interface (USB_SET_INTERFACE, detail);
|
||||||
{
|
|
||||||
int r;
|
|
||||||
|
|
||||||
if (length != 0 || (index >> 8) != 0 || (value >> 8) != 0)
|
|
||||||
return USB_UNSUPPORT;
|
|
||||||
|
|
||||||
if (dev_p->current_configuration != 0)
|
|
||||||
return USB_UNSUPPORT;
|
|
||||||
|
|
||||||
r = usb_cb_interface (USB_SET_INTERFACE, index, value);
|
|
||||||
if (r == USB_SUCCESS)
|
|
||||||
return USB_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
return USB_UNSUPPORT;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void handle_setup0 (void)
|
static void handle_setup0 (void)
|
||||||
{
|
{
|
||||||
const uint16_t *pw;
|
const uint16_t *pw;
|
||||||
|
struct control_info ctrl;
|
||||||
uint16_t w;
|
uint16_t w;
|
||||||
uint8_t req;
|
uint8_t req_no;
|
||||||
int r = USB_UNSUPPORT;
|
int r = USB_UNSUPPORT;
|
||||||
HANDLER handler;
|
HANDLER handler;
|
||||||
|
|
||||||
pw = (uint16_t *)(PMA_ADDR + (uint8_t *)(st103_get_rx_addr (ENDP0) * 2));
|
pw = (uint16_t *)(PMA_ADDR + (uint8_t *)(st103_get_rx_addr (ENDP0) * 2));
|
||||||
w = *pw++;
|
w = *pw++;
|
||||||
|
|
||||||
ctrl_p->bmRequestType = w & 0xff;
|
dev_p->bmRequestType = w & 0xff;
|
||||||
ctrl_p->bRequest = req = w >> 8;
|
dev_p->bRequest = req_no = w >> 8;
|
||||||
pw++;
|
pw++;
|
||||||
ctrl_p->wValue = *pw++;
|
ctrl.value = *pw++;
|
||||||
pw++;
|
pw++;
|
||||||
ctrl_p->wIndex = *pw++;
|
ctrl.index = *pw++;
|
||||||
pw++;
|
pw++;
|
||||||
ctrl_p->wLength = *pw;
|
ctrl.len = *pw;
|
||||||
|
|
||||||
data_p->addr = NULL;
|
data_p->addr = NULL;
|
||||||
data_p->len = 0;
|
data_p->len = 0;
|
||||||
data_p->offset = 0;
|
data_p->require_zlp = 0;
|
||||||
|
|
||||||
if ((ctrl_p->bmRequestType & REQUEST_TYPE) == STANDARD_REQUEST)
|
if ((dev_p->bmRequestType & REQUEST_TYPE) == STANDARD_REQUEST)
|
||||||
{
|
{
|
||||||
if (req < TOTAL_REQUEST)
|
if (req_no < TOTAL_REQUEST)
|
||||||
{
|
{
|
||||||
switch (req)
|
switch (req_no)
|
||||||
{
|
{
|
||||||
case 0: handler = std_get_status; break;
|
case 0: handler = std_get_status; break;
|
||||||
case 1: handler = std_clear_feature; break;
|
case 1: handler = std_clear_feature; break;
|
||||||
@@ -831,44 +777,30 @@ static void handle_setup0 (void)
|
|||||||
default: handler = std_none; break;
|
default: handler = std_none; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
r = (*handler) (ctrl_p->bmRequestType,
|
r = (*handler) (dev_p->bmRequestType, &ctrl);
|
||||||
ctrl_p->wValue, ctrl_p->wIndex, ctrl_p->wLength);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
r = usb_cb_setup (ctrl_p->bmRequestType, req,
|
r = usb_cb_setup (dev_p->bmRequestType, req_no, &ctrl);
|
||||||
ctrl_p->wValue, ctrl_p->wIndex, ctrl_p->wLength);
|
|
||||||
|
|
||||||
if (r != USB_SUCCESS)
|
if (r != USB_SUCCESS)
|
||||||
dev_p->state = STALLED;
|
dev_p->state = STALLED;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (USB_SETUP_GET (ctrl_p->bmRequestType))
|
if (USB_SETUP_SET (dev_p->bmRequestType))
|
||||||
{
|
{
|
||||||
uint32_t len = ctrl_p->wLength;
|
dev_p->value = ctrl.value;
|
||||||
|
if (ctrl.len == 0)
|
||||||
/* Restrict the data length to be the one host asks for */
|
{
|
||||||
if (data_p->len > len)
|
dev_p->state = WAIT_STATUS_IN;
|
||||||
data_p->len = len;
|
st103_set_tx_count (ENDP0, 0);
|
||||||
|
st103_ep_set_rxtx_status (ENDP0, EP_RX_STALL, EP_TX_VALID);
|
||||||
if ((data_p->len % USB_MAX_PACKET_SIZE) == 0)
|
}
|
||||||
data_p->require_zlp = TRUE;
|
|
||||||
else
|
else
|
||||||
data_p->require_zlp = FALSE;
|
{
|
||||||
|
dev_p->state = OUT_DATA;
|
||||||
dev_p->state = IN_DATA;
|
st103_ep_set_rx_status (ENDP0, EP_RX_VALID);
|
||||||
handle_datastage_in ();
|
}
|
||||||
}
|
|
||||||
else if (ctrl_p->wLength == 0)
|
|
||||||
{
|
|
||||||
dev_p->state = WAIT_STATUS_IN;
|
|
||||||
st103_set_tx_count (ENDP0, 0);
|
|
||||||
st103_ep_set_rxtx_status (ENDP0, EP_RX_STALL, EP_TX_VALID);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
dev_p->state = OUT_DATA;
|
|
||||||
st103_ep_set_rx_status (ENDP0, EP_RX_VALID);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -879,17 +811,16 @@ static void handle_in0 (void)
|
|||||||
handle_datastage_in ();
|
handle_datastage_in ();
|
||||||
else if (dev_p->state == WAIT_STATUS_IN)
|
else if (dev_p->state == WAIT_STATUS_IN)
|
||||||
{
|
{
|
||||||
if ((ctrl_p->bRequest == SET_ADDRESS) &&
|
if ((dev_p->bRequest == SET_ADDRESS) &&
|
||||||
((ctrl_p->bmRequestType & (REQUEST_TYPE | RECIPIENT))
|
((dev_p->bmRequestType & (REQUEST_TYPE | RECIPIENT))
|
||||||
== (STANDARD_REQUEST | DEVICE_RECIPIENT)))
|
== (STANDARD_REQUEST | DEVICE_RECIPIENT)))
|
||||||
{
|
{
|
||||||
st103_set_daddr (ctrl_p->wValue);
|
st103_set_daddr (dev_p->value);
|
||||||
usb_cb_handle_event (USB_EVENT_ADDRESS, ctrl_p->wValue);
|
usb_cb_handle_event (USB_EVENT_ADDRESS, dev_p->value);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
usb_cb_ctrl_write_finish (ctrl_p->bmRequestType,
|
usb_cb_ctrl_write_finish (dev_p->bmRequestType, dev_p->bRequest,
|
||||||
ctrl_p->bRequest, ctrl_p->wValue,
|
dev_p->value);
|
||||||
ctrl_p->wIndex, ctrl_p->wLength);
|
|
||||||
|
|
||||||
dev_p->state = STALLED;
|
dev_p->state = STALLED;
|
||||||
}
|
}
|
||||||
@@ -1111,7 +1042,7 @@ void usb_lld_set_feature (uint8_t feature)
|
|||||||
dev_p->current_feature = feature;
|
dev_p->current_feature = feature;
|
||||||
}
|
}
|
||||||
|
|
||||||
void usb_lld_set_data_to_send (const void *p, size_t len)
|
void usb_lld_set_data_to_recv (const void *p, size_t len)
|
||||||
{
|
{
|
||||||
data_p->addr = (uint8_t *)p;
|
data_p->addr = (uint8_t *)p;
|
||||||
data_p->len = len;
|
data_p->len = len;
|
||||||
@@ -1189,3 +1120,49 @@ void usb_lld_from_pmabuf (void *dst, uint16_t addr, size_t n)
|
|||||||
*d = (w & 0xff);
|
*d = (w & 0xff);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* BUF: Pointer to data memory. Data memory should not be allocated
|
||||||
|
* on stack when BUFLEN > USB_MAX_PACKET_SIZE.
|
||||||
|
*
|
||||||
|
* BUFLEN: size of the data.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
usb_lld_reply_request (const void *buf, size_t buflen, struct control_info *ctl)
|
||||||
|
{
|
||||||
|
uint32_t len_asked = ctl->len;
|
||||||
|
uint32_t len;
|
||||||
|
|
||||||
|
data_p->addr = (void *)buf;
|
||||||
|
data_p->len = buflen;
|
||||||
|
|
||||||
|
/* Restrict the data length to be the one host asks for */
|
||||||
|
if (data_p->len > len_asked)
|
||||||
|
data_p->len = len_asked;
|
||||||
|
|
||||||
|
if (data_p->len != 0 && (data_p->len % USB_MAX_PACKET_SIZE) == 0)
|
||||||
|
data_p->require_zlp = 1;
|
||||||
|
|
||||||
|
if (data_p->len < USB_MAX_PACKET_SIZE)
|
||||||
|
{
|
||||||
|
len = data_p->len;
|
||||||
|
dev_p->state = LAST_IN_DATA;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
len = USB_MAX_PACKET_SIZE;
|
||||||
|
dev_p->state = IN_DATA;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (len)
|
||||||
|
{
|
||||||
|
usb_lld_to_pmabuf (data_p->addr, st103_get_tx_addr (ENDP0), len);
|
||||||
|
data_p->len -= len;
|
||||||
|
data_p->addr += len;
|
||||||
|
}
|
||||||
|
|
||||||
|
st103_set_tx_count (ENDP0, len);
|
||||||
|
st103_ep_set_tx_status (ENDP0, EP_TX_VALID);
|
||||||
|
return USB_SUCCESS;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user