@@ -90,6 +90,12 @@ enum usb_pids {
 | 
				
			|||||||
  USB_PID_MDATA = 0x0f,
 | 
					  USB_PID_MDATA = 0x0f,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum valenty_usb_pids {
 | 
				
			||||||
 | 
					  VUSB_PID_IN = 0x2,
 | 
				
			||||||
 | 
					  VUSB_PID_OUT = 0x0,
 | 
				
			||||||
 | 
					  VUSB_PID_SETUP = 0x3,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct GrainuumUSB;
 | 
					struct GrainuumUSB;
 | 
				
			||||||
struct GrainuumState;
 | 
					struct GrainuumState;
 | 
				
			||||||
struct GrainuumConfig;
 | 
					struct GrainuumConfig;
 | 
				
			||||||
@@ -153,10 +159,10 @@ typedef int (*usb_data_out_finish_t)(struct GrainuumUSB *usb,
 | 
				
			|||||||
struct usb_packet {
 | 
					struct usb_packet {
 | 
				
			||||||
  union {
 | 
					  union {
 | 
				
			||||||
    struct {
 | 
					    struct {
 | 
				
			||||||
      uint8_t pid;
 | 
					      // uint8_t pid;
 | 
				
			||||||
      uint8_t data[GRAINUUM_PACKET_SIZE_MAX + 2]; /* Including CRC */
 | 
					      uint8_t data[GRAINUUM_PACKET_SIZE_MAX + 2]; /* Including CRC */
 | 
				
			||||||
    } __attribute((packed, aligned(4)));
 | 
					    } __attribute((packed, aligned(4)));
 | 
				
			||||||
    uint8_t raw_data[GRAINUUM_PACKET_SIZE_MAX + 3];
 | 
					    uint8_t raw_data[GRAINUUM_PACKET_SIZE_MAX + 2];
 | 
				
			||||||
  } __attribute((packed, aligned(4)));
 | 
					  } __attribute((packed, aligned(4)));
 | 
				
			||||||
  uint8_t size; /* Not including pid (so may be 0) */
 | 
					  uint8_t size; /* Not including pid (so may be 0) */
 | 
				
			||||||
  /* Checksum omitted */
 | 
					  /* Checksum omitted */
 | 
				
			||||||
@@ -497,6 +503,7 @@ int grainuumDataQueued(struct GrainuumUSB *usb);
 | 
				
			|||||||
 * @api
 | 
					 * @api
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
void grainuumProcess(struct GrainuumUSB *usb,
 | 
					void grainuumProcess(struct GrainuumUSB *usb,
 | 
				
			||||||
 | 
					                     uint8_t pid,
 | 
				
			||||||
                     const uint8_t packet[12],
 | 
					                     const uint8_t packet[12],
 | 
				
			||||||
                     uint32_t size);
 | 
					                     uint32_t size);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										
											BIN
										
									
								
								input/top.bin
									
									
									
									
									
								
							
							
						
						
									
										
											BIN
										
									
								
								input/top.bin
									
									
									
									
									
								
							
										
											Binary file not shown.
										
									
								
							@@ -165,7 +165,7 @@ int grainuumCaptureI(struct GrainuumUSB *usb, uint8_t samples[67])
 | 
				
			|||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  grainuumProcess(usb, obufbuf, obufbuf_cnt);
 | 
					  grainuumProcess(usb, last_tok, obufbuf, obufbuf_cnt);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return 0;
 | 
					  return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -210,6 +210,7 @@ void grainuumInit(struct GrainuumUSB *usb,
 | 
				
			|||||||
  if (usb->initialized)
 | 
					  if (usb->initialized)
 | 
				
			||||||
    return;
 | 
					    return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  printf("Initializing USB to %08x, cfg to 0x%08x  0x%08x\n", usb, cfg, cfg->getDescriptor);
 | 
				
			||||||
  grainuumInitPre(usb);
 | 
					  grainuumInitPre(usb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  usb->cfg = cfg;
 | 
					  usb->cfg = cfg;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -30,6 +30,7 @@
 | 
				
			|||||||
 ****************************************************************************/
 | 
					 ****************************************************************************/
 | 
				
			||||||
 #include "grainuum.h"
 | 
					 #include "grainuum.h"
 | 
				
			||||||
 #include <printf.h>
 | 
					 #include <printf.h>
 | 
				
			||||||
 | 
					 #include <generated/csr.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifndef NULL
 | 
					#ifndef NULL
 | 
				
			||||||
#define NULL ((void *)0)
 | 
					#define NULL ((void *)0)
 | 
				
			||||||
@@ -118,10 +119,10 @@ static void grainuum_state_process_tx(struct GrainuumState *state)
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* Pick the correct PID, DATA0 or DATA1 */
 | 
					  /* Pick the correct PID, DATA0 or DATA1 */
 | 
				
			||||||
  if (state->data_buffer & (1 << state->tok_epnum))
 | 
					  // if (state->data_buffer & (1 << state->tok_epnum))
 | 
				
			||||||
    state->packet.pid = USB_PID_DATA1;
 | 
					  //   state->packet.pid = USB_PID_DATA1;
 | 
				
			||||||
  else
 | 
					  // else
 | 
				
			||||||
    state->packet.pid = USB_PID_DATA0;
 | 
					  //   state->packet.pid = USB_PID_DATA0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* If there's no data, prepare a special NULL packet */
 | 
					  /* If there's no data, prepare a special NULL packet */
 | 
				
			||||||
  if ((state->data_out_left == 0) || (state->data_out_max == 0)) {
 | 
					  if ((state->data_out_left == 0) || (state->data_out_max == 0)) {
 | 
				
			||||||
@@ -210,6 +211,7 @@ static int grainuum_state_send_data(struct GrainuumState *state,
 | 
				
			|||||||
  state->data_out_max = max;
 | 
					  state->data_out_max = max;
 | 
				
			||||||
  state->data_out = data;
 | 
					  state->data_out = data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  grainuum_state_process_tx(state);
 | 
				
			||||||
  return 0;
 | 
					  return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -267,6 +269,7 @@ static int grainuum_state_process_setup(struct GrainuumState *state, const uint8
 | 
				
			|||||||
      cfg->setConfigNum(usb, setup->wValue);
 | 
					      cfg->setConfigNum(usb, setup->wValue);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  else {
 | 
					  else {
 | 
				
			||||||
 | 
					    printf("Going to get descriptor @ 0x%08x\n", cfg->getDescriptor);
 | 
				
			||||||
    response_len = cfg->getDescriptor(usb, setup, &response);
 | 
					    response_len = cfg->getDescriptor(usb, setup, &response);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  grainuum_state_send_data(state, state->tok_epnum, response, response_len, setup->wLength);
 | 
					  grainuum_state_send_data(state, state->tok_epnum, response, response_len, setup->wLength);
 | 
				
			||||||
@@ -308,58 +311,38 @@ static void grainuum_state_parse_data(struct GrainuumState *state,
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline void grainuum_state_parse_token(struct GrainuumState *state,
 | 
					 | 
				
			||||||
                                       const uint8_t packet[2])
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  state->tok_epnum = (((const uint16_t *)packet)[0] >> 7) & 0xf;
 | 
					 | 
				
			||||||
  /*state->tok_addr  = (((const uint16_t *)packet)[0] >> 11) & 0x1f; // Field unused in this code*/
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void grainuumProcess(struct GrainuumUSB *usb,
 | 
					void grainuumProcess(struct GrainuumUSB *usb,
 | 
				
			||||||
 | 
					                     uint8_t pid,
 | 
				
			||||||
                     const uint8_t packet[GRAINUUM_PACKET_SIZE_MAX + 3],
 | 
					                     const uint8_t packet[GRAINUUM_PACKET_SIZE_MAX + 3],
 | 
				
			||||||
                     uint32_t size)
 | 
					                     uint32_t size)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // uint32_t size = packet[GRAINUUM_PACKET_SIZE_MAX + 3];
 | 
					  // uint32_t size = packet[GRAINUUM_PACKET_SIZE_MAX + 3];
 | 
				
			||||||
  struct GrainuumState *state = &usb->state;
 | 
					  struct GrainuumState *state = &usb->state;
 | 
				
			||||||
  switch(packet[0]) {
 | 
					  printf("Processing %d byte packet %x %08x (%02x)\n", size, pid, packet, packet[0]);
 | 
				
			||||||
  case USB_PID_SETUP:
 | 
					  switch(pid) {
 | 
				
			||||||
  printf("Setup packet!\n");
 | 
					  case VUSB_PID_SETUP:
 | 
				
			||||||
 | 
					    printf("Setup packet!\n");
 | 
				
			||||||
    state->packet_type = packet_type_setup;
 | 
					    state->packet_type = packet_type_setup;
 | 
				
			||||||
    grainuum_state_clear_tx(state, 1);
 | 
					    grainuum_state_clear_tx(state, 1);
 | 
				
			||||||
    grainuum_state_parse_token(state, packet + 1);
 | 
					 | 
				
			||||||
    break;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  case USB_PID_DATA0:
 | 
					 | 
				
			||||||
    state->data_buffer |= (1 << state->tok_epnum);
 | 
					 | 
				
			||||||
    grainuum_state_parse_data(state, packet + 1, size - 1);
 | 
					 | 
				
			||||||
    break;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  case USB_PID_DATA1:
 | 
					 | 
				
			||||||
    state->data_buffer &= ~(1 << state->tok_epnum);
 | 
					 | 
				
			||||||
    grainuum_state_parse_data(state, packet + 1, size - 1);
 | 
					 | 
				
			||||||
    break;
 | 
					    break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  case USB_PID_OUT:
 | 
					  case USB_PID_OUT:
 | 
				
			||||||
    grainuum_state_parse_token(state, packet + 1);
 | 
					 | 
				
			||||||
    state->packet_type = packet_type_out;
 | 
					    state->packet_type = packet_type_out;
 | 
				
			||||||
    state->tok_pos = 0;
 | 
					    state->tok_pos = 0;
 | 
				
			||||||
    state->tok_buf = usb->cfg->getReceiveBuffer(usb, state->tok_epnum, NULL);
 | 
					    state->tok_buf = usb->cfg->getReceiveBuffer(usb, state->tok_epnum, NULL);
 | 
				
			||||||
  break;
 | 
					  break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  case USB_PID_ACK:
 | 
					 | 
				
			||||||
    state->data_buffer ^= (1 << state->tok_epnum);
 | 
					 | 
				
			||||||
    usbStateTransferSuccess(state);
 | 
					 | 
				
			||||||
    if (state->data_out) {
 | 
					 | 
				
			||||||
      grainuum_state_process_tx(state);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    else {
 | 
					 | 
				
			||||||
      grainuum_state_clear_tx(state, 0);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    break;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  default:
 | 
					  default:
 | 
				
			||||||
 | 
					    printf("Unrecognized PID: %02x\n", pid);
 | 
				
			||||||
    break;
 | 
					    break;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (size == 0) {
 | 
				
			||||||
 | 
					    usb_ep_0_in_respond_write(0);
 | 
				
			||||||
 | 
					    usb_ep_0_in_ev_pending_write(0xff);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  //state->data_buffer |= (1 << state->tok_epnum);
 | 
				
			||||||
 | 
					  grainuum_state_parse_data(state, packet, size);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										60
									
								
								src/main.c
									
									
									
									
									
								
							
							
						
						
									
										60
									
								
								src/main.c
									
									
									
									
									
								
							@@ -28,60 +28,15 @@ static void rv_putchar(void *ignored, char c)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
static void init(void)
 | 
					static void init(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    init_printf(NULL, rv_putchar);
 | 
				
			||||||
    irq_setmask(0);
 | 
					    irq_setmask(0);
 | 
				
			||||||
    irq_setie(1);
 | 
					    irq_setie(1);
 | 
				
			||||||
    uart_init();
 | 
					    uart_init();
 | 
				
			||||||
    usb_init();
 | 
					    usb_init();
 | 
				
			||||||
    time_init();
 | 
					    time_init();
 | 
				
			||||||
    init_printf(NULL, rv_putchar);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef CSR_USB_EP_0_OUT_EV_PENDING_ADDR
 | 
					#ifdef CSR_USB_EP_0_OUT_EV_PENDING_ADDR
 | 
				
			||||||
struct usb_status
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    // uint32_t out_ev_status;
 | 
					 | 
				
			||||||
    uint32_t out_ev_pending;
 | 
					 | 
				
			||||||
    uint32_t in_ev_status;
 | 
					 | 
				
			||||||
    uint32_t out_last_tok;
 | 
					 | 
				
			||||||
    uint32_t out_obuf_empty;
 | 
					 | 
				
			||||||
    uint32_t in_ibuf_empty;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static struct usb_status get_status(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    struct usb_status s;
 | 
					 | 
				
			||||||
    // s.out_ev_status = usb_ep_0_out_ev_status_read();
 | 
					 | 
				
			||||||
    s.out_ev_pending = usb_ep_0_out_ev_pending_read();
 | 
					 | 
				
			||||||
    s.in_ev_status = usb_ep_0_in_ev_status_read();
 | 
					 | 
				
			||||||
    s.out_last_tok = usb_ep_0_out_last_tok_read();
 | 
					 | 
				
			||||||
    s.out_obuf_empty = usb_ep_0_out_obuf_empty_read();
 | 
					 | 
				
			||||||
    s.in_ibuf_empty = usb_ep_0_in_ibuf_empty_read();
 | 
					 | 
				
			||||||
    return s;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void get_print_status(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    static int loops;
 | 
					 | 
				
			||||||
    int obufbuf_cnt = 0;
 | 
					 | 
				
			||||||
    struct usb_status s = get_status();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // printf("i: %8d  OEP: %02x  OBE: %02x  OLT: %02x\n",
 | 
					 | 
				
			||||||
    //         loops++,
 | 
					 | 
				
			||||||
    //         s.out_ev_pending,
 | 
					 | 
				
			||||||
    //         s.out_obuf_empty,
 | 
					 | 
				
			||||||
    //         s.out_last_tok);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (s.out_ev_pending & (1 << 1)) {
 | 
					 | 
				
			||||||
        loops++;
 | 
					 | 
				
			||||||
        usb_isr();
 | 
					 | 
				
			||||||
        // for (i = 0; i < 0x20; i++) {
 | 
					 | 
				
			||||||
        //     usb_ep_0_in_ibuf_head_write(i);
 | 
					 | 
				
			||||||
        // }
 | 
					 | 
				
			||||||
        // // Indicate that we respond with an ACK
 | 
					 | 
				
			||||||
        // usb_ep_0_in_respond_write(USB_ACK);
 | 
					 | 
				
			||||||
        // usb_ep_0_in_ev_pending_write(0xff);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
static void get_print_status(void)
 | 
					static void get_print_status(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@@ -119,21 +74,20 @@ int main(int argc, char **argv)
 | 
				
			|||||||
    (void)argv;
 | 
					    (void)argv;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    init();
 | 
					    init();
 | 
				
			||||||
    printf("\nStatus: %d\n", usb_ep_0_out_ev_pending_read());
 | 
					 | 
				
			||||||
    get_print_status();
 | 
					 | 
				
			||||||
    usb_pullup_out_write(1);
 | 
					    usb_pullup_out_write(1);
 | 
				
			||||||
    usb_ep_0_out_ev_pending_write((1 << 1));
 | 
					    usb_ep_0_out_ev_pending_write((1 << 1));
 | 
				
			||||||
    printf("Status: %d\n", usb_ep_0_out_obuf_empty_read());
 | 
					    if (usb_ep_0_out_ev_pending_read() & (1 << 1))
 | 
				
			||||||
    get_print_status();
 | 
					        usb_isr();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    printf("Hello, world!\n");
 | 
					    printf("Hello, world!\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    int last_event = 0;
 | 
					 | 
				
			||||||
    while (1)
 | 
					    while (1)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        elapsed(&last_event, 1000);
 | 
					        if (usb_ep_0_out_ev_pending_read() & (1 << 1))
 | 
				
			||||||
 | 
					            usb_isr();
 | 
				
			||||||
 | 
					        // elapsed(&last_event, 1000);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        get_print_status();
 | 
					        // get_print_status();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -2,6 +2,7 @@
 | 
				
			|||||||
#include <usb.h>
 | 
					#include <usb.h>
 | 
				
			||||||
#include <generated/csr.h>
 | 
					#include <generated/csr.h>
 | 
				
			||||||
#include <string.h>
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					#include <printf.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define NUM_BUFFERS 4
 | 
					#define NUM_BUFFERS 4
 | 
				
			||||||
#define BUFFER_SIZE 64
 | 
					#define BUFFER_SIZE 64
 | 
				
			||||||
@@ -233,22 +234,28 @@ static int get_descriptor(struct GrainuumUSB *usb,
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const struct usb_setup_packet *setup = packet;
 | 
					  const struct usb_setup_packet *setup = packet;
 | 
				
			||||||
 | 
					  printf("In get_Descriptor()\n");
 | 
				
			||||||
  switch (setup->wValueH)
 | 
					  switch (setup->wValueH)
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
  case DT_DEVICE:
 | 
					  case DT_DEVICE:
 | 
				
			||||||
 | 
					    printf("Returning device descriptor %d\n", setup->wValueL);
 | 
				
			||||||
    return get_device_descriptor(usb, setup->wValueL, response);
 | 
					    return get_device_descriptor(usb, setup->wValueL, response);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  case DT_STRING:
 | 
					  case DT_STRING:
 | 
				
			||||||
 | 
					    printf("Returning string descriptor %d\n", setup->wValueL);
 | 
				
			||||||
    return get_string_descriptor(usb, setup->wValueL, response);
 | 
					    return get_string_descriptor(usb, setup->wValueL, response);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  case DT_CONFIGURATION:
 | 
					  case DT_CONFIGURATION:
 | 
				
			||||||
 | 
					    printf("Returning configuration descriptor %d\n", setup->wValueL);
 | 
				
			||||||
    return get_configuration_descriptor(usb, setup->wValueL, response);
 | 
					    return get_configuration_descriptor(usb, setup->wValueL, response);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  case DT_HID_REPORT:
 | 
					  case DT_HID_REPORT:
 | 
				
			||||||
 | 
					    printf("Returning HID descriptor %d\n", setup->wValueL);
 | 
				
			||||||
    return get_hid_report_descriptor(usb, setup->wValueL, response);
 | 
					    return get_hid_report_descriptor(usb, setup->wValueL, response);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  printf("Returning no descriptor %d\n", setup->wValueL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return 0;
 | 
					  return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user