usb: work-in-progress for USB development
Signed-off-by: Sean Cross <sean@xobs.io>
This commit is contained in:
		
							
								
								
									
										71
									
								
								src/main.c
									
									
									
									
									
								
							
							
						
						
									
										71
									
								
								src/main.c
									
									
									
									
									
								
							@@ -23,7 +23,12 @@ void isr(void)
 | 
				
			|||||||
static void rv_putchar(void *ignored, char c)
 | 
					static void rv_putchar(void *ignored, char c)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    (void)ignored;
 | 
					    (void)ignored;
 | 
				
			||||||
 | 
					    if (c == '\n')
 | 
				
			||||||
 | 
					        uart_write('\r');
 | 
				
			||||||
 | 
					    if (c == '\r')
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
    uart_write(c);
 | 
					    uart_write(c);
 | 
				
			||||||
 | 
					    // uart_sync();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void init(void)
 | 
					static void init(void)
 | 
				
			||||||
@@ -36,37 +41,21 @@ static void init(void)
 | 
				
			|||||||
    time_init();
 | 
					    time_init();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const char *usb_hw_api(void) {
 | 
				
			||||||
#ifdef CSR_USB_EP_0_OUT_EV_PENDING_ADDR
 | 
					#ifdef CSR_USB_EP_0_OUT_EV_PENDING_ADDR
 | 
				
			||||||
 | 
					    return "epfifo";
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
static void get_print_status(void)
 | 
					#ifdef CSR_USB_OBUF_EMPTY_ADDR
 | 
				
			||||||
{
 | 
					    return "rawfifo";
 | 
				
			||||||
    static int loops;
 | 
					#else
 | 
				
			||||||
    uint32_t obe = usb_obuf_empty_read();
 | 
					#ifdef CSR_USB_WHATEVER
 | 
				
			||||||
    uint8_t obufbuf[128];
 | 
					    return "whatever";
 | 
				
			||||||
    int obufbuf_cnt = 0;
 | 
					#else
 | 
				
			||||||
    loops++;
 | 
					    return "unrecognized hw api";
 | 
				
			||||||
 | 
					#endif /* CSR_USB_WHATEVER */
 | 
				
			||||||
    while (!usb_obuf_empty_read()) {
 | 
					#endif /* CSR_USB_OBUF_EMPTY_ADDR */
 | 
				
			||||||
        uint32_t obh = usb_obuf_head_read();
 | 
					#endif /* CSR_USB_EP_0_OUT_EV_PENDING_ADDR */
 | 
				
			||||||
        obufbuf[obufbuf_cnt++] = obh;
 | 
					 | 
				
			||||||
        usb_obuf_head_write(1);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    if (obufbuf_cnt) {
 | 
					 | 
				
			||||||
        int i;
 | 
					 | 
				
			||||||
        printf("i: %d  b: %d  --", loops, obufbuf_cnt);//obe: %d  obh: %02x\n", i, obe, obh);
 | 
					 | 
				
			||||||
        for (i = 0; i < obufbuf_cnt; i++) {
 | 
					 | 
				
			||||||
            printf(" %02x", obufbuf[i]);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        printf("\n");
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    // if (!obe) {
 | 
					 | 
				
			||||||
    //     uint32_t obh = usb_obuf_head_read();
 | 
					 | 
				
			||||||
    //     usb_obuf_head_write(1);
 | 
					 | 
				
			||||||
    //     if (i < 300)
 | 
					 | 
				
			||||||
    //         printf("i: %8d  obe: %d  obh: %02x\n", i, obe, obh);
 | 
					 | 
				
			||||||
    // }
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
int main(int argc, char **argv)
 | 
					int main(int argc, char **argv)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@@ -74,20 +63,26 @@ int main(int argc, char **argv)
 | 
				
			|||||||
    (void)argv;
 | 
					    (void)argv;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    init();
 | 
					    init();
 | 
				
			||||||
    usb_pullup_out_write(1);
 | 
					 | 
				
			||||||
    usb_ep_0_out_ev_pending_write((1 << 1));
 | 
					 | 
				
			||||||
    if (usb_ep_0_out_ev_pending_read() & (1 << 1))
 | 
					 | 
				
			||||||
        usb_isr();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    printf("Hello, world!\n");
 | 
					    printf("\n\nUSB API: %s\n", usb_hw_api());
 | 
				
			||||||
 | 
					    // printf("Press any key to enable USB...\n");
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
 | 
					    usb_print_status();
 | 
				
			||||||
 | 
					    // uart_read();
 | 
				
			||||||
 | 
					    printf("Enabling USB\n");
 | 
				
			||||||
 | 
					    usb_connect();
 | 
				
			||||||
 | 
					    printf("USB enabled, waiting for packet...\n");
 | 
				
			||||||
 | 
					    // usb_wait();
 | 
				
			||||||
 | 
					    usb_print_status();
 | 
				
			||||||
 | 
					    int last = 0;
 | 
				
			||||||
    while (1)
 | 
					    while (1)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        if (usb_ep_0_out_ev_pending_read() & (1 << 1))
 | 
					        if (usb_irq_happened() != last) {
 | 
				
			||||||
            usb_isr();
 | 
					            last = usb_irq_happened();
 | 
				
			||||||
        // elapsed(&last_event, 1000);
 | 
					            printf("USB %d IRQ happened\n", last);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        // get_print_status();
 | 
					        // printf("x");
 | 
				
			||||||
 | 
					        usb_print_status();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -1,30 +1,19 @@
 | 
				
			|||||||
#include <grainuum.h>
 | 
					#include <grainuum.h>
 | 
				
			||||||
#include <usb.h>
 | 
					#include <usb.h>
 | 
				
			||||||
 | 
					#include <irq.h>
 | 
				
			||||||
#include <generated/csr.h>
 | 
					#include <generated/csr.h>
 | 
				
			||||||
#include <string.h>
 | 
					#include <string.h>
 | 
				
			||||||
#include <printf.h>
 | 
					#include <printf.h>
 | 
				
			||||||
 | 
					#include <uart.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef CSR_USB_EP_0_OUT_EV_PENDING_ADDR
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#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
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct GrainuumUSB usb;
 | 
					//static struct GrainuumUSB usb;
 | 
				
			||||||
static uint8_t usb_buf[67];
 | 
					//static uint8_t usb_buf[67];
 | 
				
			||||||
 | 
					 | 
				
			||||||
static uint32_t rx_buffer[NUM_BUFFERS][BUFFER_SIZE / sizeof(uint32_t)];
 | 
					 | 
				
			||||||
static uint8_t rx_buffer_head;
 | 
					 | 
				
			||||||
static uint8_t rx_buffer_tail;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static uint32_t rx_buffer_queries = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void set_usb_config_num(struct GrainuumUSB *usb, int configNum)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  (void)usb;
 | 
					 | 
				
			||||||
  (void)configNum;
 | 
					 | 
				
			||||||
  ;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static const uint8_t hid_report_descriptor[] = {
 | 
					static const uint8_t hid_report_descriptor[] = {
 | 
				
			||||||
    0x06, 0x00, 0xFF, // (GLOBAL) USAGE_PAGE         0xFF00 Vendor-defined
 | 
					    0x06, 0x00, 0xFF, // (GLOBAL) USAGE_PAGE         0xFF00 Vendor-defined
 | 
				
			||||||
    0x09, 0x00,       // (LOCAL)  USAGE              0xFF000000
 | 
					    0x09, 0x00,       // (LOCAL)  USAGE              0xFF000000
 | 
				
			||||||
@@ -114,6 +103,255 @@ static const struct usb_configuration_descriptor configuration_descriptor = {
 | 
				
			|||||||
    },
 | 
					    },
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum epfifo_response {
 | 
				
			||||||
 | 
					    EPF_ACK = 0,
 | 
				
			||||||
 | 
					    EPF_NAK = 1,
 | 
				
			||||||
 | 
					    EPF_NONE = 2,
 | 
				
			||||||
 | 
					    EPF_STALL = 3,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define USB_EV_ERROR 1
 | 
				
			||||||
 | 
					#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_NAK);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						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);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						irq_setmask(irq_getmask() | (1 << USB_INTERRUPT));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void usb_init(void) {
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					volatile int irq_count = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define EP0OUT_BUFFERS 64
 | 
				
			||||||
 | 
					static uint8_t usb_ep0out_buffer[EP0OUT_BUFFERS][128];
 | 
				
			||||||
 | 
					uint8_t usb_ep0out_wr_ptr;
 | 
				
			||||||
 | 
					uint8_t usb_ep0out_rd_ptr;
 | 
				
			||||||
 | 
					int descriptor_ptr;
 | 
				
			||||||
 | 
					int max_byte_length = 8;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const uint8_t *current_data;
 | 
				
			||||||
 | 
					static int current_length;
 | 
				
			||||||
 | 
					static int current_offset;
 | 
				
			||||||
 | 
					static int current_to_send;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int maybe_send_more_data(int epnum) {
 | 
				
			||||||
 | 
					    (void)epnum;
 | 
				
			||||||
 | 
					    // Don't allow requeueing
 | 
				
			||||||
 | 
					    if (usb_ep_0_in_respond_read() != EPF_NAK)
 | 
				
			||||||
 | 
					        return -1;
 | 
				
			||||||
 | 
					    // if (!usb_ep_0_in_ibuf_empty_read())
 | 
				
			||||||
 | 
					        // return -2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    int this_offset;
 | 
				
			||||||
 | 
					    current_to_send = current_length - current_offset;
 | 
				
			||||||
 | 
					    if (current_to_send > max_byte_length)
 | 
				
			||||||
 | 
					        current_to_send = max_byte_length;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (this_offset = current_offset; this_offset < current_offset + current_to_send; this_offset++) {
 | 
				
			||||||
 | 
					        usb_ep_0_in_ibuf_head_write(current_data[this_offset]);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    usb_ep_0_in_respond_write(EPF_ACK);
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int send_data(int epnum, const void *data, int total_count) {
 | 
				
			||||||
 | 
					    // Don't allow requeueing
 | 
				
			||||||
 | 
					    if (usb_ep_0_in_respond_read() != EPF_NAK)
 | 
				
			||||||
 | 
					        return -1;
 | 
				
			||||||
 | 
					    current_data = (uint8_t *)data;
 | 
				
			||||||
 | 
					    current_length = total_count;
 | 
				
			||||||
 | 
					    current_offset = 0;
 | 
				
			||||||
 | 
					    maybe_send_more_data(epnum);
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void usb_isr(void) {
 | 
				
			||||||
 | 
					    irq_count++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    uint8_t ep0o_pending = usb_ep_0_out_ev_pending_read();
 | 
				
			||||||
 | 
					    uint8_t ep0i_pending = usb_ep_0_in_ev_pending_read();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (ep0o_pending) {
 | 
				
			||||||
 | 
					        int byte_count = 0;
 | 
				
			||||||
 | 
					        uint8_t *obuf = usb_ep0out_buffer[usb_ep0out_wr_ptr];
 | 
				
			||||||
 | 
					        while (1) {
 | 
				
			||||||
 | 
					            if (usb_ep_0_out_obuf_empty_read())
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            obuf[++byte_count] = usb_ep_0_out_obuf_head_read();
 | 
				
			||||||
 | 
					            usb_ep_0_out_obuf_head_write(0);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        usb_ep_0_out_ev_pending_write(ep0o_pending);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (byte_count) {
 | 
				
			||||||
 | 
					            obuf[0] = byte_count;
 | 
				
			||||||
 | 
					            usb_ep0out_wr_ptr = (usb_ep0out_wr_ptr + 1) & (EP0OUT_BUFFERS-1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // usb_ep_0_in_dtb_write(1);
 | 
				
			||||||
 | 
					            send_data(0, &device_descriptor, sizeof(device_descriptor));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        else {
 | 
				
			||||||
 | 
					            usb_ep_0_out_respond_write(EPF_ACK);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (ep0i_pending) {
 | 
				
			||||||
 | 
					        /*
 | 
				
			||||||
 | 
					        uint8_t *descriptor = (uint8_t *)&device_descriptor;
 | 
				
			||||||
 | 
					        if (descriptor_ptr < 0) {
 | 
				
			||||||
 | 
					            usb_ep_0_in_respond_write(EPF_NAK);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        else if (descriptor_ptr >= sizeof(device_descriptor)) {
 | 
				
			||||||
 | 
					            descriptor_ptr = -1;
 | 
				
			||||||
 | 
					            usb_ep_0_in_respond_write(EPF_ACK);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        else {
 | 
				
			||||||
 | 
					            usb_ep_0_in_respond_write(EPF_NAK);
 | 
				
			||||||
 | 
					            for (descriptor_ptr; descriptor_ptr < sizeof(device_descriptor); descriptor_ptr++) {
 | 
				
			||||||
 | 
					                usb_ep_0_in_ibuf_head_write(descriptor[descriptor_ptr]);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            usb_ep_0_in_respond_write(EPF_ACK);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        */
 | 
				
			||||||
 | 
					        usb_ep_0_in_respond_write(EPF_NAK);
 | 
				
			||||||
 | 
					        current_offset += current_to_send;
 | 
				
			||||||
 | 
					        maybe_send_more_data(0);
 | 
				
			||||||
 | 
					        usb_ep_0_in_ev_pending_write(ep0i_pending);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void usb_wait(void) {
 | 
				
			||||||
 | 
					    while (!irq_count)
 | 
				
			||||||
 | 
					        ;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int usb_irq_happened(void) {
 | 
				
			||||||
 | 
					  return irq_count;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const char hex[] = "0123456789abcdef";
 | 
				
			||||||
 | 
					void usb_print_status(void) {
 | 
				
			||||||
 | 
					    /*
 | 
				
			||||||
 | 
					    printf("EP0_OUT  Status:     %02x\n", usb_ep_0_out_ev_status_read());
 | 
				
			||||||
 | 
					    printf("EP0_OUT  Pending:    %02x\n", usb_ep_0_out_ev_pending_read());
 | 
				
			||||||
 | 
					    printf("EP0_OUT  Enable:     %02x\n", usb_ep_0_out_ev_enable_read());
 | 
				
			||||||
 | 
					    printf("EP0_OUT  Last Tok:   %02x\n", usb_ep_0_out_last_tok_read());
 | 
				
			||||||
 | 
					    printf("EP0_OUT  Respond:    %02x\n", usb_ep_0_out_respond_read());
 | 
				
			||||||
 | 
					    printf("EP0_OUT  DTB:        %02x\n", usb_ep_0_out_dtb_read());
 | 
				
			||||||
 | 
					    printf("EP0_OUT  OBUF Head:  %02x\n", usb_ep_0_out_obuf_head_read());
 | 
				
			||||||
 | 
					    printf("EP0_OUT  OBUF Empty: %02x\n", usb_ep_0_out_obuf_empty_read());
 | 
				
			||||||
 | 
					    printf("EP0_IN   Status:     %02x\n", usb_ep_0_in_ev_status_read());
 | 
				
			||||||
 | 
					    printf("EP0_IN   Pending:    %02x\n", usb_ep_0_in_ev_pending_read());
 | 
				
			||||||
 | 
					    printf("EP0_IN   Enable:     %02x\n", usb_ep_0_in_ev_enable_read());
 | 
				
			||||||
 | 
					    printf("EP0_IN   Last Tok:   %02x\n", usb_ep_0_in_last_tok_read());
 | 
				
			||||||
 | 
					    printf("EP0_IN   Respond:    %02x\n", usb_ep_0_in_respond_read());
 | 
				
			||||||
 | 
					    printf("EP0_IN   DTB:        %02x\n", usb_ep_0_in_dtb_read());
 | 
				
			||||||
 | 
					    printf("EP0_IN   IBUF Head:  %02x\n", usb_ep_0_in_ibuf_head_read());
 | 
				
			||||||
 | 
					    printf("EP0_IN   IBUF Empty: %02x\n", usb_ep_0_in_ibuf_empty_read());
 | 
				
			||||||
 | 
					    */
 | 
				
			||||||
 | 
					    while (usb_ep0out_rd_ptr != usb_ep0out_wr_ptr) {
 | 
				
			||||||
 | 
					        // printf("for (this_offset = current_offset; this_offset < this_offset + current_to_send; this_offset++) {\n");
 | 
				
			||||||
 | 
					        // printf("for (this_offset = %d; this_offset < %d; %d++) {\n", current_offset, this_offset, this_offset + current_to_send, this_offset);
 | 
				
			||||||
 | 
					        printf("current_data: 0x%08x\n", current_data);
 | 
				
			||||||
 | 
					        printf("current_length: %d\n", current_length);
 | 
				
			||||||
 | 
					        printf("current_offset: %d\n", current_offset);
 | 
				
			||||||
 | 
					        printf("current_to_send: %d\n", current_to_send);
 | 
				
			||||||
 | 
					        uint8_t *obuf = usb_ep0out_buffer[usb_ep0out_rd_ptr];
 | 
				
			||||||
 | 
					        uint8_t cnt = obuf[0];
 | 
				
			||||||
 | 
					        unsigned int i;
 | 
				
			||||||
 | 
					        if (cnt) {
 | 
				
			||||||
 | 
					            for (i = 0; i < cnt; i++) {
 | 
				
			||||||
 | 
					                uart_write(' ');
 | 
				
			||||||
 | 
					                uart_write(hex[(obuf[i+1] >> 4) & 0xf]);
 | 
				
			||||||
 | 
					                uart_write(hex[obuf[i+1] & (0xf)]);
 | 
				
			||||||
 | 
					                // printf(" %02x", obufbuf[i]);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            uart_write('\r');
 | 
				
			||||||
 | 
					            uart_write('\n');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        // printf("\n");
 | 
				
			||||||
 | 
					        usb_ep0out_rd_ptr = (usb_ep0out_rd_ptr + 1) & (EP0OUT_BUFFERS-1);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// static inline unsigned char usb_pullup_out_read(void);
 | 
				
			||||||
 | 
					// static inline void usb_pullup_out_write(unsigned char value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// static inline unsigned char usb_ep_0_out_ev_status_read(void);
 | 
				
			||||||
 | 
					// static inline void usb_ep_0_out_ev_status_write(unsigned char value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// static inline unsigned char usb_ep_0_out_ev_pending_read(void);
 | 
				
			||||||
 | 
					// static inline void usb_ep_0_out_ev_pending_write(unsigned char value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// static inline unsigned char usb_ep_0_out_ev_enable_read(void);
 | 
				
			||||||
 | 
					// static inline void usb_ep_0_out_ev_enable_write(unsigned char value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// static inline unsigned char usb_ep_0_out_last_tok_read(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// static inline unsigned char usb_ep_0_out_respond_read(void);
 | 
				
			||||||
 | 
					// static inline void usb_ep_0_out_respond_write(unsigned char value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// static inline unsigned char usb_ep_0_out_dtb_read(void);
 | 
				
			||||||
 | 
					// static inline void usb_ep_0_out_dtb_write(unsigned char value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// static inline unsigned char usb_ep_0_out_obuf_head_read(void);
 | 
				
			||||||
 | 
					// static inline void usb_ep_0_out_obuf_head_write(unsigned char value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// static inline unsigned char usb_ep_0_out_obuf_empty_read(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// static inline unsigned char usb_ep_0_in_ev_status_read(void);
 | 
				
			||||||
 | 
					// static inline void usb_ep_0_in_ev_status_write(unsigned char value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// static inline unsigned char usb_ep_0_in_ev_pending_read(void);
 | 
				
			||||||
 | 
					// static inline void usb_ep_0_in_ev_pending_write(unsigned char value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// static inline unsigned char usb_ep_0_in_ev_enable_read(void);
 | 
				
			||||||
 | 
					// static inline void usb_ep_0_in_ev_enable_write(unsigned char value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// static inline unsigned char usb_ep_0_in_last_tok_read(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// static inline unsigned char usb_ep_0_in_respond_read(void);
 | 
				
			||||||
 | 
					// static inline void usb_ep_0_in_respond_write(unsigned char value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// static inline unsigned char usb_ep_0_in_dtb_read(void);
 | 
				
			||||||
 | 
					// static inline void usb_ep_0_in_dtb_write(unsigned char value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// static inline unsigned char usb_ep_0_in_ibuf_head_read(void);
 | 
				
			||||||
 | 
					// static inline void usb_ep_0_in_ibuf_head_write(unsigned char value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// static inline unsigned char usb_ep_0_in_ibuf_empty_read(void);
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if 0
 | 
				
			||||||
 | 
					static uint32_t rx_buffer[NUM_BUFFERS][BUFFER_SIZE / sizeof(uint32_t)];
 | 
				
			||||||
 | 
					static uint8_t rx_buffer_head;
 | 
				
			||||||
 | 
					static uint8_t rx_buffer_tail;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static uint32_t rx_buffer_queries = 0;
 | 
				
			||||||
 | 
					static void set_usb_config_num(struct GrainuumUSB *usb, int configNum)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  (void)usb;
 | 
				
			||||||
 | 
					  (void)configNum;
 | 
				
			||||||
 | 
					  ;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define USB_STR_BUF_LEN 64
 | 
					#define USB_STR_BUF_LEN 64
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static uint32_t str_buf_storage[USB_STR_BUF_LEN / sizeof(uint32_t)];
 | 
					static uint32_t str_buf_storage[USB_STR_BUF_LEN / sizeof(uint32_t)];
 | 
				
			||||||
@@ -307,30 +545,32 @@ static struct GrainuumConfig cfg = {
 | 
				
			|||||||
    .setConfigNum = set_usb_config_num,
 | 
					    .setConfigNum = set_usb_config_num,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void usb_isr(void) {
 | 
					// void usb_isr(void) {
 | 
				
			||||||
    grainuumCaptureI(&usb, usb_buf);
 | 
					//     // grainuumCaptureI(&usb, usb_buf);
 | 
				
			||||||
    return;
 | 
					//     return;
 | 
				
			||||||
}
 | 
					// }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void usb_init(void) {
 | 
					// void usb_init(void) {
 | 
				
			||||||
    grainuumInit(&usb, &cfg);
 | 
					//     // grainuumInit(&usb, &cfg);
 | 
				
			||||||
    grainuumConnect(&usb);
 | 
					//     // grainuumConnect(&usb);
 | 
				
			||||||
    return;
 | 
					//     return;
 | 
				
			||||||
}
 | 
					// }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void usbPhyWriteI(const struct GrainuumUSB *usb, const void *buffer, uint32_t size) {
 | 
					void usbPhyWriteI(const struct GrainuumUSB *usb, const void *buffer, uint32_t size) {
 | 
				
			||||||
    (void)usb;
 | 
					    // (void)usb;
 | 
				
			||||||
    const uint8_t *ubuffer = (const uint8_t *)buffer;
 | 
					    // const uint8_t *ubuffer = (const uint8_t *)buffer;
 | 
				
			||||||
    uint32_t i = 0;
 | 
					    // uint32_t i = 0;
 | 
				
			||||||
    while (i < size)
 | 
					    // while (i < size)
 | 
				
			||||||
        usb_obuf_head_write(ubuffer[i]);
 | 
					    //     usb_obuf_head_write(ubuffer[i]);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int usbPhyReadI(const struct GrainuumUSB *usb, uint8_t *samples) {
 | 
					int usbPhyReadI(const struct GrainuumUSB *usb, uint8_t *samples) {
 | 
				
			||||||
    (void)usb;
 | 
					    (void)usb;
 | 
				
			||||||
    int count = 0;
 | 
					    int count = 0;
 | 
				
			||||||
    while (!usb_ibuf_empty_read()) {
 | 
					    // while (!usb_ibuf_empty_read()) {
 | 
				
			||||||
        samples[count++] = usb_ibuf_head_read();
 | 
					        // samples[count++] = usb_ibuf_head_read();
 | 
				
			||||||
    }
 | 
					    // }
 | 
				
			||||||
    return count;
 | 
					    return count;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					#endif /* CSR_USB_EP_0_OUT_EV_PENDING_ADDR */
 | 
				
			||||||
							
								
								
									
										116
									
								
								src/usb-rawfifo.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										116
									
								
								src/usb-rawfifo.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,116 @@
 | 
				
			|||||||
 | 
					#include <usb.h>
 | 
				
			||||||
 | 
					#include <irq.h>
 | 
				
			||||||
 | 
					#include <generated/csr.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					#include <printf.h>
 | 
				
			||||||
 | 
					#include <uart.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef CSR_USB_OBUF_EMPTY_ADDR
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline unsigned char usb_obuf_head_read(void);
 | 
				
			||||||
 | 
					static inline void usb_obuf_head_write(unsigned char value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline unsigned char usb_obuf_empty_read(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline unsigned char usb_arm_read(void);
 | 
				
			||||||
 | 
					static inline void usb_arm_write(unsigned char value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline unsigned char usb_ibuf_head_read(void);
 | 
				
			||||||
 | 
					static inline void usb_ibuf_head_write(unsigned char value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline unsigned char usb_ibuf_empty_read(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline unsigned char usb_pullup_out_read(void);
 | 
				
			||||||
 | 
					static inline void usb_pullup_out_write(unsigned char value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline unsigned char usb_ev_status_read(void);
 | 
				
			||||||
 | 
					static inline void usb_ev_status_write(unsigned char value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline unsigned char usb_ev_pending_read(void);
 | 
				
			||||||
 | 
					static inline void usb_ev_pending_write(unsigned char value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline unsigned char usb_ev_enable_read(void);
 | 
				
			||||||
 | 
					static inline void usb_ev_enable_write(unsigned char value);
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					static const char hex[] = "0123456789abcdef";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint8_t usb_ep0out_wr_ptr;
 | 
				
			||||||
 | 
					uint8_t usb_ep0out_rd_ptr;
 | 
				
			||||||
 | 
					#define EP0OUT_BUFFERS 64
 | 
				
			||||||
 | 
					static uint8_t usb_ep0out_buffer[EP0OUT_BUFFERS][128];
 | 
				
			||||||
 | 
					void usb_print_status(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    static int loops;
 | 
				
			||||||
 | 
					    loops++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    while (usb_ep0out_rd_ptr != usb_ep0out_wr_ptr) {
 | 
				
			||||||
 | 
					        uint8_t *obuf = usb_ep0out_buffer[usb_ep0out_rd_ptr];
 | 
				
			||||||
 | 
					        uint8_t cnt = obuf[0];
 | 
				
			||||||
 | 
					        unsigned int i;
 | 
				
			||||||
 | 
					        if (cnt) {
 | 
				
			||||||
 | 
					            for (i = 0; i < cnt; i++) {
 | 
				
			||||||
 | 
					                uart_write(' ');
 | 
				
			||||||
 | 
					                uart_write(hex[(obuf[i+1] >> 4) & 0xf]);
 | 
				
			||||||
 | 
					                uart_write(hex[obuf[i+1] & (0xf)]);
 | 
				
			||||||
 | 
					                // printf(" %02x", obufbuf[i]);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            uart_write('\r');
 | 
				
			||||||
 | 
					            uart_write('\n');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        // printf("\n");
 | 
				
			||||||
 | 
					        usb_ep0out_rd_ptr = (usb_ep0out_rd_ptr + 1) & (EP0OUT_BUFFERS-1);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    // if (!obe) {
 | 
				
			||||||
 | 
					    //     uint32_t obh = usb_obuf_head_read();
 | 
				
			||||||
 | 
					    //     usb_obuf_head_write(1);
 | 
				
			||||||
 | 
					    //     if (i < 300)
 | 
				
			||||||
 | 
					    //         printf("i: %8d  obe: %d  obh: %02x\n", i, obe, obh);
 | 
				
			||||||
 | 
					    // }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int irq_happened;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void usb_init(void) {
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void usb_isr(void) {
 | 
				
			||||||
 | 
					    uint8_t pending = usb_ev_pending_read();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Advance the obuf head, which will reset the obuf_empty bit
 | 
				
			||||||
 | 
					    if (pending & 1) {
 | 
				
			||||||
 | 
					        int byte_count = 0;
 | 
				
			||||||
 | 
					        uint8_t *obuf = usb_ep0out_buffer[usb_ep0out_wr_ptr];
 | 
				
			||||||
 | 
					        while (1) {
 | 
				
			||||||
 | 
					            if (usb_obuf_empty_read())
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            obuf[++byte_count] = usb_obuf_head_read();
 | 
				
			||||||
 | 
					            usb_obuf_head_write(0);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        usb_ev_pending_write(1);
 | 
				
			||||||
 | 
					        obuf[0] = byte_count;
 | 
				
			||||||
 | 
					        usb_ep0out_wr_ptr = (usb_ep0out_wr_ptr + 1) & (EP0OUT_BUFFERS-1);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void usb_connect(void) {
 | 
				
			||||||
 | 
					    usb_pullup_out_write(1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    usb_ev_pending_write(usb_ev_pending_read());
 | 
				
			||||||
 | 
					    usb_ev_enable_write(0xff);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						irq_setmask(irq_getmask() | (1 << USB_INTERRUPT));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void usb_wait(void) {
 | 
				
			||||||
 | 
					    while (!irq_happened)
 | 
				
			||||||
 | 
					        ;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int usb_irq_happened(void) {
 | 
				
			||||||
 | 
					  return irq_happened;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* CSR_USB_OBUF_EMPTY_ADDR */
 | 
				
			||||||
		Reference in New Issue
	
	Block a user