wip: packets kinda flow now
Signed-off-by: Sean Cross <sean@xobs.io>
This commit is contained in:
parent
d31bcea114
commit
5f0d83b2e2
@ -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) {
|
||||||
|
case VUSB_PID_SETUP:
|
||||||
printf("Setup packet!\n");
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user