sw: usb-epfifo: fixups to remove errors in enumeration

With these fixups, we can now enumerate successfully.

The code is a mess, but this is the first functionally-correct build.

Signed-off-by: Sean Cross <sean@xobs.io>
This commit is contained in:
Sean Cross 2019-03-11 11:51:19 +08:00
parent 9909b3bbdb
commit ff4774ebc3

View File

@ -1,4 +1,3 @@
#include <grainuum.h>
#include <usb.h> #include <usb.h>
#include <irq.h> #include <irq.h>
#include <generated/csr.h> #include <generated/csr.h>
@ -12,6 +11,7 @@
enum CONTROL_STATE enum CONTROL_STATE
{ {
WAIT_SETUP, WAIT_SETUP,
IN_SETUP,
IN_DATA, IN_DATA,
OUT_DATA, OUT_DATA,
LAST_IN_DATA, LAST_IN_DATA,
@ -20,6 +20,11 @@ enum CONTROL_STATE
STALLED, STALLED,
} control_state; } control_state;
// Note that our PIDs only have the lower nybble.
enum USB_PID {
USB_PID_SETUP = 3,
};
#define NUM_BUFFERS 4 #define NUM_BUFFERS 4
#define BUFFER_SIZE 64 #define BUFFER_SIZE 64
#define EP_INTERVAL_MS 6 #define EP_INTERVAL_MS 6
@ -129,17 +134,6 @@ int usb_send(struct usb_device *dev, int epnum, const void *data, int total_coun
} }
void usb_isr(void) { void usb_isr(void) {
#if 0
uint8_t ep0o_pending = usb_ep_0_out_ev_pending_read();
uint8_t ep0i_pending = usb_ep_0_in_ev_pending_read();
while (!usb_ep_0_out_obuf_empty_read()) {
usb_ep_0_out_obuf_head_write(0);
}
usb_ep_0_out_respond_write(EPF_ACK);
usb_ep_0_in_respond_write(EPF_ACK);
usb_ep_0_out_ev_pending_write(ep0o_pending);
usb_ep_0_in_ev_pending_write(ep0i_pending);
#else
irq_count++; irq_count++;
uint8_t ep0o_pending = usb_ep_0_out_ev_pending_read(); uint8_t ep0o_pending = usb_ep_0_out_ev_pending_read();
uint8_t ep0i_pending = usb_ep_0_in_ev_pending_read(); uint8_t ep0i_pending = usb_ep_0_in_ev_pending_read();
@ -161,10 +155,11 @@ void usb_isr(void) {
usb_ep0out_buffer_len[usb_ep0out_wr_ptr] = byte_count; usb_ep0out_buffer_len[usb_ep0out_wr_ptr] = byte_count;
usb_ep0out_wr_ptr = (usb_ep0out_wr_ptr + 1) & (EP0OUT_BUFFERS-1); usb_ep0out_wr_ptr = (usb_ep0out_wr_ptr + 1) & (EP0OUT_BUFFERS-1);
if (last_tok == 3 /*USB_PID_SETUP*/) { if (last_tok == USB_PID_SETUP) {
current_offset = 0; current_offset = 0;
current_length = 0; current_length = 0;
current_data = NULL; current_data = NULL;
control_state = IN_SETUP;
} }
} }
@ -174,21 +169,21 @@ void usb_isr(void) {
current_offset += current_to_send; current_offset += current_to_send;
queue_more_data(0); queue_more_data(0);
usb_ep_0_in_ev_pending_write(ep0i_pending); usb_ep_0_in_ev_pending_write(ep0i_pending);
usb_ep_0_out_respond_write(EPF_ACK);
// Get ready to respond with an empty data byte // // Get ready to respond with an empty data byte
if (current_offset >= current_length) { // if (current_offset >= current_length) {
current_offset = 0; // current_offset = 0;
current_length = 0; // current_length = 0;
current_data = NULL; // current_data = NULL;
if (control_state == IN_DATA) { // if (control_state == IN_DATA) {
usb_ep_0_out_respond_write(EPF_ACK); // usb_ep_0_out_respond_write(EPF_ACK);
} // }
usb_ep_0_out_respond_write(EPF_ACK); // usb_ep_0_out_respond_write(EPF_ACK);
} // }
else // else
usb_ep_0_in_respond_write(EPF_NAK); usb_ep_0_in_respond_write(EPF_NAK);
} }
#endif
return; return;
} }
@ -202,11 +197,15 @@ int usb_irq_happened(void) {
} }
int usb_ack(struct usb_device *dev, int epnum) { int usb_ack(struct usb_device *dev, int epnum) {
(void)dev;
(void)epnum;
usb_ep_0_out_respond_write(EPF_ACK); usb_ep_0_out_respond_write(EPF_ACK);
usb_ep_0_in_respond_write(EPF_ACK); usb_ep_0_in_respond_write(EPF_ACK);
} }
int usb_err(struct usb_device *dev, int epnum) { int usb_err(struct usb_device *dev, int epnum) {
(void)dev;
(void)epnum;
printf("STALLING!!!\n"); printf("STALLING!!!\n");
usb_ep_0_out_respond_write(EPF_STALL); usb_ep_0_out_respond_write(EPF_STALL);
usb_ep_0_in_respond_write(EPF_STALL); usb_ep_0_in_respond_write(EPF_STALL);
@ -229,7 +228,9 @@ void usb_poll(void) {
const struct usb_setup_request *request = (const struct usb_setup_request *)(usb_ep0out_buffer[usb_ep0out_rd_ptr]); const struct usb_setup_request *request = (const struct usb_setup_request *)(usb_ep0out_buffer[usb_ep0out_rd_ptr]);
const uint8_t *obuf = (const struct usb_setup_request *)(usb_ep0out_buffer[usb_ep0out_rd_ptr]); const uint8_t *obuf = (const struct usb_setup_request *)(usb_ep0out_buffer[usb_ep0out_rd_ptr]);
if (usb_ep0out_last_tok[usb_ep0out_rd_ptr] == 3) { if (usb_ep0out_last_tok[usb_ep0out_rd_ptr] == USB_PID_SETUP) {
// usb_ep_0_out_dtb_write(1);
// usb_ep_0_in_dtb_write(1);
usb_setup(NULL, request); usb_setup(NULL, request);
} }