From c98017cbc9745070b5b19f7e64964c28b2dbdf2a Mon Sep 17 00:00:00 2001 From: Sean Cross Date: Sun, 10 Mar 2019 15:25:33 +0800 Subject: [PATCH] client: working on the client Signed-off-by: Sean Cross --- sw/include/generated/csr.h | 178 ++++++++++++++++++++++++++++--------- sw/src/main.c | 10 ++- sw/src/usb-epfifo.c | 76 ++++++++++++---- 3 files changed, 204 insertions(+), 60 deletions(-) diff --git a/sw/include/generated/csr.h b/sw/include/generated/csr.h index d708825..8db929c 100644 --- a/sw/include/generated/csr.h +++ b/sw/include/generated/csr.h @@ -224,87 +224,183 @@ static inline void uart_phy_tuning_word_write(unsigned int value) { /* usb */ #define CSR_USB_BASE 0xe0004800 -#define CSR_USB_BYTE_COUNT_ADDR 0xe0004800 -#define CSR_USB_BYTE_COUNT_SIZE 1 -static inline unsigned char usb_byte_count_read(void) { +#define CSR_USB_PULLUP_OUT_ADDR 0xe0004800 +#define CSR_USB_PULLUP_OUT_SIZE 1 +static inline unsigned char usb_pullup_out_read(void) { unsigned char r = csr_readl(0xe0004800); return r; } -#define CSR_USB_OBUF_HEAD_ADDR 0xe0004804 -#define CSR_USB_OBUF_HEAD_SIZE 1 -static inline unsigned char usb_obuf_head_read(void) { +static inline void usb_pullup_out_write(unsigned char value) { + csr_writel(value, 0xe0004800); +} +#define CSR_USB_EP_0_OUT_EV_STATUS_ADDR 0xe0004804 +#define CSR_USB_EP_0_OUT_EV_STATUS_SIZE 1 +static inline unsigned char usb_ep_0_out_ev_status_read(void) { unsigned char r = csr_readl(0xe0004804); return r; } -static inline void usb_obuf_head_write(unsigned char value) { +static inline void usb_ep_0_out_ev_status_write(unsigned char value) { csr_writel(value, 0xe0004804); } -#define CSR_USB_OBUF_EMPTY_ADDR 0xe0004808 -#define CSR_USB_OBUF_EMPTY_SIZE 1 -static inline unsigned char usb_obuf_empty_read(void) { +#define CSR_USB_EP_0_OUT_EV_PENDING_ADDR 0xe0004808 +#define CSR_USB_EP_0_OUT_EV_PENDING_SIZE 1 +static inline unsigned char usb_ep_0_out_ev_pending_read(void) { unsigned char r = csr_readl(0xe0004808); return r; } -#define CSR_USB_ARM_ADDR 0xe000480c -#define CSR_USB_ARM_SIZE 1 -static inline unsigned char usb_arm_read(void) { +static inline void usb_ep_0_out_ev_pending_write(unsigned char value) { + csr_writel(value, 0xe0004808); +} +#define CSR_USB_EP_0_OUT_EV_ENABLE_ADDR 0xe000480c +#define CSR_USB_EP_0_OUT_EV_ENABLE_SIZE 1 +static inline unsigned char usb_ep_0_out_ev_enable_read(void) { unsigned char r = csr_readl(0xe000480c); return r; } -static inline void usb_arm_write(unsigned char value) { +static inline void usb_ep_0_out_ev_enable_write(unsigned char value) { csr_writel(value, 0xe000480c); } -#define CSR_USB_IBUF_HEAD_ADDR 0xe0004810 -#define CSR_USB_IBUF_HEAD_SIZE 1 -static inline unsigned char usb_ibuf_head_read(void) { +#define CSR_USB_EP_0_OUT_LAST_TOK_ADDR 0xe0004810 +#define CSR_USB_EP_0_OUT_LAST_TOK_SIZE 1 +static inline unsigned char usb_ep_0_out_last_tok_read(void) { unsigned char r = csr_readl(0xe0004810); return r; } -static inline void usb_ibuf_head_write(unsigned char value) { - csr_writel(value, 0xe0004810); -} -#define CSR_USB_IBUF_EMPTY_ADDR 0xe0004814 -#define CSR_USB_IBUF_EMPTY_SIZE 1 -static inline unsigned char usb_ibuf_empty_read(void) { +#define CSR_USB_EP_0_OUT_RESPOND_ADDR 0xe0004814 +#define CSR_USB_EP_0_OUT_RESPOND_SIZE 1 +static inline unsigned char usb_ep_0_out_respond_read(void) { unsigned char r = csr_readl(0xe0004814); return r; } -#define CSR_USB_PULLUP_OUT_ADDR 0xe0004818 -#define CSR_USB_PULLUP_OUT_SIZE 1 -static inline unsigned char usb_pullup_out_read(void) { +static inline void usb_ep_0_out_respond_write(unsigned char value) { + csr_writel(value, 0xe0004814); +} +#define CSR_USB_EP_0_OUT_DTB_ADDR 0xe0004818 +#define CSR_USB_EP_0_OUT_DTB_SIZE 1 +static inline unsigned char usb_ep_0_out_dtb_read(void) { unsigned char r = csr_readl(0xe0004818); return r; } -static inline void usb_pullup_out_write(unsigned char value) { +static inline void usb_ep_0_out_dtb_write(unsigned char value) { csr_writel(value, 0xe0004818); } -#define CSR_USB_EV_STATUS_ADDR 0xe000481c -#define CSR_USB_EV_STATUS_SIZE 1 -static inline unsigned char usb_ev_status_read(void) { +#define CSR_USB_EP_0_OUT_OBUF_HEAD_ADDR 0xe000481c +#define CSR_USB_EP_0_OUT_OBUF_HEAD_SIZE 1 +static inline unsigned char usb_ep_0_out_obuf_head_read(void) { unsigned char r = csr_readl(0xe000481c); return r; } -static inline void usb_ev_status_write(unsigned char value) { +static inline void usb_ep_0_out_obuf_head_write(unsigned char value) { csr_writel(value, 0xe000481c); } -#define CSR_USB_EV_PENDING_ADDR 0xe0004820 -#define CSR_USB_EV_PENDING_SIZE 1 -static inline unsigned char usb_ev_pending_read(void) { +#define CSR_USB_EP_0_OUT_OBUF_EMPTY_ADDR 0xe0004820 +#define CSR_USB_EP_0_OUT_OBUF_EMPTY_SIZE 1 +static inline unsigned char usb_ep_0_out_obuf_empty_read(void) { unsigned char r = csr_readl(0xe0004820); return r; } -static inline void usb_ev_pending_write(unsigned char value) { - csr_writel(value, 0xe0004820); -} -#define CSR_USB_EV_ENABLE_ADDR 0xe0004824 -#define CSR_USB_EV_ENABLE_SIZE 1 -static inline unsigned char usb_ev_enable_read(void) { +#define CSR_USB_EP_0_IN_EV_STATUS_ADDR 0xe0004824 +#define CSR_USB_EP_0_IN_EV_STATUS_SIZE 1 +static inline unsigned char usb_ep_0_in_ev_status_read(void) { unsigned char r = csr_readl(0xe0004824); return r; } -static inline void usb_ev_enable_write(unsigned char value) { +static inline void usb_ep_0_in_ev_status_write(unsigned char value) { csr_writel(value, 0xe0004824); } +#define CSR_USB_EP_0_IN_EV_PENDING_ADDR 0xe0004828 +#define CSR_USB_EP_0_IN_EV_PENDING_SIZE 1 +static inline unsigned char usb_ep_0_in_ev_pending_read(void) { + unsigned char r = csr_readl(0xe0004828); + return r; +} +static inline void usb_ep_0_in_ev_pending_write(unsigned char value) { + csr_writel(value, 0xe0004828); +} +#define CSR_USB_EP_0_IN_EV_ENABLE_ADDR 0xe000482c +#define CSR_USB_EP_0_IN_EV_ENABLE_SIZE 1 +static inline unsigned char usb_ep_0_in_ev_enable_read(void) { + unsigned char r = csr_readl(0xe000482c); + return r; +} +static inline void usb_ep_0_in_ev_enable_write(unsigned char value) { + csr_writel(value, 0xe000482c); +} +#define CSR_USB_EP_0_IN_LAST_TOK_ADDR 0xe0004830 +#define CSR_USB_EP_0_IN_LAST_TOK_SIZE 1 +static inline unsigned char usb_ep_0_in_last_tok_read(void) { + unsigned char r = csr_readl(0xe0004830); + return r; +} +#define CSR_USB_EP_0_IN_RESPOND_ADDR 0xe0004834 +#define CSR_USB_EP_0_IN_RESPOND_SIZE 1 +static inline unsigned char usb_ep_0_in_respond_read(void) { + unsigned char r = csr_readl(0xe0004834); + return r; +} +static inline void usb_ep_0_in_respond_write(unsigned char value) { + csr_writel(value, 0xe0004834); +} +#define CSR_USB_EP_0_IN_DTB_ADDR 0xe0004838 +#define CSR_USB_EP_0_IN_DTB_SIZE 1 +static inline unsigned char usb_ep_0_in_dtb_read(void) { + unsigned char r = csr_readl(0xe0004838); + return r; +} +static inline void usb_ep_0_in_dtb_write(unsigned char value) { + csr_writel(value, 0xe0004838); +} +#define CSR_USB_EP_0_IN_IBUF_HEAD_ADDR 0xe000483c +#define CSR_USB_EP_0_IN_IBUF_HEAD_SIZE 1 +static inline unsigned char usb_ep_0_in_ibuf_head_read(void) { + unsigned char r = csr_readl(0xe000483c); + return r; +} +static inline void usb_ep_0_in_ibuf_head_write(unsigned char value) { + csr_writel(value, 0xe000483c); +} +#define CSR_USB_EP_0_IN_IBUF_EMPTY_ADDR 0xe0004840 +#define CSR_USB_EP_0_IN_IBUF_EMPTY_SIZE 1 +static inline unsigned char usb_ep_0_in_ibuf_empty_read(void) { + unsigned char r = csr_readl(0xe0004840); + return r; +} +#define CSR_USB_USB_TRANSFER_O_PID_ADDR 0xe0004844 +#define CSR_USB_USB_TRANSFER_O_PID_SIZE 1 +static inline unsigned char usb_usb_transfer_o_pid_read(void) { + unsigned char r = csr_readl(0xe0004844); + return r; +} +#define CSR_USB_USB_TRANSFER_ERROR_STATE_ADDR 0xe0004848 +#define CSR_USB_USB_TRANSFER_ERROR_STATE_SIZE 1 +static inline unsigned char usb_usb_transfer_error_state_read(void) { + unsigned char r = csr_readl(0xe0004848); + return r; +} +#define CSR_USB_USB_TRANSFER_ERROR_PID_ADDR 0xe000484c +#define CSR_USB_USB_TRANSFER_ERROR_PID_SIZE 1 +static inline unsigned char usb_usb_transfer_error_pid_read(void) { + unsigned char r = csr_readl(0xe000484c); + return r; +} +#define CSR_USB_DBG_LWH_ADDR 0xe0004850 +#define CSR_USB_DBG_LWH_SIZE 1 +static inline unsigned char usb_dbg_lwh_read(void) { + unsigned char r = csr_readl(0xe0004850); + return r; +} +#define CSR_USB_DBG_LWD_ADDR 0xe0004854 +#define CSR_USB_DBG_LWD_SIZE 1 +static inline unsigned char usb_dbg_lwd_read(void) { + unsigned char r = csr_readl(0xe0004854); + return r; +} +#define CSR_USB_DBG_LFP_ADDR 0xe0004858 +#define CSR_USB_DBG_LFP_SIZE 1 +static inline unsigned char usb_dbg_lfp_read(void) { + unsigned char r = csr_readl(0xe0004858); + return r; +} /* constants */ #define NMI_INTERRUPT 0 diff --git a/sw/src/main.c b/sw/src/main.c index 86ac993..a5b599b 100644 --- a/sw/src/main.c +++ b/sw/src/main.c @@ -70,7 +70,7 @@ int main(int argc, char **argv) // uart_read(); printf("Enabling USB\n"); usb_connect(); - printf("USB enabled, waiting for packet...\n"); + printf("USB enabled.\n"); // usb_print_status(); int last = 0; static uint8_t bfr[12]; @@ -81,14 +81,16 @@ int main(int argc, char **argv) printf("USB %d IRQ happened\n", last); } usb_poll(); + /* printf("Press any key to send... "); uart_read(); printf("Sending... "); - bfr[0] = ~0; - bfr[1] = 0; + bfr[0] = 0; + bfr[1] = ~0; bfr[2] = 0; - usb_send(NULL, 0, bfr, 3); + usb_send(NULL, 0, bfr, 1); printf("Sent\n"); + */ } return 0; } \ No newline at end of file diff --git a/sw/src/usb-epfifo.c b/sw/src/usb-epfifo.c index 0e05f25..36062a6 100644 --- a/sw/src/usb-epfifo.c +++ b/sw/src/usb-epfifo.c @@ -23,6 +23,7 @@ enum CONTROL_STATE #define NUM_BUFFERS 4 #define BUFFER_SIZE 64 #define EP_INTERVAL_MS 6 +static const char hex[] = "0123456789abcdef"; enum epfifo_response { EPF_ACK = 0, @@ -35,17 +36,18 @@ enum epfifo_response { #define USB_EV_PACKET 2 void usb_connect(void) { - usb_pullup_out_write(1); - - // By default, it wants to respond with NAK. - usb_ep_0_out_respond_write(EPF_ACK); - usb_ep_0_in_respond_write(EPF_ACK); usb_ep_0_out_ev_pending_write(usb_ep_0_out_ev_enable_read()); usb_ep_0_in_ev_pending_write(usb_ep_0_in_ev_pending_read()); usb_ep_0_out_ev_enable_write(USB_EV_PACKET | USB_EV_ERROR); usb_ep_0_in_ev_enable_write(USB_EV_PACKET | USB_EV_ERROR); + // By default, it wants to respond with NAK. + usb_ep_0_out_respond_write(EPF_ACK); + usb_ep_0_in_respond_write(EPF_ACK); + + usb_pullup_out_write(1); + irq_setmask(irq_getmask() | (1 << USB_INTERRUPT)); } @@ -89,8 +91,18 @@ static int queue_more_data(int epnum) { int usb_send(struct usb_device *dev, int epnum, const void *data, int total_count) { (void)dev; // Don't allow requeueing - if (usb_ep_0_in_respond_read() != EPF_NAK) + // if (usb_ep_0_in_respond_read() != EPF_NAK) + // return -1; + if (!usb_ep_0_in_ibuf_empty_read()) { + printf("IBUF isn't empty. Error? %d\n", usb_usb_transfer_error_state_read()); return -1; + } +/* + while (!usb_ep_0_in_ibuf_empty_read()) { + printf("Emptying out ibuf...\n"); + usb_ep_0_in_ibuf_head_read(); + } + */ current_data = (uint8_t *)data; current_length = total_count; current_offset = 0; @@ -100,10 +112,21 @@ int usb_send(struct usb_device *dev, int epnum, const void *data, int total_coun } void usb_isr(void) { - irq_count++; - +#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++; + uint8_t ep0o_pending = usb_ep_0_out_ev_pending_read(); + uint8_t ep0i_pending = usb_ep_0_in_ev_pending_read(); + printf(">> %02x %02x <<\n", ep0o_pending, ep0i_pending); // We got an OUT or a SETUP packet. Copy it to usb_ep0out_buffer // and clear the "pending" bit. @@ -118,7 +141,16 @@ void usb_isr(void) { usb_ep_0_out_ev_pending_write(ep0o_pending); if (byte_count) { - printf("read %d bytes\n", byte_count); + printf("read %d bytes: [", byte_count); + unsigned int i; + for (i = 0; i < byte_count; i++) { + uart_write(' '); + uart_write(hex[(obuf[i] >> 4) & 0xf]); + uart_write(hex[obuf[i] & (0xf)]); + } + uart_write(' ]'); + uart_write('\r'); + uart_write('\n'); usb_ep0out_buffer_len[usb_ep0out_wr_ptr] = byte_count; usb_ep0out_wr_ptr = (usb_ep0out_wr_ptr + 1) & (EP0OUT_BUFFERS-1); } @@ -144,9 +176,10 @@ void usb_isr(void) { usb_ep_0_out_respond_write(EPF_ACK); } } + else + usb_ep_0_in_respond_write(EPF_NAK); } - - printf(">> %02x %02x <<\n", ep0o_pending, ep0i_pending); +#endif return; } @@ -165,6 +198,7 @@ int usb_ack(struct usb_device *dev, int epnum) { } int usb_err(struct usb_device *dev, int epnum) { + printf("STALLING!!!\n"); usb_ep_0_out_respond_write(EPF_STALL); usb_ep_0_in_respond_write(EPF_STALL); } @@ -173,9 +207,14 @@ int usb_recv(struct usb_device *dev, void *buffer, unsigned int buffer_len) { return; } -static const char hex[] = "0123456789abcdef"; void usb_poll(void) { + static int last_error_count; + int this_error_count = usb_usb_transfer_error_state_read(); + if (last_error_count != this_error_count) { + printf("USB TRANSFER ERROR STATE # %d!! WaitHand? %d WaitData? %d PID: %02x (was: %02x, full: %02x)\n", this_error_count, usb_dbg_lwh_read(), usb_dbg_lwd_read(), usb_usb_transfer_o_pid_read(), usb_usb_transfer_error_pid_read(), usb_dbg_lfp_read()); + last_error_count = this_error_count; + } // If some data was received, then process it. if (usb_ep0out_rd_ptr != usb_ep0out_wr_ptr) { const struct usb_setup_request *request = (const struct usb_setup_request *)(usb_ep0out_buffer[usb_ep0out_rd_ptr]); @@ -184,6 +223,10 @@ void usb_poll(void) { usb_ep0out_buffer_len[usb_ep0out_rd_ptr] = 0; usb_ep0out_rd_ptr = (usb_ep0out_rd_ptr + 1) & (EP0OUT_BUFFERS-1); } + + if ((usb_ep_0_in_respond_read() == EPF_NAK) && (current_data)) + queue_more_data(0); + // Cancel any pending transfers if ((control_state == IN_DATA) && usb_ep_0_in_ibuf_empty_read()) { printf("state is IN_DATA but ibuf is empty?\n"); @@ -192,9 +235,12 @@ void usb_poll(void) { usb_ep_0_out_obuf_head_write(0); control_state = WAIT_SETUP; } - if (!usb_ep_0_out_obuf_empty_read()) { - printf("obuf not empty\n"); - } + // if (!usb_ep_0_out_obuf_empty_read()) { + // printf("FATAL: obuf not empty, and pending is %d\n", usb_ep_0_out_ev_pending_read()); + // printf("HALT"); + // while (1) + // ; + // } // if (!usb_ep_0_in_ibuf_empty_read()) { // usb_ep_0_in_ibuf_head_write(0); // }