summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/cc1111/ao_usb.c68
-rw-r--r--src/core/ao_usb.h1
2 files changed, 39 insertions, 30 deletions
diff --git a/src/cc1111/ao_usb.c b/src/cc1111/ao_usb.c
index 8bd2efdf..a655d1be 100644
--- a/src/cc1111/ao_usb.c
+++ b/src/cc1111/ao_usb.c
@@ -152,19 +152,17 @@ ao_usb_ep0_fill(void)
*ao_usb_ep0_out_data++ = USBFIFO[0];
}
-void
+static void
ao_usb_ep0_queue_byte(uint8_t a)
{
ao_usb_ep0_in_buf[ao_usb_ep0_in_len++] = a;
}
-void
+static void
ao_usb_set_address(uint8_t address)
{
ao_usb_running = 1;
- USBADDR = address | 0x80;
- while (USBADDR & 0x80)
- ;
+ USBADDR = address;
}
static void
@@ -191,24 +189,6 @@ ao_usb_ep0_setup(void)
if (ao_usb_ep0_out_len != 0)
return;
- /* Figure out how to ACK the setup packet */
- if (ao_usb_setup.dir_type_recip & AO_USB_DIR_IN) {
- if (ao_usb_setup.length)
- ao_usb_ep0_state = AO_USB_EP0_DATA_IN;
- else
- ao_usb_ep0_state = AO_USB_EP0_IDLE;
- } else {
- if (ao_usb_setup.length)
- ao_usb_ep0_state = AO_USB_EP0_DATA_OUT;
- else
- ao_usb_ep0_state = AO_USB_EP0_IDLE;
- }
- USBINDEX = 0;
- if (ao_usb_ep0_state == AO_USB_EP0_IDLE)
- USBCS0 = USBCS0_CLR_OUTPKT_RDY | USBCS0_DATA_END;
- else
- USBCS0 = USBCS0_CLR_OUTPKT_RDY;
-
ao_usb_ep0_in_data = ao_usb_ep0_in_buf;
ao_usb_ep0_in_len = 0;
switch(ao_usb_setup.dir_type_recip & AO_USB_SETUP_TYPE_MASK) {
@@ -274,10 +254,39 @@ ao_usb_ep0_setup(void)
}
break;
}
- if (ao_usb_ep0_state != AO_USB_EP0_DATA_OUT) {
+
+ /* Figure out how to ACK the setup packet and the
+ * next state
+ */
+ USBINDEX = 0;
+ if (ao_usb_ep0_in_len) {
+
+ /* Sending data back to the host
+ */
+ ao_usb_ep0_state = AO_USB_EP0_DATA_IN;
+ USBCS0 = USBCS0_CLR_OUTPKT_RDY;
if (ao_usb_setup.length < ao_usb_ep0_in_len)
ao_usb_ep0_in_len = ao_usb_setup.length;
ao_usb_ep0_flush();
+ } else if (ao_usb_ep0_out_len) {
+
+ /* Receiving data from the host
+ */
+ ao_usb_ep0_state = AO_USB_EP0_DATA_OUT;
+ USBCS0 = USBCS0_CLR_OUTPKT_RDY;
+ } else if (ao_usb_setup.length) {
+
+ /* Uh-oh, the host expected to send or receive data
+ * and we don't know what to do.
+ */
+ ao_usb_ep0_state = AO_USB_EP0_STALL;
+ USBCS0 = USBCS0_CLR_OUTPKT_RDY | USBCS0_SEND_STALL;
+ } else {
+
+ /* Simple setup packet with no data
+ */
+ ao_usb_ep0_state = AO_USB_EP0_IDLE;
+ USBCS0 = USBCS0_CLR_OUTPKT_RDY | USBCS0_DATA_END;
}
}
@@ -299,12 +308,12 @@ ao_usb_ep0(void)
USBINDEX = 0;
cs0 = USBCS0;
if (cs0 & USBCS0_SETUP_END) {
- ao_usb_ep0_state = AO_USB_EP0_IDLE;
USBCS0 = USBCS0_CLR_SETUP_END;
+ ao_usb_ep0_state = AO_USB_EP0_IDLE;
}
if (cs0 & USBCS0_SENT_STALL) {
+ USBCS0 = 0;
ao_usb_ep0_state = AO_USB_EP0_IDLE;
- USBCS0 &= ~USBCS0_SENT_STALL;
}
if (ao_usb_ep0_state == AO_USB_EP0_DATA_IN &&
(cs0 & USBCS0_INPKT_RDY) == 0)
@@ -318,12 +327,11 @@ ao_usb_ep0(void)
break;
case AO_USB_EP0_DATA_OUT:
ao_usb_ep0_fill();
- if (ao_usb_ep0_out_len == 0)
- ao_usb_ep0_state = AO_USB_EP0_IDLE;
USBINDEX = 0;
- if (ao_usb_ep0_state == AO_USB_EP0_IDLE)
+ if (ao_usb_ep0_out_len == 0) {
+ ao_usb_ep0_state = AO_USB_EP0_IDLE;
USBCS0 = USBCS0_CLR_OUTPKT_RDY | USBCS0_DATA_END;
- else
+ } else
USBCS0 = USBCS0_CLR_OUTPKT_RDY;
break;
}
diff --git a/src/core/ao_usb.h b/src/core/ao_usb.h
index 4476ee6b..6bc77608 100644
--- a/src/core/ao_usb.h
+++ b/src/core/ao_usb.h
@@ -114,6 +114,7 @@ extern __code __at (0x00aa) uint8_t ao_usb_descriptors [];
#define AO_USB_EP0_IDLE 0
#define AO_USB_EP0_DATA_IN 1
#define AO_USB_EP0_DATA_OUT 2
+#define AO_USB_EP0_STALL 3
#define LE_WORD(x) ((x)&0xFF),((uint8_t) (((uint16_t) (x))>>8))