sw: add initial tests for spi and rgb
These tests are still a work-in-progress, but they form the basis of what will be the factory test. Signed-off-by: Sean Cross <sean@xobs.io>
This commit is contained in:
		
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										52
									
								
								sw/include/hw/common.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								sw/include/hw/common.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,52 @@
 | 
			
		||||
#ifndef __HW_COMMON_H
 | 
			
		||||
#define __HW_COMMON_H
 | 
			
		||||
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
 | 
			
		||||
/* To overwrite CSR accessors, define extern, non-inlined versions
 | 
			
		||||
 * of csr_read[bwl]() and csr_write[bwl](), and define
 | 
			
		||||
 * CSR_ACCESSORS_DEFINED.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef CSR_ACCESSORS_DEFINED
 | 
			
		||||
#define CSR_ACCESSORS_DEFINED
 | 
			
		||||
 | 
			
		||||
#ifdef __ASSEMBLER__
 | 
			
		||||
#define MMPTR(x) x
 | 
			
		||||
#else /* ! __ASSEMBLER__ */
 | 
			
		||||
#define MMPTR(x) (*((volatile unsigned int *)(x)))
 | 
			
		||||
 | 
			
		||||
static inline void csr_writeb(uint8_t value, uint32_t addr)
 | 
			
		||||
{
 | 
			
		||||
	*((volatile uint8_t *)addr) = value;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline uint8_t csr_readb(uint32_t addr)
 | 
			
		||||
{
 | 
			
		||||
	return *(volatile uint8_t *)addr;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline void csr_writew(uint16_t value, uint32_t addr)
 | 
			
		||||
{
 | 
			
		||||
	*((volatile uint16_t *)addr) = value;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline uint16_t csr_readw(uint32_t addr)
 | 
			
		||||
{
 | 
			
		||||
	return *(volatile uint16_t *)addr;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline void csr_writel(uint32_t value, uint32_t addr)
 | 
			
		||||
{
 | 
			
		||||
	*((volatile uint32_t *)addr) = value;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline uint32_t csr_readl(uint32_t addr)
 | 
			
		||||
{
 | 
			
		||||
	return *(volatile uint32_t *)addr;
 | 
			
		||||
}
 | 
			
		||||
#endif /* ! __ASSEMBLER__ */
 | 
			
		||||
 | 
			
		||||
#endif /* ! CSR_ACCESSORS_DEFINED */
 | 
			
		||||
 | 
			
		||||
#endif /* __HW_COMMON_H */
 | 
			
		||||
@@ -6,5 +6,6 @@ void rgb_mode_idle(void);
 | 
			
		||||
void rgb_mode_done(void);
 | 
			
		||||
void rgb_mode_writing(void);
 | 
			
		||||
void rgb_mode_error(void);
 | 
			
		||||
void rgb_mode_off(void);
 | 
			
		||||
 | 
			
		||||
#endif /* _RGB_H_ */
 | 
			
		||||
@@ -50,45 +50,43 @@ struct spi_id {
 | 
			
		||||
 | 
			
		||||
struct ff_spi;
 | 
			
		||||
 | 
			
		||||
void spiPause(struct ff_spi *spi);
 | 
			
		||||
void spiBegin(struct ff_spi *spi);
 | 
			
		||||
void spiEnd(struct ff_spi *spi);
 | 
			
		||||
void spiPause(void);
 | 
			
		||||
void spiBegin(void);
 | 
			
		||||
void spiEnd(void);
 | 
			
		||||
 | 
			
		||||
//void spiSingleTx(struct ff_spi *spi, uint8_t out);
 | 
			
		||||
//uint8_t spiSingleRx(struct ff_spi *spi);
 | 
			
		||||
//void spiDualTx(struct ff_spi *spi, uint8_t out);
 | 
			
		||||
//void spiQuadTx(struct ff_spi *spi, uint8_t out);
 | 
			
		||||
void spiCommand(struct ff_spi *spi, uint8_t cmd);
 | 
			
		||||
//uint8_t spiDualRx(struct ff_spi *spi);
 | 
			
		||||
//uint8_t spiQuadRx(struct ff_spi *spi);
 | 
			
		||||
int spiTx(struct ff_spi *spi, uint8_t word);
 | 
			
		||||
uint8_t spiRx(struct ff_spi *spi);
 | 
			
		||||
uint8_t spiReadStatus(struct ff_spi *spi, uint8_t sr);
 | 
			
		||||
void spiWriteStatus(struct ff_spi *spi, uint8_t sr, uint8_t val);
 | 
			
		||||
void spiReadSecurity(struct ff_spi *spi, uint8_t sr, uint8_t security[256]);
 | 
			
		||||
void spiWriteSecurity(struct ff_spi *spi, uint8_t sr, uint8_t security[256]);
 | 
			
		||||
int spiSetType(struct ff_spi *spi, enum spi_type type);
 | 
			
		||||
int spiRead(struct ff_spi *spi, uint32_t addr, uint8_t *data, unsigned int count);
 | 
			
		||||
int spiIsBusy(struct ff_spi *spi);
 | 
			
		||||
int spiBeginErase32(struct ff_spi *spi, uint32_t erase_addr);
 | 
			
		||||
int spiBeginErase64(struct ff_spi *spi, uint32_t erase_addr);
 | 
			
		||||
int spiBeginWrite(struct ff_spi *spi, uint32_t addr, const void *data, unsigned int count);
 | 
			
		||||
//void spiSingleTx(uint8_t out);
 | 
			
		||||
//uint8_t spiSingleRx(void);
 | 
			
		||||
//void spiDualTx(uint8_t out);
 | 
			
		||||
//void spiQuadTx(uint8_t out);
 | 
			
		||||
void spiCommand(uint8_t cmd);
 | 
			
		||||
//uint8_t spiDualRx(void);
 | 
			
		||||
//uint8_t spiQuadRx(void);
 | 
			
		||||
int spiTx(uint8_t word);
 | 
			
		||||
uint8_t spiRx(void);
 | 
			
		||||
uint8_t spiReadStatus(uint8_t sr);
 | 
			
		||||
void spiWriteStatus(uint8_t sr, uint8_t val);
 | 
			
		||||
void spiReadSecurity(uint8_t sr, uint8_t security[256]);
 | 
			
		||||
void spiWriteSecurity(uint8_t sr, uint8_t security[256]);
 | 
			
		||||
int spiSetType(enum spi_type type);
 | 
			
		||||
int spiRead(uint32_t addr, uint8_t *data, unsigned int count);
 | 
			
		||||
int spiIsBusy(void);
 | 
			
		||||
int spiBeginErase32(uint32_t erase_addr);
 | 
			
		||||
int spiBeginErase64(uint32_t erase_addr);
 | 
			
		||||
int spiBeginWrite(uint32_t addr, const void *data, unsigned int count);
 | 
			
		||||
void spiEnableQuad(void);
 | 
			
		||||
 | 
			
		||||
struct spi_id spiId(struct ff_spi *spi);
 | 
			
		||||
void spiOverrideSize(struct ff_spi *spi, uint32_t new_size);
 | 
			
		||||
struct spi_id spiId(void);
 | 
			
		||||
void spiOverrideSize(uint32_t new_size);
 | 
			
		||||
 | 
			
		||||
//int spi_wait_for_not_busy(struct ff_spi *spi);
 | 
			
		||||
int spiWrite(struct ff_spi *spi, uint32_t addr, const uint8_t *data, unsigned int count);
 | 
			
		||||
uint8_t spiReset(struct ff_spi *spi);
 | 
			
		||||
int spiInit(struct ff_spi *spi);
 | 
			
		||||
int spiWrite(uint32_t addr, const uint8_t *data, unsigned int count);
 | 
			
		||||
uint8_t spiReset(void);
 | 
			
		||||
int spi_init(void);
 | 
			
		||||
 | 
			
		||||
void spiHold(struct ff_spi *spi);
 | 
			
		||||
void spiUnhold(struct ff_spi *spi);
 | 
			
		||||
void spiSwapTxRx(struct ff_spi *spi);
 | 
			
		||||
void spiHold(void);
 | 
			
		||||
void spiUnhold(void);
 | 
			
		||||
void spiSwapTxRx(void);
 | 
			
		||||
 | 
			
		||||
struct ff_spi *spiAlloc(void);
 | 
			
		||||
void spiSetPin(struct ff_spi *spi, enum spi_pin pin, int val);
 | 
			
		||||
void spiSetPin(enum spi_pin pin, int val);
 | 
			
		||||
void spiFree(void);
 | 
			
		||||
 | 
			
		||||
#endif /* BB_SPI_H_ */
 | 
			
		||||
 
 | 
			
		||||
@@ -62,7 +62,7 @@ struct usb_string_descriptor_struct {
 | 
			
		||||
#define PRODUCT_NAME              u"Fomu Factory Test " GIT_VERSION
 | 
			
		||||
#define PRODUCT_NAME_LEN          sizeof(PRODUCT_NAME)
 | 
			
		||||
#define EP0_SIZE                  64
 | 
			
		||||
#define NUM_INTERFACE             1
 | 
			
		||||
#define NUM_INTERFACE             2
 | 
			
		||||
#define CONFIG_DESC_SIZE          67
 | 
			
		||||
#define USB_DT_INTERFACE_SIZE			9
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -33,7 +33,7 @@ void usb_idle(void);
 | 
			
		||||
void usb_disconnect(void);
 | 
			
		||||
 | 
			
		||||
int usb_irq_happened(void);
 | 
			
		||||
void usb_setup(const struct usb_setup_request *setup);
 | 
			
		||||
int usb_setup(const struct usb_setup_request *setup);
 | 
			
		||||
void usb_send(const void *data, int total_count);
 | 
			
		||||
void usb_ack_in(void);
 | 
			
		||||
void usb_ack_out(void);
 | 
			
		||||
 
 | 
			
		||||
@@ -22,13 +22,11 @@ void isr(void)
 | 
			
		||||
static void init(void)
 | 
			
		||||
{
 | 
			
		||||
    rgb_init();
 | 
			
		||||
    spi = spiAlloc();
 | 
			
		||||
    spiInit(spi);
 | 
			
		||||
    spi_init();
 | 
			
		||||
    irq_setmask(0);
 | 
			
		||||
    irq_setie(1);
 | 
			
		||||
    usb_init();
 | 
			
		||||
    time_init();
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int main(int argc, char **argv)
 | 
			
		||||
 
 | 
			
		||||
@@ -34,6 +34,7 @@ static enum {
 | 
			
		||||
    WRITING,
 | 
			
		||||
    ERROR,
 | 
			
		||||
    DONE,
 | 
			
		||||
    OFF,
 | 
			
		||||
} rgb_mode;
 | 
			
		||||
 | 
			
		||||
static void rgb_write(uint8_t value, uint8_t addr) {
 | 
			
		||||
@@ -86,4 +87,8 @@ void rgb_mode_error(void) {
 | 
			
		||||
 | 
			
		||||
void rgb_mode_done(void) {
 | 
			
		||||
    rgb_switch_mode(DONE, 8, 8, 2, 3, 0x14/4, 0xff/4, 0x44/4);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void rgb_mode_off(void) {
 | 
			
		||||
    rgb_switch_mode(OFF, 0, 0, 0, 0, 0, 0, 0);    
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										917
									
								
								sw/src/spi.c
									
									
									
									
									
								
							
							
						
						
									
										917
									
								
								sw/src/spi.c
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -1,7 +1,68 @@
 | 
			
		||||
#include <tester.h>
 | 
			
		||||
#include <printf.h>
 | 
			
		||||
#include <spi.h>
 | 
			
		||||
#include <usb.h>
 | 
			
		||||
#include <fomu/csr.h>
 | 
			
		||||
#include <time.h>
 | 
			
		||||
#include <rgb.h>
 | 
			
		||||
 | 
			
		||||
void tester_poll(void) {
 | 
			
		||||
    printf("Hello, world!\n");
 | 
			
		||||
    return;
 | 
			
		||||
int test_spi(void)
 | 
			
		||||
{
 | 
			
		||||
    uint8_t test_buffer[64];
 | 
			
		||||
    uint8_t compare_buffer[sizeof(test_buffer)];
 | 
			
		||||
    unsigned int i;
 | 
			
		||||
    int errors = 0;
 | 
			
		||||
 | 
			
		||||
    struct spi_id id = spiId();
 | 
			
		||||
    spiSetType(ST_QUAD);
 | 
			
		||||
    // printf("SPI Manufacturer: %02x\n", id.manufacturer_id);
 | 
			
		||||
    // printf("SPI Device ID: %02x\n", id.device_id);
 | 
			
		||||
    // printf("SPI Capacity: %02x %02x\n", id.memory_type, id.memory_size);
 | 
			
		||||
 | 
			
		||||
    for (i = 0; i < sizeof(test_buffer); i++) {
 | 
			
		||||
        test_buffer[i] = (i^0x9d) ^ (i<<5);
 | 
			
		||||
    }
 | 
			
		||||
    spiWrite(0, test_buffer, sizeof(test_buffer)-1);
 | 
			
		||||
 | 
			
		||||
    for (i = 0; i < sizeof(compare_buffer); i++) {
 | 
			
		||||
        compare_buffer[i] = 0;
 | 
			
		||||
    }
 | 
			
		||||
    spiRead(0, compare_buffer, sizeof(compare_buffer));
 | 
			
		||||
 | 
			
		||||
    for (i = 0; i < sizeof(compare_buffer); i++) {
 | 
			
		||||
        if (test_buffer[i] != compare_buffer[i]) {
 | 
			
		||||
            // printf("SPI: Offset %d  Expected %02x  Got %02x\n", i, test_buffer[i], compare_buffer[i]);
 | 
			
		||||
            errors++;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return errors;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int test_led(void) {
 | 
			
		||||
    uint32_t pulses_per_second;
 | 
			
		||||
    touch_oe_write(touch_oe_read() & ~(1 << 1));
 | 
			
		||||
    // touch_oe_write(touch_oe_read() | (1 << 1));
 | 
			
		||||
    // touch_o_write(touch_o_read() & ~(1 << 1));
 | 
			
		||||
    rgb_bypass_write(1);
 | 
			
		||||
    rgb_mode_off();
 | 
			
		||||
    rgb_pwm_count_write(SYSTEM_CLOCK_FREQUENCY/1000*125);
 | 
			
		||||
    printf("Blinking: ");
 | 
			
		||||
    msleep(1000);
 | 
			
		||||
    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)
 | 
			
		||||
{
 | 
			
		||||
    int error_count = 0;
 | 
			
		||||
    printf("\nHello, world!\n");
 | 
			
		||||
    // error_count = test_spi();
 | 
			
		||||
    // printf("SPI errors: %d\n", error_count);
 | 
			
		||||
    while (1) {
 | 
			
		||||
        usb_poll();
 | 
			
		||||
        test_led();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -16,6 +16,9 @@ void cdc_set_connected(int is_connected)
 | 
			
		||||
 | 
			
		||||
void _putchar(char character)
 | 
			
		||||
{
 | 
			
		||||
    if (character == '\n')
 | 
			
		||||
        _putchar('\r');
 | 
			
		||||
 | 
			
		||||
    // Wait for buffer to be empty
 | 
			
		||||
    while (usb_ep_2_in_respond_read() == EPF_ACK)
 | 
			
		||||
        ;
 | 
			
		||||
 
 | 
			
		||||
@@ -60,7 +60,7 @@
 | 
			
		||||
static const uint8_t device_descriptor[] = {
 | 
			
		||||
    18,                                     // bLength
 | 
			
		||||
    1,                                      // bDescriptorType
 | 
			
		||||
    0x01, 0x02,                             // bcdUSB
 | 
			
		||||
    0x10, 0x01,                             // bcdUSB
 | 
			
		||||
    USB_CLASS_CDC,                          // bDeviceClass
 | 
			
		||||
    0x00,                                   // bDeviceSubClass
 | 
			
		||||
    0x00,                                   // bDeviceProtocol
 | 
			
		||||
 
 | 
			
		||||
@@ -11,11 +11,12 @@ static const int max_byte_length = 64;
 | 
			
		||||
#define EP2OUT_BUFFERS 4
 | 
			
		||||
__attribute__((aligned(4)))
 | 
			
		||||
#define EP0OUT_BUFFER_SIZE 256
 | 
			
		||||
static uint8_t volatile usb_ep0out_buffer_len[EP0OUT_BUFFERS];
 | 
			
		||||
static uint8_t volatile usb_ep0out_buffer[EP0OUT_BUFFERS][EP0OUT_BUFFER_SIZE];
 | 
			
		||||
static uint8_t volatile usb_ep0out_last_tok[EP0OUT_BUFFERS];
 | 
			
		||||
static volatile uint8_t usb_ep0out_wr_ptr;
 | 
			
		||||
static volatile uint8_t usb_ep0out_rd_ptr;
 | 
			
		||||
// static uint8_t volatile usb_ep0out_buffer_len[EP0OUT_BUFFERS];
 | 
			
		||||
static uint8_t volatile usb_ep0out_buffer[EP0OUT_BUFFER_SIZE];
 | 
			
		||||
static int wait_reply;
 | 
			
		||||
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
 | 
			
		||||
static uint8_t volatile usb_ep2out_buffer_len[EP2OUT_BUFFERS];
 | 
			
		||||
@@ -76,8 +77,8 @@ void usb_connect(void) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void usb_init(void) {
 | 
			
		||||
    usb_ep0out_wr_ptr = 0;
 | 
			
		||||
    usb_ep0out_rd_ptr = 0;
 | 
			
		||||
    // usb_ep0out_wr_ptr = 0;
 | 
			
		||||
    // usb_ep0out_rd_ptr = 0;
 | 
			
		||||
    usb_pullup_out_write(0);
 | 
			
		||||
    return;
 | 
			
		||||
}
 | 
			
		||||
@@ -133,8 +134,7 @@ static void process_tx(void) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void usb_send(const void *data, int total_count) {
 | 
			
		||||
 | 
			
		||||
    while ((current_length || current_data))// && usb_ep_0_in_respond_read() != EPF_NAK)
 | 
			
		||||
    while ((current_length || current_data) && (usb_ep_0_in_respond_read() != EPF_NAK))
 | 
			
		||||
        ;
 | 
			
		||||
    current_data = (uint8_t *)data;
 | 
			
		||||
    current_length = total_count;
 | 
			
		||||
@@ -157,34 +157,21 @@ void usb_isr(void) {
 | 
			
		||||
    uint8_t ep2in_pending = usb_ep_2_in_ev_pending_read();
 | 
			
		||||
    uint8_t ep2out_pending = usb_ep_2_out_ev_pending_read();
 | 
			
		||||
 | 
			
		||||
    // We got an OUT or a SETUP packet.  Copy it to usb_ep0out_buffer
 | 
			
		||||
    // and clear the "pending" bit.
 | 
			
		||||
    if (ep0out_pending) {
 | 
			
		||||
        uint8_t last_tok = usb_ep_0_out_last_tok_read();
 | 
			
		||||
        
 | 
			
		||||
        int byte_count = 0;
 | 
			
		||||
        usb_ep0out_last_tok[usb_ep0out_wr_ptr] = last_tok;
 | 
			
		||||
        volatile uint8_t * obuf = usb_ep0out_buffer[usb_ep0out_wr_ptr];
 | 
			
		||||
        while (!usb_ep_0_out_obuf_empty_read()) {
 | 
			
		||||
            obuf[byte_count++] = usb_ep_0_out_obuf_head_read();
 | 
			
		||||
            usb_ep_0_out_obuf_head_write(0);
 | 
			
		||||
        }
 | 
			
		||||
        if (byte_count >= 2)
 | 
			
		||||
            usb_ep0out_buffer_len[usb_ep0out_wr_ptr] = byte_count - 2 /* Strip off CRC16 */;
 | 
			
		||||
        usb_ep0out_wr_ptr = (usb_ep0out_wr_ptr + 1) & (EP0OUT_BUFFERS-1);
 | 
			
		||||
 | 
			
		||||
        if (last_tok == USB_PID_SETUP) {
 | 
			
		||||
            usb_ep_0_in_dtb_write(1);
 | 
			
		||||
            data_offset = 0;
 | 
			
		||||
            current_length = 0;
 | 
			
		||||
            current_data = NULL;
 | 
			
		||||
        }
 | 
			
		||||
        usb_ep_0_out_ev_pending_write(ep0out_pending);
 | 
			
		||||
        usb_ep_0_out_respond_write(EPF_ACK);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // We just got an "IN" token.  Send data if we have it.
 | 
			
		||||
    if (ep0in_pending) {
 | 
			
		||||
        if (wait_reply == 2) {
 | 
			
		||||
            wait_reply--;
 | 
			
		||||
            if (!wait_type) {
 | 
			
		||||
                wait_type = 1;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        else if (wait_reply == 1) {
 | 
			
		||||
            if (wait_type == 2) {
 | 
			
		||||
                current_data = NULL;
 | 
			
		||||
                current_length = 0;
 | 
			
		||||
            }
 | 
			
		||||
            wait_type = 0;
 | 
			
		||||
        }
 | 
			
		||||
        usb_ep_0_in_respond_write(EPF_NAK);
 | 
			
		||||
        usb_ep_0_in_ev_pending_write(ep0in_pending);
 | 
			
		||||
    }
 | 
			
		||||
@@ -200,8 +187,17 @@ void usb_isr(void) {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (ep2out_pending) {
 | 
			
		||||
#ifdef LOOPBACK_TEST
 | 
			
		||||
        volatile uint8_t * obuf = usb_ep2out_buffer[usb_ep2out_wr_ptr];
 | 
			
		||||
        int sz = 0;
 | 
			
		||||
 | 
			
		||||
        if (wait_reply == 2) {
 | 
			
		||||
            wait_reply--;
 | 
			
		||||
            wait_type = 2;
 | 
			
		||||
        }
 | 
			
		||||
        else if (wait_reply == 1) {
 | 
			
		||||
            wait_reply--;
 | 
			
		||||
        }
 | 
			
		||||
        while (!usb_ep_2_out_obuf_empty_read()) {
 | 
			
		||||
            if (sz < EP2OUT_BUFFER_SIZE)
 | 
			
		||||
                obuf[sz++] = usb_ep_2_out_obuf_head_read() + 1;
 | 
			
		||||
@@ -211,12 +207,40 @@ void usb_isr(void) {
 | 
			
		||||
            usb_ep2out_buffer_len[usb_ep2out_wr_ptr] = sz - 2; /* Strip off CRC16 */
 | 
			
		||||
            usb_ep2out_wr_ptr = (usb_ep2out_wr_ptr + 1) & (EP2OUT_BUFFERS-1);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
#else // !LOOPBACK_TEST
 | 
			
		||||
        while (!usb_ep_2_out_obuf_empty_read()) {
 | 
			
		||||
            usb_ep_2_out_obuf_head_write(0);
 | 
			
		||||
        }
 | 
			
		||||
#endif
 | 
			
		||||
        usb_ep_2_out_respond_write(EPF_ACK);
 | 
			
		||||
        usb_ep_2_out_ev_pending_write(ep2out_pending);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return;
 | 
			
		||||
    // We got an OUT or a SETUP packet.  Copy it to usb_ep0out_buffer
 | 
			
		||||
    // and clear the "pending" bit.
 | 
			
		||||
    if (ep0out_pending) {
 | 
			
		||||
        unsigned int byte_count = 0;
 | 
			
		||||
        for (byte_count = 0; byte_count < EP0OUT_BUFFER_SIZE; byte_count++)
 | 
			
		||||
            usb_ep0out_buffer[byte_count] = 0;
 | 
			
		||||
 | 
			
		||||
        byte_count = 0;
 | 
			
		||||
        while (!usb_ep_0_out_obuf_empty_read()) {
 | 
			
		||||
            usb_ep0out_buffer[byte_count++] = usb_ep_0_out_obuf_head_read();
 | 
			
		||||
            usb_ep_0_out_obuf_head_write(0);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (byte_count >= 2) {
 | 
			
		||||
            usb_ep_0_in_dtb_write(1);
 | 
			
		||||
            data_offset = 0;
 | 
			
		||||
            current_length = 0;
 | 
			
		||||
            current_data = NULL;
 | 
			
		||||
            wait_reply = usb_setup((void *)usb_ep0out_buffer);
 | 
			
		||||
        }
 | 
			
		||||
        usb_ep_0_out_ev_pending_write(ep0out_pending);
 | 
			
		||||
        usb_ep_0_out_respond_write(EPF_ACK);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    process_tx();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void usb_ack_in(void) {
 | 
			
		||||
@@ -236,6 +260,7 @@ void usb_err(void) {
 | 
			
		||||
    usb_ep_0_in_respond_write(EPF_STALL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if 0
 | 
			
		||||
int usb_recv(void *buffer, unsigned int buffer_len) {
 | 
			
		||||
 | 
			
		||||
    // Set the OUT response to ACK, since we are in a position to receive data now.
 | 
			
		||||
@@ -256,23 +281,25 @@ int usb_recv(void *buffer, unsigned int buffer_len) {
 | 
			
		||||
    }
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
void usb_poll(void) {
 | 
			
		||||
    // If some data was received, then process it.
 | 
			
		||||
    while (usb_ep0out_rd_ptr != usb_ep0out_wr_ptr) {
 | 
			
		||||
        const struct usb_setup_request *request = (const struct usb_setup_request *)(usb_ep0out_buffer[usb_ep0out_rd_ptr]);
 | 
			
		||||
        // uint8_t len = usb_ep0out_buffer_len[usb_ep0out_rd_ptr];
 | 
			
		||||
        uint8_t last_tok = usb_ep0out_last_tok[usb_ep0out_rd_ptr];
 | 
			
		||||
 | 
			
		||||
        // usb_ep0out_buffer_len[usb_ep0out_rd_ptr] = 0;
 | 
			
		||||
        usb_ep0out_rd_ptr = (usb_ep0out_rd_ptr + 1) & (EP0OUT_BUFFERS-1);
 | 
			
		||||
 | 
			
		||||
        if (last_tok == USB_PID_SETUP) {
 | 
			
		||||
            usb_setup(request);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    process_tx();
 | 
			
		||||
#ifdef LOOPBACK_TEST
 | 
			
		||||
    if (usb_ep2out_rd_ptr != usb_ep2out_wr_ptr) {
 | 
			
		||||
        volatile uint8_t *buf = usb_ep2out_buffer[usb_ep2out_rd_ptr];
 | 
			
		||||
        unsigned int len = usb_ep2out_buffer_len[usb_ep2out_rd_ptr];
 | 
			
		||||
        unsigned int i;
 | 
			
		||||
        while (usb_ep_2_in_respond_read() == EPF_ACK) {
 | 
			
		||||
            ;
 | 
			
		||||
        }
 | 
			
		||||
        for (i = 0; i < len; i++) {
 | 
			
		||||
            usb_ep_2_in_ibuf_head_write(buf[i]);
 | 
			
		||||
        }
 | 
			
		||||
        usb_ep_2_in_respond_write(EPF_ACK);
 | 
			
		||||
        usb_ep2out_rd_ptr = (usb_ep2out_rd_ptr + 1) & (EP2OUT_BUFFERS-1);
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif /* CSR_USB_EP_0_OUT_EV_PENDING_ADDR */
 | 
			
		||||
@@ -8,16 +8,30 @@
 | 
			
		||||
static uint8_t reply_buffer[8];
 | 
			
		||||
static uint8_t usb_configuration = 0;
 | 
			
		||||
 | 
			
		||||
void usb_setup(const struct usb_setup_request *setup)
 | 
			
		||||
int usb_setup(const struct usb_setup_request *setup)
 | 
			
		||||
{
 | 
			
		||||
    const uint8_t *data = NULL;
 | 
			
		||||
    uint32_t datalen = 0;
 | 
			
		||||
    const usb_descriptor_list_t *list;
 | 
			
		||||
    uint32_t max_length = setup->wLength;//((setup->wLength >> 8) & 0xff) | ((setup->wLength << 8) & 0xff00);
 | 
			
		||||
 | 
			
		||||
    switch (setup->wRequestAndType)
 | 
			
		||||
    {
 | 
			
		||||
 | 
			
		||||
    // case 0x21a1: // Get Line Coding
 | 
			
		||||
    //     reply_buffer[0] = 0x80;
 | 
			
		||||
    //     reply_buffer[1] = 0x25;
 | 
			
		||||
    //     reply_buffer[2] = 0x00;
 | 
			
		||||
    //     reply_buffer[3] = 0x00;
 | 
			
		||||
    //     reply_buffer[4] = 0x00;
 | 
			
		||||
    //     reply_buffer[5] = 0x00;
 | 
			
		||||
    //     reply_buffer[6] = 0x08;
 | 
			
		||||
    //     data = reply_buffer;
 | 
			
		||||
    //     datalen = 7;
 | 
			
		||||
    //     break;
 | 
			
		||||
 | 
			
		||||
    case 0x2021: // Set Line Coding
 | 
			
		||||
    case 0x20A1: // Set Line Coding
 | 
			
		||||
        break;
 | 
			
		||||
 | 
			
		||||
    case 0x2221: // Set control line state
 | 
			
		||||
@@ -49,7 +63,7 @@ void usb_setup(const struct usb_setup_request *setup)
 | 
			
		||||
        if (setup->wIndex > 0)
 | 
			
		||||
        {
 | 
			
		||||
            usb_err();
 | 
			
		||||
            return;
 | 
			
		||||
            return 0;
 | 
			
		||||
        }
 | 
			
		||||
        reply_buffer[0] = 0;
 | 
			
		||||
        reply_buffer[1] = 0;
 | 
			
		||||
@@ -64,7 +78,7 @@ void usb_setup(const struct usb_setup_request *setup)
 | 
			
		||||
        {
 | 
			
		||||
            // TODO: do we need to handle IN vs OUT here?
 | 
			
		||||
            usb_err();
 | 
			
		||||
            return;
 | 
			
		||||
            return 0;
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
 | 
			
		||||
@@ -73,7 +87,7 @@ void usb_setup(const struct usb_setup_request *setup)
 | 
			
		||||
        {
 | 
			
		||||
            // TODO: do we need to handle IN vs OUT here?
 | 
			
		||||
            usb_err();
 | 
			
		||||
            return;
 | 
			
		||||
            return 0;
 | 
			
		||||
        }
 | 
			
		||||
        // XXX: Should we set the stall bit?
 | 
			
		||||
        // USB->DIEP0CTL |= USB_DIEP_CTL_STALL;
 | 
			
		||||
@@ -104,20 +118,20 @@ void usb_setup(const struct usb_setup_request *setup)
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        usb_err();
 | 
			
		||||
        return;
 | 
			
		||||
        return 0;
 | 
			
		||||
 | 
			
		||||
    default:
 | 
			
		||||
        usb_err();
 | 
			
		||||
        return;
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
send:
 | 
			
		||||
    if (data && datalen) {
 | 
			
		||||
        if (datalen > setup->wLength)
 | 
			
		||||
            datalen = setup->wLength;
 | 
			
		||||
        if (datalen > max_length)
 | 
			
		||||
            datalen = max_length;
 | 
			
		||||
        usb_send(data, datalen);
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
        usb_ack_in();
 | 
			
		||||
    return;
 | 
			
		||||
    return 2;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user