sw: initial commit of mvp test
This version of the test runs end-to-end, and should be mostly feature complete. Signed-off-by: Sean Cross <sean@xobs.io>
This commit is contained in:
parent
5ff6153b53
commit
6d8875850c
@ -1,5 +1,5 @@
|
|||||||
//--------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------
|
||||||
// Auto-generated by Migen (bc90344) & LiteX (3a72688b) on 2019-05-22 22:55:33
|
// Auto-generated by Migen (bc90344) & LiteX (3a72688b) on 2019-05-23 14:16:56
|
||||||
//--------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------
|
||||||
#ifndef __GENERATED_CSR_H
|
#ifndef __GENERATED_CSR_H
|
||||||
#define __GENERATED_CSR_H
|
#define __GENERATED_CSR_H
|
||||||
@ -188,9 +188,9 @@ static inline unsigned char rgb_bypass_read(void) {
|
|||||||
static inline void rgb_bypass_write(unsigned char value) {
|
static inline void rgb_bypass_write(unsigned char value) {
|
||||||
csr_writel(value, 0xe000680cL);
|
csr_writel(value, 0xe000680cL);
|
||||||
}
|
}
|
||||||
#define CSR_RGB_PWM_COUNT_ADDR 0xe0006810L
|
#define CSR_RGB_PULSE_ADDR 0xe0006810L
|
||||||
#define CSR_RGB_PWM_COUNT_SIZE 3
|
#define CSR_RGB_PULSE_SIZE 3
|
||||||
static inline unsigned int rgb_pwm_count_read(void) {
|
static inline unsigned int rgb_pulse_read(void) {
|
||||||
unsigned int r = csr_readl(0xe0006810L);
|
unsigned int r = csr_readl(0xe0006810L);
|
||||||
r <<= 8;
|
r <<= 8;
|
||||||
r |= csr_readl(0xe0006814L);
|
r |= csr_readl(0xe0006814L);
|
||||||
@ -198,33 +198,48 @@ static inline unsigned int rgb_pwm_count_read(void) {
|
|||||||
r |= csr_readl(0xe0006818L);
|
r |= csr_readl(0xe0006818L);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
static inline void rgb_pwm_count_write(unsigned int value) {
|
static inline void rgb_pulse_write(unsigned int value) {
|
||||||
csr_writel(value >> 16, 0xe0006810L);
|
csr_writel(value >> 16, 0xe0006810L);
|
||||||
csr_writel(value >> 8, 0xe0006814L);
|
csr_writel(value >> 8, 0xe0006814L);
|
||||||
csr_writel(value, 0xe0006818L);
|
csr_writel(value, 0xe0006818L);
|
||||||
}
|
}
|
||||||
#define CSR_RGB_SENT_PULSES_ADDR 0xe000681cL
|
#define CSR_RGB_DUTY_ADDR 0xe000681cL
|
||||||
#define CSR_RGB_SENT_PULSES_SIZE 4
|
#define CSR_RGB_DUTY_SIZE 3
|
||||||
static inline unsigned int rgb_sent_pulses_read(void) {
|
static inline unsigned int rgb_duty_read(void) {
|
||||||
unsigned int r = csr_readl(0xe000681cL);
|
unsigned int r = csr_readl(0xe000681cL);
|
||||||
r <<= 8;
|
r <<= 8;
|
||||||
r |= csr_readl(0xe0006820L);
|
r |= csr_readl(0xe0006820L);
|
||||||
r <<= 8;
|
r <<= 8;
|
||||||
r |= csr_readl(0xe0006824L);
|
r |= csr_readl(0xe0006824L);
|
||||||
r <<= 8;
|
|
||||||
r |= csr_readl(0xe0006828L);
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
#define CSR_RGB_DETECTED_PULSES_ADDR 0xe000682cL
|
static inline void rgb_duty_write(unsigned int value) {
|
||||||
#define CSR_RGB_DETECTED_PULSES_SIZE 4
|
csr_writel(value >> 16, 0xe000681cL);
|
||||||
static inline unsigned int rgb_detected_pulses_read(void) {
|
csr_writel(value >> 8, 0xe0006820L);
|
||||||
unsigned int r = csr_readl(0xe000682cL);
|
csr_writel(value, 0xe0006824L);
|
||||||
|
}
|
||||||
|
#define CSR_RGB_SENT_PULSES_ADDR 0xe0006828L
|
||||||
|
#define CSR_RGB_SENT_PULSES_SIZE 4
|
||||||
|
static inline unsigned int rgb_sent_pulses_read(void) {
|
||||||
|
unsigned int r = csr_readl(0xe0006828L);
|
||||||
|
r <<= 8;
|
||||||
|
r |= csr_readl(0xe000682cL);
|
||||||
r <<= 8;
|
r <<= 8;
|
||||||
r |= csr_readl(0xe0006830L);
|
r |= csr_readl(0xe0006830L);
|
||||||
r <<= 8;
|
r <<= 8;
|
||||||
r |= csr_readl(0xe0006834L);
|
r |= csr_readl(0xe0006834L);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
#define CSR_RGB_DETECTED_PULSES_ADDR 0xe0006838L
|
||||||
|
#define CSR_RGB_DETECTED_PULSES_SIZE 4
|
||||||
|
static inline unsigned int rgb_detected_pulses_read(void) {
|
||||||
|
unsigned int r = csr_readl(0xe0006838L);
|
||||||
r <<= 8;
|
r <<= 8;
|
||||||
r |= csr_readl(0xe0006838L);
|
r |= csr_readl(0xe000683cL);
|
||||||
|
r <<= 8;
|
||||||
|
r |= csr_readl(0xe0006840L);
|
||||||
|
r <<= 8;
|
||||||
|
r |= csr_readl(0xe0006844L);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -160,6 +160,11 @@ struct usb_cdc_notification {
|
|||||||
|
|
||||||
int cdc_connected();
|
int cdc_connected();
|
||||||
void cdc_set_connected(int is_connected);
|
void cdc_set_connected(int is_connected);
|
||||||
|
void put_hex(uint32_t val);
|
||||||
|
void put_hex_byte(uint8_t val);
|
||||||
|
void put_string(const char *str);
|
||||||
|
void put_char(char character);
|
||||||
|
void flush_serial(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
191
sw/src/tester.c
191
sw/src/tester.c
@ -1,12 +1,12 @@
|
|||||||
#include <tester.h>
|
#include <tester.h>
|
||||||
#include <printf.h>
|
#include <usb-cdc.h>
|
||||||
#include <spi.h>
|
#include <spi.h>
|
||||||
#include <usb.h>
|
#include <usb.h>
|
||||||
#include <fomu/csr.h>
|
#include <fomu/csr.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <rgb.h>
|
#include <rgb.h>
|
||||||
|
|
||||||
int test_spi(void)
|
static uint32_t test_spi(void)
|
||||||
{
|
{
|
||||||
uint8_t test_buffer[64];
|
uint8_t test_buffer[64];
|
||||||
uint8_t compare_buffer[sizeof(test_buffer)];
|
uint8_t compare_buffer[sizeof(test_buffer)];
|
||||||
@ -15,54 +15,193 @@ int test_spi(void)
|
|||||||
|
|
||||||
struct spi_id id = spiId();
|
struct spi_id id = spiId();
|
||||||
spiSetType(ST_QUAD);
|
spiSetType(ST_QUAD);
|
||||||
// printf("SPI Manufacturer: %02x\n", id.manufacturer_id);
|
put_string("SPI: Manufacturer ");
|
||||||
// printf("SPI Device ID: %02x\n", id.device_id);
|
put_hex_byte(id.manufacturer_id);
|
||||||
// printf("SPI Capacity: %02x %02x\n", id.memory_type, id.memory_size);
|
put_string(" / ");
|
||||||
|
|
||||||
for (i = 0; i < sizeof(test_buffer); i++) {
|
put_string("Device ID ");
|
||||||
test_buffer[i] = (i^0x9d) ^ (i<<5);
|
put_hex_byte(id.device_id);
|
||||||
|
put_string(" / ");
|
||||||
|
|
||||||
|
put_string("Capacity ");
|
||||||
|
put_hex_byte(id.memory_type);
|
||||||
|
put_char(' ');
|
||||||
|
put_hex_byte(id.memory_size);
|
||||||
|
put_string(" / ");
|
||||||
|
|
||||||
|
put_string("Serial ");
|
||||||
|
put_hex(*((uint32_t *)id.serial));
|
||||||
|
put_string(" / ");
|
||||||
|
|
||||||
|
for (i = 0; i < sizeof(test_buffer); i++)
|
||||||
|
{
|
||||||
|
test_buffer[i] = (i ^ 0x9d) ^ (i << 5);
|
||||||
}
|
}
|
||||||
spiWrite(0, test_buffer, sizeof(test_buffer)-1);
|
spiWrite(0, test_buffer, sizeof(test_buffer));
|
||||||
|
|
||||||
for (i = 0; i < sizeof(compare_buffer); i++) {
|
for (i = 0; i < sizeof(compare_buffer); i++)
|
||||||
|
{
|
||||||
compare_buffer[i] = 0;
|
compare_buffer[i] = 0;
|
||||||
}
|
}
|
||||||
spiRead(0, compare_buffer, sizeof(compare_buffer));
|
spiRead(0, compare_buffer, sizeof(compare_buffer));
|
||||||
|
|
||||||
for (i = 0; i < sizeof(compare_buffer); i++) {
|
for (i = 0; i < sizeof(compare_buffer); i++)
|
||||||
if (test_buffer[i] != compare_buffer[i]) {
|
{
|
||||||
|
if (test_buffer[i] != compare_buffer[i])
|
||||||
|
{
|
||||||
|
put_string("E@");
|
||||||
|
put_hex_byte(i);
|
||||||
|
put_char(':');
|
||||||
|
put_hex_byte(test_buffer[i]);
|
||||||
|
put_char('!');
|
||||||
|
put_hex_byte(compare_buffer[i]);
|
||||||
|
put_char(' ');
|
||||||
// printf("SPI: Offset %d Expected %02x Got %02x\n", i, test_buffer[i], compare_buffer[i]);
|
// printf("SPI: Offset %d Expected %02x Got %02x\n", i, test_buffer[i], compare_buffer[i]);
|
||||||
errors++;
|
errors++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!errors)
|
||||||
|
{
|
||||||
|
put_string("Pass\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
put_string("FAIL\n");
|
||||||
|
}
|
||||||
|
|
||||||
return errors;
|
return errors;
|
||||||
}
|
}
|
||||||
|
|
||||||
int test_led(void) {
|
static uint32_t test_one_pad(uint8_t src, uint8_t dest)
|
||||||
|
{
|
||||||
|
unsigned int loops;
|
||||||
|
unsigned int matches = 0;
|
||||||
|
const unsigned int loop_max = 10;
|
||||||
|
|
||||||
|
put_char('0'+src);
|
||||||
|
put_char('>');
|
||||||
|
put_char('0'+dest);
|
||||||
|
put_char(':');
|
||||||
|
for (loops = 0; loops < loop_max; loops++) {
|
||||||
|
// Set pin 2 as output, and pin 0 as input, and see if it loops back.
|
||||||
|
touch_oe_write((1 << src) | (0 << dest));
|
||||||
|
touch_o_write((loops&1) << src);
|
||||||
|
if ((loops&1) == !!((touch_i_read() & (1 << dest))))
|
||||||
|
matches++;
|
||||||
|
}
|
||||||
|
if (matches == loop_max) {
|
||||||
|
put_string("OK ");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
put_string("FAIL(");
|
||||||
|
put_hex_byte(loop_max);
|
||||||
|
put_char('!');
|
||||||
|
put_hex_byte(matches);
|
||||||
|
put_string(") ");
|
||||||
|
return (loop_max - matches);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t test_touch(void)
|
||||||
|
{
|
||||||
|
uint32_t error_count = 0;
|
||||||
|
|
||||||
|
put_string("Touch: ");
|
||||||
|
|
||||||
|
error_count += test_one_pad(0, 2);
|
||||||
|
error_count += test_one_pad(0, 3);
|
||||||
|
error_count += test_one_pad(2, 0);
|
||||||
|
error_count += test_one_pad(2, 3);
|
||||||
|
error_count += test_one_pad(3, 0);
|
||||||
|
error_count += test_one_pad(3, 2);
|
||||||
|
|
||||||
|
if (error_count)
|
||||||
|
put_string("FAIL\n");
|
||||||
|
else
|
||||||
|
put_string("Pass\n");
|
||||||
|
return error_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char color_names[] = {'B', 'R', 'G'};
|
||||||
|
|
||||||
|
static uint32_t test_one_color(int color)
|
||||||
|
{
|
||||||
uint32_t pulses_per_second;
|
uint32_t pulses_per_second;
|
||||||
|
uint32_t sent_pulses;
|
||||||
|
uint32_t detected_pulses;
|
||||||
|
uint32_t high_value;
|
||||||
|
|
||||||
|
rgb_bypass_write(1 << color);
|
||||||
|
rgb_mode_off();
|
||||||
|
rgb_duty_write(SYSTEM_CLOCK_FREQUENCY / 10000 * 1);
|
||||||
|
rgb_pulse_write(SYSTEM_CLOCK_FREQUENCY / 1000 * 1);
|
||||||
|
put_string("RGB");
|
||||||
|
put_char(color_names[color]);
|
||||||
|
put_string(": ");
|
||||||
|
msleep(100);
|
||||||
|
|
||||||
|
rgb_pulse_write(SYSTEM_CLOCK_FREQUENCY / 1000 * 1);
|
||||||
|
pulses_per_second = rgb_pulse_read();
|
||||||
|
high_value = rgb_duty_read();
|
||||||
|
sent_pulses = rgb_sent_pulses_read();
|
||||||
|
detected_pulses = rgb_detected_pulses_read();
|
||||||
|
|
||||||
|
put_hex(pulses_per_second);
|
||||||
|
put_string(" / ");
|
||||||
|
put_hex(high_value);
|
||||||
|
put_string(" / ");
|
||||||
|
put_hex(sent_pulses);
|
||||||
|
put_string(" / ");
|
||||||
|
put_hex(detected_pulses);
|
||||||
|
put_string(" / ");
|
||||||
|
rgb_bypass_write(0);
|
||||||
|
|
||||||
|
uint32_t ratio = ((detected_pulses * 100) / sent_pulses);
|
||||||
|
put_string("Ratio: 0x");
|
||||||
|
put_hex(ratio);
|
||||||
|
put_string(" / ");
|
||||||
|
if (ratio > 60)
|
||||||
|
{
|
||||||
|
put_string("Pass\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
put_string("FAIL\n");
|
||||||
|
return 1 + ratio;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t test_led(void)
|
||||||
|
{
|
||||||
|
uint32_t error_count = 0;
|
||||||
|
|
||||||
touch_oe_write(touch_oe_read() & ~(1 << 1));
|
touch_oe_write(touch_oe_read() & ~(1 << 1));
|
||||||
// touch_oe_write(touch_oe_read() | (1 << 1));
|
// touch_oe_write(touch_oe_read() | (1 << 1));
|
||||||
// touch_o_write(touch_o_read() & ~(1 << 1));
|
// touch_o_write(touch_o_read() & ~(1 << 1));
|
||||||
rgb_bypass_write(1);
|
|
||||||
rgb_mode_off();
|
error_count += test_one_color(0);
|
||||||
rgb_pwm_count_write(SYSTEM_CLOCK_FREQUENCY/1000*125);
|
error_count += test_one_color(1);
|
||||||
printf("Blinking: ");
|
error_count += test_one_color(2);
|
||||||
msleep(1000);
|
return error_count;
|
||||||
pulses_per_second = rgb_pwm_count_read();
|
|
||||||
rgb_pwm_count_write(SYSTEM_CLOCK_FREQUENCY/1000*125);
|
|
||||||
printf("%08x / %08x / %08x\n", pulses_per_second, rgb_sent_pulses_read(), rgb_detected_pulses_read());
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void tester_poll(void)
|
void tester_poll(void)
|
||||||
{
|
{
|
||||||
int error_count = 0;
|
int error_count = 0;
|
||||||
printf("\nHello, world!\n");
|
put_string("\nHello, world!\n");
|
||||||
// error_count = test_spi();
|
error_count += test_spi();
|
||||||
// printf("SPI errors: %d\n", error_count);
|
error_count += test_led();
|
||||||
while (1) {
|
error_count += test_touch();
|
||||||
|
|
||||||
|
put_string("FOMU: ");
|
||||||
|
put_hex(error_count);
|
||||||
|
put_string(" errors ");
|
||||||
|
if (error_count)
|
||||||
|
put_string("FAIL!\n");
|
||||||
|
else
|
||||||
|
put_string("Pass\n");
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
usb_poll();
|
usb_poll();
|
||||||
test_led();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -3,6 +3,10 @@
|
|||||||
#include <fomu/csr.h>
|
#include <fomu/csr.h>
|
||||||
|
|
||||||
static int connected = 0;
|
static int connected = 0;
|
||||||
|
struct str_bfr
|
||||||
|
{
|
||||||
|
uint8_t bfr_contents;
|
||||||
|
} str_bfr;
|
||||||
|
|
||||||
int cdc_connected(void)
|
int cdc_connected(void)
|
||||||
{
|
{
|
||||||
@ -24,4 +28,71 @@ void _putchar(char character)
|
|||||||
;
|
;
|
||||||
usb_ep_2_in_ibuf_head_write(character);
|
usb_ep_2_in_ibuf_head_write(character);
|
||||||
usb_ep_2_in_respond_write(EPF_ACK);
|
usb_ep_2_in_respond_write(EPF_ACK);
|
||||||
|
}
|
||||||
|
|
||||||
|
void flush_serial(void)
|
||||||
|
{
|
||||||
|
if (!str_bfr.bfr_contents)
|
||||||
|
return;
|
||||||
|
|
||||||
|
usb_ep_2_in_respond_write(EPF_ACK);
|
||||||
|
// Wait for buffer to be empty
|
||||||
|
while (usb_ep_2_in_respond_read() == EPF_ACK)
|
||||||
|
;
|
||||||
|
str_bfr.bfr_contents = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void add_char_to_buffer(char character)
|
||||||
|
{
|
||||||
|
while (usb_ep_2_in_respond_read() == EPF_ACK)
|
||||||
|
;
|
||||||
|
usb_ep_2_in_ibuf_head_write(character);
|
||||||
|
str_bfr.bfr_contents++;
|
||||||
|
if (str_bfr.bfr_contents >= 64)
|
||||||
|
flush_serial();
|
||||||
|
}
|
||||||
|
|
||||||
|
void put_string(const char *str)
|
||||||
|
{
|
||||||
|
while (*str != '\0')
|
||||||
|
{
|
||||||
|
if (*str == '\n')
|
||||||
|
add_char_to_buffer('\r');
|
||||||
|
add_char_to_buffer(*str);
|
||||||
|
str++;
|
||||||
|
}
|
||||||
|
flush_serial();
|
||||||
|
}
|
||||||
|
|
||||||
|
void put_hex(uint32_t val)
|
||||||
|
{
|
||||||
|
int num_nibbles = sizeof(val) * 2;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
char v = '0' + (((val >> (num_nibbles - 1) * 4)) & 0x0f);
|
||||||
|
if (v > '9')
|
||||||
|
v += 'a' - ('9'+1);
|
||||||
|
put_char(v);
|
||||||
|
} while (--num_nibbles);
|
||||||
|
}
|
||||||
|
|
||||||
|
void put_hex_byte(uint8_t val)
|
||||||
|
{
|
||||||
|
int num_nibbles = sizeof(val) * 2;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
char v = '0' + (((val >> (num_nibbles - 1) * 4)) & 0x0f);
|
||||||
|
if (v > '9')
|
||||||
|
v += 'a' - ('9'+1);
|
||||||
|
put_char(v);
|
||||||
|
} while (--num_nibbles);
|
||||||
|
}
|
||||||
|
|
||||||
|
void put_char(char character)
|
||||||
|
{
|
||||||
|
if (character == '\n')
|
||||||
|
add_char_to_buffer('\r');
|
||||||
|
add_char_to_buffer(character);
|
||||||
}
|
}
|
@ -7,16 +7,12 @@
|
|||||||
|
|
||||||
static const int max_byte_length = 64;
|
static const int max_byte_length = 64;
|
||||||
|
|
||||||
#define EP0OUT_BUFFERS 4
|
|
||||||
#define EP2OUT_BUFFERS 4
|
#define EP2OUT_BUFFERS 4
|
||||||
__attribute__((aligned(4)))
|
|
||||||
#define EP0OUT_BUFFER_SIZE 256
|
#define EP0OUT_BUFFER_SIZE 256
|
||||||
// static uint8_t volatile usb_ep0out_buffer_len[EP0OUT_BUFFERS];
|
__attribute__((aligned(4)))
|
||||||
static uint8_t volatile usb_ep0out_buffer[EP0OUT_BUFFER_SIZE];
|
static uint8_t volatile usb_ep0out_buffer[64 + 2];
|
||||||
static int wait_reply;
|
static int wait_reply;
|
||||||
static int wait_type;
|
static int wait_type;
|
||||||
// static volatile uint8_t usb_ep0out_wr_ptr;
|
|
||||||
// static volatile uint8_t usb_ep0out_rd_ptr;
|
|
||||||
|
|
||||||
#define EP2OUT_BUFFER_SIZE 256
|
#define EP2OUT_BUFFER_SIZE 256
|
||||||
static uint8_t volatile usb_ep2out_buffer_len[EP2OUT_BUFFERS];
|
static uint8_t volatile usb_ep2out_buffer_len[EP2OUT_BUFFERS];
|
||||||
@ -220,21 +216,35 @@ void usb_isr(void) {
|
|||||||
// and clear the "pending" bit.
|
// and clear the "pending" bit.
|
||||||
if (ep0out_pending) {
|
if (ep0out_pending) {
|
||||||
unsigned int byte_count = 0;
|
unsigned int byte_count = 0;
|
||||||
for (byte_count = 0; byte_count < EP0OUT_BUFFER_SIZE; byte_count++)
|
for (byte_count = 0; byte_count < sizeof(usb_ep0out_buffer); byte_count++)
|
||||||
usb_ep0out_buffer[byte_count] = 0;
|
usb_ep0out_buffer[byte_count] = '\0';
|
||||||
|
|
||||||
byte_count = 0;
|
byte_count = 0;
|
||||||
while (!usb_ep_0_out_obuf_empty_read()) {
|
while (!usb_ep_0_out_obuf_empty_read()) {
|
||||||
usb_ep0out_buffer[byte_count++] = usb_ep_0_out_obuf_head_read();
|
uint8_t byte = usb_ep_0_out_obuf_head_read();
|
||||||
usb_ep_0_out_obuf_head_write(0);
|
usb_ep_0_out_obuf_head_write(0);
|
||||||
|
usb_ep0out_buffer[byte_count++] = byte;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (byte_count >= 2) {
|
if (byte_count >= 2) {
|
||||||
|
volatile void *setup_buffer = usb_ep0out_buffer;
|
||||||
usb_ep_0_in_dtb_write(1);
|
usb_ep_0_in_dtb_write(1);
|
||||||
data_offset = 0;
|
data_offset = 0;
|
||||||
current_length = 0;
|
current_length = 0;
|
||||||
current_data = NULL;
|
current_data = NULL;
|
||||||
wait_reply = usb_setup((void *)usb_ep0out_buffer);
|
byte_count -= 2;
|
||||||
|
// XXX TERRIBLE HACK!
|
||||||
|
// Because the epfifo backend doesn't have any concept of packet boundaries,
|
||||||
|
// sometimes one or two of the bytes from the CRC on the "ACK" from the previous
|
||||||
|
// "Get Descriptor" will be stuck on the front of this request.
|
||||||
|
// This can happen if, for example, we get the OUT from that and the OUT from
|
||||||
|
// the subsequent SETUP packet without first handling that.
|
||||||
|
// Since all SETUP packets are 8 bytes (in this tester), we'll simply clamp the
|
||||||
|
// SETUP data packet to be the last 8 bytes received (minus the 2-byte CRC16).
|
||||||
|
// This is horrible and should be fixed in hardware.
|
||||||
|
if (byte_count > 8)
|
||||||
|
setup_buffer += byte_count - 8;
|
||||||
|
wait_reply = usb_setup((const struct usb_setup_request *)setup_buffer);
|
||||||
}
|
}
|
||||||
usb_ep_0_out_ev_pending_write(ep0out_pending);
|
usb_ep_0_out_ev_pending_write(ep0out_pending);
|
||||||
usb_ep_0_out_respond_write(EPF_ACK);
|
usb_ep_0_out_respond_write(EPF_ACK);
|
||||||
|
Loading…
Reference in New Issue
Block a user