aboutsummaryrefslogtreecommitdiff
path: root/lib/usb
diff options
context:
space:
mode:
authorGareth McMullin2010-11-04 16:49:03 +1300
committerGareth McMullin2010-11-04 16:49:03 +1300
commit87960830f4eb656f410ff3b220151e0b5ad9a556 (patch)
treece2ff6208c79ca40be61a27a5da0e46735ee2745 /lib/usb
parentd6eacce827a8ebffb5e82b48d4c88eb097594c1e (diff)
Fixed HALT condition handling and data toggle.
Diffstat (limited to 'lib/usb')
-rw-r--r--lib/usb/usb_control.c16
-rw-r--r--lib/usb/usb_f103.c41
-rw-r--r--lib/usb/usb_standard.c10
3 files changed, 41 insertions, 26 deletions
diff --git a/lib/usb/usb_control.c b/lib/usb/usb_control.c
index 950e491..f5e4d27 100644
--- a/lib/usb/usb_control.c
+++ b/lib/usb/usb_control.c
@@ -93,7 +93,7 @@ static int usb_control_recv_chunk(void)
packetsize);
if (size != packetsize) {
- usbd_ep_stall(0);
+ usbd_ep_stall_set(0, 1);
return -1;
}
@@ -127,7 +127,7 @@ static void usb_control_setup_nodata(struct usb_setup_data *req)
control_state.state = STATUS_IN;
} else {
/* Stall endpoint on failure */
- usbd_ep_stall(0);
+ usbd_ep_stall_set(0, 1);
}
}
@@ -156,14 +156,14 @@ static void usb_control_setup_read(struct usb_setup_data *req)
usb_control_send_chunk();
} else {
/* Stall endpoint on failure */
- usbd_ep_stall(0);
+ usbd_ep_stall_set(0, 1);
}
}
static void usb_control_setup_write(struct usb_setup_data *req)
{
if(req->wLength > _usbd_device.ctrl_buf_len) {
- usbd_ep_stall(0);
+ usbd_ep_stall_set(0, 1);
return;
}
@@ -184,7 +184,7 @@ void _usbd_control_setup(uint8_t ea)
control_state.complete = NULL;
if(usbd_ep_read_packet(0, req, 8) != 8) {
- usbd_ep_stall(0);
+ usbd_ep_stall_set(0, 1);
return;
}
@@ -233,7 +233,7 @@ void _usbd_control_out(uint8_t ea)
usbd_ep_write_packet(0, NULL, 0);
control_state.state = STATUS_IN;
} else {
- usbd_ep_stall(0);
+ usbd_ep_stall_set(0, 1);
}
break;
@@ -249,7 +249,7 @@ void _usbd_control_out(uint8_t ea)
}
default:
- usbd_ep_stall(0);
+ usbd_ep_stall_set(0, 1);
}
}
@@ -280,7 +280,7 @@ void _usbd_control_in(uint8_t ea)
}
default:
- usbd_ep_stall(0);
+ usbd_ep_stall_set(0, 1);
}
}
diff --git a/lib/usb/usb_f103.c b/lib/usb/usb_f103.c
index 1af4493..5a79a82 100644
--- a/lib/usb/usb_f103.c
+++ b/lib/usb/usb_f103.c
@@ -83,6 +83,7 @@ void usbd_ep_setup(u8 addr, u8 type, u16 max_size, void (*callback)(u8 ep))
USB_SET_EP_TX_ADDR(addr, _usbd_device.pm_top);
if(callback)
_usbd_device.user_callback_ctr[addr][USB_TRANSACTION_IN] = (void*)callback;
+ USB_CLR_EP_TX_DTOG(addr);
USB_SET_EP_TX_STAT(addr, USB_EP_TX_STAT_NAK);
_usbd_device.pm_top += max_size;
}
@@ -91,6 +92,7 @@ void usbd_ep_setup(u8 addr, u8 type, u16 max_size, void (*callback)(u8 ep))
usb_set_ep_rx_bufsize(addr, max_size);
if(callback)
_usbd_device.user_callback_ctr[addr][USB_TRANSACTION_OUT] = (void*)callback;
+ USB_CLR_EP_RX_DTOG(addr);
USB_SET_EP_RX_STAT(addr, USB_EP_RX_STAT_VALID);
_usbd_device.pm_top += max_size;
}
@@ -108,27 +110,40 @@ void _usbd_hw_endpoints_reset(void)
_usbd_device.pm_top = 0x40 + (2*_usbd_device.desc->bMaxPacketSize0);
}
-void usbd_ep_stall(u8 addr)
+void usbd_ep_stall_set(u8 addr, u8 stall)
{
if(addr == 0)
- USB_SET_EP_TX_STAT(addr, USB_EP_TX_STAT_STALL);
+ USB_SET_EP_TX_STAT(addr,
+ stall ? USB_EP_TX_STAT_STALL : USB_EP_TX_STAT_NAK);
- if(addr & 0x80)
- USB_SET_EP_TX_STAT(addr, USB_EP_TX_STAT_STALL);
- else
- USB_SET_EP_RX_STAT(addr&0x7F, USB_EP_RX_STAT_STALL);
+ if(addr & 0x80) {
+ addr &= 0x7F;
+
+ USB_SET_EP_TX_STAT(addr,
+ stall ? USB_EP_TX_STAT_STALL : USB_EP_TX_STAT_NAK);
+
+ /* Reset to DATA0 if clearing stall condition */
+ if(!stall)
+ USB_CLR_EP_TX_DTOG(addr);
+ } else {
+ /* Reset to DATA0 if clearing stall condition */
+ if(!stall)
+ USB_CLR_EP_RX_DTOG(addr);
+
+ USB_SET_EP_RX_STAT(addr,
+ stall ? USB_EP_RX_STAT_STALL : USB_EP_RX_STAT_VALID);
+ }
}
-u8 usbd_get_ep_stall(u8 addr)
+u8 usbd_ep_stall_get(u8 addr)
{
- if(addr == 0)
- if ((*USB_EP_REG(addr) & USB_EP_TX_STAT) == USB_EP_TX_STAT_STALL)
- return 1;
if(addr & 0x80) {
- if ((*USB_EP_REG(addr) & USB_EP_TX_STAT) == USB_EP_TX_STAT_STALL)
- return 1;
+ if ((*USB_EP_REG(addr & 0x7F) & USB_EP_TX_STAT) ==
+ USB_EP_TX_STAT_STALL)
+ return 1;
} else {
- if ((*USB_EP_REG(addr&0x7F) & USB_EP_RX_STAT) == USB_EP_RX_STAT_STALL)
+ if ((*USB_EP_REG(addr) & USB_EP_RX_STAT) ==
+ USB_EP_RX_STAT_STALL)
return 1;
}
return 0;
diff --git a/lib/usb/usb_standard.c b/lib/usb/usb_standard.c
index ae6c2ee..770d3cc 100644
--- a/lib/usb/usb_standard.c
+++ b/lib/usb/usb_standard.c
@@ -220,7 +220,7 @@ static int usb_standard_endpoint_get_status(struct usb_setup_data *req,
(void)req;
if(*len > 2) *len = 2;
- (*buf)[0] = usbd_get_ep_stall(req->wIndex);
+ (*buf)[0] = usbd_ep_stall_get(req->wIndex) ? 1 : 0;
(*buf)[1] = 0;
return 1;
@@ -232,7 +232,7 @@ static int usb_standard_endpoint_stall(struct usb_setup_data *req,
(void)buf;
(void)len;
- usbd_ep_stall(req->wIndex);
+ usbd_ep_stall_set(req->wIndex, 1);
return 1;
}
@@ -243,7 +243,7 @@ static int usb_standard_endpoint_unstall(struct usb_setup_data *req,
(void)buf;
(void)len;
- usbd_ep_stall(req->wIndex);
+ usbd_ep_stall_set(req->wIndex, 0);
return 1;
}
@@ -329,12 +329,12 @@ int _usbd_standard_request_endpoint(struct usb_setup_data *req, uint8_t **buf,
switch(req->bRequest) {
case USB_REQ_CLEAR_FEATURE:
if (req->wValue == USB_FEAT_ENDPOINT_HALT) {
- command = usb_standard_endpoint_stall;
+ command = usb_standard_endpoint_unstall;
}
break;
case USB_REQ_SET_FEATURE:
if (req->wValue == USB_FEAT_ENDPOINT_HALT) {
- command = usb_standard_endpoint_unstall;
+ command = usb_standard_endpoint_stall;
}
break;
case USB_REQ_GET_STATUS: