Browse Source

Fixed HALT condition handling and data toggle.

pull/2/head
Gareth McMullin 14 years ago
parent
commit
87960830f4
  1. 4
      include/libopenstm32/tools.h
  2. 12
      include/libopenstm32/usb.h
  3. 3
      include/usbd.h
  4. 16
      lib/usb/usb_control.c
  5. 41
      lib/usb/usb_f103.c
  6. 10
      lib/usb/usb_standard.c

4
include/libopenstm32/tools.h

@ -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); \

12
include/libopenstm32/usb.h

@ -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
******************************************************************************/ ******************************************************************************/

3
include/usbd.h

@ -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);

16
lib/usb/usb_control.c

@ -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);
} }
} }

41
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); 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;

10
lib/usb/usb_standard.c

@ -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:

Loading…
Cancel
Save