usb: work-in-progress for USB development
Signed-off-by: Sean Cross <sean@xobs.io>
This commit is contained in:
parent
5f0d83b2e2
commit
fae65117cd
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 */
|
Loading…
Reference in New Issue
Block a user