Fixed HALT condition handling and data toggle.
This commit is contained in:
@@ -52,10 +52,10 @@
|
|||||||
*/
|
*/
|
||||||
#define TOG_SET_REG_BIT_MSK(REG, MSK, BIT) \
|
#define TOG_SET_REG_BIT_MSK(REG, MSK, BIT) \
|
||||||
do { \
|
do { \
|
||||||
register u16 toggle_mask = GET_REG(REG) & MSK; \
|
register u16 toggle_mask = GET_REG(REG) & (MSK); \
|
||||||
register u16 bit_selector; \
|
register u16 bit_selector; \
|
||||||
for (bit_selector = 1; bit_selector; bit_selector <<= 1) { \
|
for (bit_selector = 1; bit_selector; bit_selector <<= 1) { \
|
||||||
if ((bit_selector & BIT) != 0) \
|
if ((bit_selector & (BIT)) != 0) \
|
||||||
toggle_mask ^= bit_selector; \
|
toggle_mask ^= bit_selector; \
|
||||||
} \
|
} \
|
||||||
SET_REG(REG, toggle_mask); \
|
SET_REG(REG, toggle_mask); \
|
||||||
|
|||||||
@@ -244,6 +244,18 @@
|
|||||||
(USB_EP_NTOGGLE_MSK & \
|
(USB_EP_NTOGGLE_MSK & \
|
||||||
(~USB_EP_ADDR))) | ADDR))
|
(~USB_EP_ADDR))) | ADDR))
|
||||||
|
|
||||||
|
/* Macros for clearing DTOG bits */
|
||||||
|
#define USB_CLR_EP_TX_DTOG(EP) \
|
||||||
|
SET_REG(USB_EP_REG(EP), \
|
||||||
|
(GET_REG(USB_EP_REG(EP)) & \
|
||||||
|
USB_EP_NTOGGLE_MSK) | USB_EP_TX_DTOG)
|
||||||
|
|
||||||
|
#define USB_CLR_EP_RX_DTOG(EP) \
|
||||||
|
SET_REG(USB_EP_REG(EP), \
|
||||||
|
(GET_REG(USB_EP_REG(EP)) & \
|
||||||
|
USB_EP_NTOGGLE_MSK) | USB_EP_RX_DTOG)
|
||||||
|
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* USB BTABLE registers
|
* USB BTABLE registers
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|||||||
@@ -64,7 +64,8 @@ usbd_ep_write_packet(uint8_t addr, const void *buf, uint16_t len);
|
|||||||
extern uint16_t
|
extern uint16_t
|
||||||
usbd_ep_read_packet(uint8_t addr, void *buf, uint16_t len);
|
usbd_ep_read_packet(uint8_t addr, void *buf, uint16_t len);
|
||||||
|
|
||||||
extern void usbd_ep_stall(uint8_t addr);
|
extern void usbd_ep_stall_set(uint8_t addr, uint8_t stall);
|
||||||
|
extern uint8_t usbd_ep_stall_get(uint8_t addr);
|
||||||
|
|
||||||
/* Optional */
|
/* Optional */
|
||||||
extern void usbd_cable_connect(uint8_t on);
|
extern void usbd_cable_connect(uint8_t on);
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ static int usb_control_recv_chunk(void)
|
|||||||
packetsize);
|
packetsize);
|
||||||
|
|
||||||
if (size != packetsize) {
|
if (size != packetsize) {
|
||||||
usbd_ep_stall(0);
|
usbd_ep_stall_set(0, 1);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -127,7 +127,7 @@ static void usb_control_setup_nodata(struct usb_setup_data *req)
|
|||||||
control_state.state = STATUS_IN;
|
control_state.state = STATUS_IN;
|
||||||
} else {
|
} else {
|
||||||
/* Stall endpoint on failure */
|
/* 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();
|
usb_control_send_chunk();
|
||||||
} else {
|
} else {
|
||||||
/* Stall endpoint on failure */
|
/* 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)
|
static void usb_control_setup_write(struct usb_setup_data *req)
|
||||||
{
|
{
|
||||||
if(req->wLength > _usbd_device.ctrl_buf_len) {
|
if(req->wLength > _usbd_device.ctrl_buf_len) {
|
||||||
usbd_ep_stall(0);
|
usbd_ep_stall_set(0, 1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -184,7 +184,7 @@ void _usbd_control_setup(uint8_t ea)
|
|||||||
control_state.complete = NULL;
|
control_state.complete = NULL;
|
||||||
|
|
||||||
if(usbd_ep_read_packet(0, req, 8) != 8) {
|
if(usbd_ep_read_packet(0, req, 8) != 8) {
|
||||||
usbd_ep_stall(0);
|
usbd_ep_stall_set(0, 1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -233,7 +233,7 @@ void _usbd_control_out(uint8_t ea)
|
|||||||
usbd_ep_write_packet(0, NULL, 0);
|
usbd_ep_write_packet(0, NULL, 0);
|
||||||
control_state.state = STATUS_IN;
|
control_state.state = STATUS_IN;
|
||||||
} else {
|
} else {
|
||||||
usbd_ep_stall(0);
|
usbd_ep_stall_set(0, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@@ -249,7 +249,7 @@ void _usbd_control_out(uint8_t ea)
|
|||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
usbd_ep_stall(0);
|
usbd_ep_stall_set(0, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -280,7 +280,7 @@ void _usbd_control_in(uint8_t ea)
|
|||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
usbd_ep_stall(0);
|
usbd_ep_stall_set(0, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
USB_SET_EP_TX_ADDR(addr, _usbd_device.pm_top);
|
||||||
if(callback)
|
if(callback)
|
||||||
_usbd_device.user_callback_ctr[addr][USB_TRANSACTION_IN] = (void*)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);
|
USB_SET_EP_TX_STAT(addr, USB_EP_TX_STAT_NAK);
|
||||||
_usbd_device.pm_top += max_size;
|
_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);
|
usb_set_ep_rx_bufsize(addr, max_size);
|
||||||
if(callback)
|
if(callback)
|
||||||
_usbd_device.user_callback_ctr[addr][USB_TRANSACTION_OUT] = (void*)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);
|
USB_SET_EP_RX_STAT(addr, USB_EP_RX_STAT_VALID);
|
||||||
_usbd_device.pm_top += max_size;
|
_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);
|
_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)
|
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)
|
if(addr & 0x80) {
|
||||||
USB_SET_EP_TX_STAT(addr, USB_EP_TX_STAT_STALL);
|
addr &= 0x7F;
|
||||||
else
|
|
||||||
USB_SET_EP_RX_STAT(addr&0x7F, USB_EP_RX_STAT_STALL);
|
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(addr & 0x80) {
|
||||||
if ((*USB_EP_REG(addr) & USB_EP_TX_STAT) == USB_EP_TX_STAT_STALL)
|
if ((*USB_EP_REG(addr & 0x7F) & USB_EP_TX_STAT) ==
|
||||||
return 1;
|
USB_EP_TX_STAT_STALL)
|
||||||
|
return 1;
|
||||||
} else {
|
} 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 1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -220,7 +220,7 @@ static int usb_standard_endpoint_get_status(struct usb_setup_data *req,
|
|||||||
(void)req;
|
(void)req;
|
||||||
|
|
||||||
if(*len > 2) *len = 2;
|
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;
|
(*buf)[1] = 0;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
@@ -232,7 +232,7 @@ static int usb_standard_endpoint_stall(struct usb_setup_data *req,
|
|||||||
(void)buf;
|
(void)buf;
|
||||||
(void)len;
|
(void)len;
|
||||||
|
|
||||||
usbd_ep_stall(req->wIndex);
|
usbd_ep_stall_set(req->wIndex, 1);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -243,7 +243,7 @@ static int usb_standard_endpoint_unstall(struct usb_setup_data *req,
|
|||||||
(void)buf;
|
(void)buf;
|
||||||
(void)len;
|
(void)len;
|
||||||
|
|
||||||
usbd_ep_stall(req->wIndex);
|
usbd_ep_stall_set(req->wIndex, 0);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -329,12 +329,12 @@ int _usbd_standard_request_endpoint(struct usb_setup_data *req, uint8_t **buf,
|
|||||||
switch(req->bRequest) {
|
switch(req->bRequest) {
|
||||||
case USB_REQ_CLEAR_FEATURE:
|
case USB_REQ_CLEAR_FEATURE:
|
||||||
if (req->wValue == USB_FEAT_ENDPOINT_HALT) {
|
if (req->wValue == USB_FEAT_ENDPOINT_HALT) {
|
||||||
command = usb_standard_endpoint_stall;
|
command = usb_standard_endpoint_unstall;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case USB_REQ_SET_FEATURE:
|
case USB_REQ_SET_FEATURE:
|
||||||
if (req->wValue == USB_FEAT_ENDPOINT_HALT) {
|
if (req->wValue == USB_FEAT_ENDPOINT_HALT) {
|
||||||
command = usb_standard_endpoint_unstall;
|
command = usb_standard_endpoint_stall;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case USB_REQ_GET_STATUS:
|
case USB_REQ_GET_STATUS:
|
||||||
|
|||||||
Reference in New Issue
Block a user