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:
parent
0c8f29c7bf
commit
5ff6153b53
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_done(void);
|
||||||
void rgb_mode_writing(void);
|
void rgb_mode_writing(void);
|
||||||
void rgb_mode_error(void);
|
void rgb_mode_error(void);
|
||||||
|
void rgb_mode_off(void);
|
||||||
|
|
||||||
#endif /* _RGB_H_ */
|
#endif /* _RGB_H_ */
|
@ -50,45 +50,43 @@ struct spi_id {
|
|||||||
|
|
||||||
struct ff_spi;
|
struct ff_spi;
|
||||||
|
|
||||||
void spiPause(struct ff_spi *spi);
|
void spiPause(void);
|
||||||
void spiBegin(struct ff_spi *spi);
|
void spiBegin(void);
|
||||||
void spiEnd(struct ff_spi *spi);
|
void spiEnd(void);
|
||||||
|
|
||||||
//void spiSingleTx(struct ff_spi *spi, uint8_t out);
|
//void spiSingleTx(uint8_t out);
|
||||||
//uint8_t spiSingleRx(struct ff_spi *spi);
|
//uint8_t spiSingleRx(void);
|
||||||
//void spiDualTx(struct ff_spi *spi, uint8_t out);
|
//void spiDualTx(uint8_t out);
|
||||||
//void spiQuadTx(struct ff_spi *spi, uint8_t out);
|
//void spiQuadTx(uint8_t out);
|
||||||
void spiCommand(struct ff_spi *spi, uint8_t cmd);
|
void spiCommand(uint8_t cmd);
|
||||||
//uint8_t spiDualRx(struct ff_spi *spi);
|
//uint8_t spiDualRx(void);
|
||||||
//uint8_t spiQuadRx(struct ff_spi *spi);
|
//uint8_t spiQuadRx(void);
|
||||||
int spiTx(struct ff_spi *spi, uint8_t word);
|
int spiTx(uint8_t word);
|
||||||
uint8_t spiRx(struct ff_spi *spi);
|
uint8_t spiRx(void);
|
||||||
uint8_t spiReadStatus(struct ff_spi *spi, uint8_t sr);
|
uint8_t spiReadStatus(uint8_t sr);
|
||||||
void spiWriteStatus(struct ff_spi *spi, uint8_t sr, uint8_t val);
|
void spiWriteStatus(uint8_t sr, uint8_t val);
|
||||||
void spiReadSecurity(struct ff_spi *spi, uint8_t sr, uint8_t security[256]);
|
void spiReadSecurity(uint8_t sr, uint8_t security[256]);
|
||||||
void spiWriteSecurity(struct ff_spi *spi, uint8_t sr, uint8_t security[256]);
|
void spiWriteSecurity(uint8_t sr, uint8_t security[256]);
|
||||||
int spiSetType(struct ff_spi *spi, enum spi_type type);
|
int spiSetType(enum spi_type type);
|
||||||
int spiRead(struct ff_spi *spi, uint32_t addr, uint8_t *data, unsigned int count);
|
int spiRead(uint32_t addr, uint8_t *data, unsigned int count);
|
||||||
int spiIsBusy(struct ff_spi *spi);
|
int spiIsBusy(void);
|
||||||
int spiBeginErase32(struct ff_spi *spi, uint32_t erase_addr);
|
int spiBeginErase32(uint32_t erase_addr);
|
||||||
int spiBeginErase64(struct ff_spi *spi, uint32_t erase_addr);
|
int spiBeginErase64(uint32_t erase_addr);
|
||||||
int spiBeginWrite(struct ff_spi *spi, uint32_t addr, const void *data, unsigned int count);
|
int spiBeginWrite(uint32_t addr, const void *data, unsigned int count);
|
||||||
void spiEnableQuad(void);
|
void spiEnableQuad(void);
|
||||||
|
|
||||||
struct spi_id spiId(struct ff_spi *spi);
|
struct spi_id spiId(void);
|
||||||
void spiOverrideSize(struct ff_spi *spi, uint32_t new_size);
|
void spiOverrideSize(uint32_t new_size);
|
||||||
|
|
||||||
//int spi_wait_for_not_busy(struct ff_spi *spi);
|
int spiWrite(uint32_t addr, const uint8_t *data, unsigned int count);
|
||||||
int spiWrite(struct ff_spi *spi, uint32_t addr, const uint8_t *data, unsigned int count);
|
uint8_t spiReset(void);
|
||||||
uint8_t spiReset(struct ff_spi *spi);
|
int spi_init(void);
|
||||||
int spiInit(struct ff_spi *spi);
|
|
||||||
|
|
||||||
void spiHold(struct ff_spi *spi);
|
void spiHold(void);
|
||||||
void spiUnhold(struct ff_spi *spi);
|
void spiUnhold(void);
|
||||||
void spiSwapTxRx(struct ff_spi *spi);
|
void spiSwapTxRx(void);
|
||||||
|
|
||||||
struct ff_spi *spiAlloc(void);
|
void spiSetPin(enum spi_pin pin, int val);
|
||||||
void spiSetPin(struct ff_spi *spi, enum spi_pin pin, int val);
|
|
||||||
void spiFree(void);
|
void spiFree(void);
|
||||||
|
|
||||||
#endif /* BB_SPI_H_ */
|
#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 u"Fomu Factory Test " GIT_VERSION
|
||||||
#define PRODUCT_NAME_LEN sizeof(PRODUCT_NAME)
|
#define PRODUCT_NAME_LEN sizeof(PRODUCT_NAME)
|
||||||
#define EP0_SIZE 64
|
#define EP0_SIZE 64
|
||||||
#define NUM_INTERFACE 1
|
#define NUM_INTERFACE 2
|
||||||
#define CONFIG_DESC_SIZE 67
|
#define CONFIG_DESC_SIZE 67
|
||||||
#define USB_DT_INTERFACE_SIZE 9
|
#define USB_DT_INTERFACE_SIZE 9
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ void usb_idle(void);
|
|||||||
void usb_disconnect(void);
|
void usb_disconnect(void);
|
||||||
|
|
||||||
int usb_irq_happened(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_send(const void *data, int total_count);
|
||||||
void usb_ack_in(void);
|
void usb_ack_in(void);
|
||||||
void usb_ack_out(void);
|
void usb_ack_out(void);
|
||||||
|
@ -22,13 +22,11 @@ void isr(void)
|
|||||||
static void init(void)
|
static void init(void)
|
||||||
{
|
{
|
||||||
rgb_init();
|
rgb_init();
|
||||||
spi = spiAlloc();
|
spi_init();
|
||||||
spiInit(spi);
|
|
||||||
irq_setmask(0);
|
irq_setmask(0);
|
||||||
irq_setie(1);
|
irq_setie(1);
|
||||||
usb_init();
|
usb_init();
|
||||||
time_init();
|
time_init();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
|
@ -34,6 +34,7 @@ static enum {
|
|||||||
WRITING,
|
WRITING,
|
||||||
ERROR,
|
ERROR,
|
||||||
DONE,
|
DONE,
|
||||||
|
OFF,
|
||||||
} rgb_mode;
|
} rgb_mode;
|
||||||
|
|
||||||
static void rgb_write(uint8_t value, uint8_t addr) {
|
static void rgb_write(uint8_t value, uint8_t addr) {
|
||||||
@ -86,4 +87,8 @@ void rgb_mode_error(void) {
|
|||||||
|
|
||||||
void rgb_mode_done(void) {
|
void rgb_mode_done(void) {
|
||||||
rgb_switch_mode(DONE, 8, 8, 2, 3, 0x14/4, 0xff/4, 0x44/4);
|
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 <tester.h>
|
||||||
#include <printf.h>
|
#include <printf.h>
|
||||||
|
#include <spi.h>
|
||||||
|
#include <usb.h>
|
||||||
|
#include <fomu/csr.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <rgb.h>
|
||||||
|
|
||||||
void tester_poll(void) {
|
int test_spi(void)
|
||||||
printf("Hello, world!\n");
|
{
|
||||||
return;
|
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)
|
void _putchar(char character)
|
||||||
{
|
{
|
||||||
|
if (character == '\n')
|
||||||
|
_putchar('\r');
|
||||||
|
|
||||||
// Wait for buffer to be empty
|
// Wait for buffer to be empty
|
||||||
while (usb_ep_2_in_respond_read() == EPF_ACK)
|
while (usb_ep_2_in_respond_read() == EPF_ACK)
|
||||||
;
|
;
|
||||||
|
@ -60,7 +60,7 @@
|
|||||||
static const uint8_t device_descriptor[] = {
|
static const uint8_t device_descriptor[] = {
|
||||||
18, // bLength
|
18, // bLength
|
||||||
1, // bDescriptorType
|
1, // bDescriptorType
|
||||||
0x01, 0x02, // bcdUSB
|
0x10, 0x01, // bcdUSB
|
||||||
USB_CLASS_CDC, // bDeviceClass
|
USB_CLASS_CDC, // bDeviceClass
|
||||||
0x00, // bDeviceSubClass
|
0x00, // bDeviceSubClass
|
||||||
0x00, // bDeviceProtocol
|
0x00, // bDeviceProtocol
|
||||||
|
@ -11,11 +11,12 @@ static const int max_byte_length = 64;
|
|||||||
#define EP2OUT_BUFFERS 4
|
#define EP2OUT_BUFFERS 4
|
||||||
__attribute__((aligned(4)))
|
__attribute__((aligned(4)))
|
||||||
#define EP0OUT_BUFFER_SIZE 256
|
#define EP0OUT_BUFFER_SIZE 256
|
||||||
static uint8_t volatile usb_ep0out_buffer_len[EP0OUT_BUFFERS];
|
// 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_buffer[EP0OUT_BUFFER_SIZE];
|
||||||
static uint8_t volatile usb_ep0out_last_tok[EP0OUT_BUFFERS];
|
static int wait_reply;
|
||||||
static volatile uint8_t usb_ep0out_wr_ptr;
|
static int wait_type;
|
||||||
static volatile uint8_t usb_ep0out_rd_ptr;
|
// 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];
|
||||||
@ -76,8 +77,8 @@ void usb_connect(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void usb_init(void) {
|
void usb_init(void) {
|
||||||
usb_ep0out_wr_ptr = 0;
|
// usb_ep0out_wr_ptr = 0;
|
||||||
usb_ep0out_rd_ptr = 0;
|
// usb_ep0out_rd_ptr = 0;
|
||||||
usb_pullup_out_write(0);
|
usb_pullup_out_write(0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -133,8 +134,7 @@ static void process_tx(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void usb_send(const void *data, int total_count) {
|
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_data = (uint8_t *)data;
|
||||||
current_length = total_count;
|
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 ep2in_pending = usb_ep_2_in_ev_pending_read();
|
||||||
uint8_t ep2out_pending = usb_ep_2_out_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.
|
// We just got an "IN" token. Send data if we have it.
|
||||||
if (ep0in_pending) {
|
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_respond_write(EPF_NAK);
|
||||||
usb_ep_0_in_ev_pending_write(ep0in_pending);
|
usb_ep_0_in_ev_pending_write(ep0in_pending);
|
||||||
}
|
}
|
||||||
@ -200,8 +187,17 @@ void usb_isr(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (ep2out_pending) {
|
if (ep2out_pending) {
|
||||||
|
#ifdef LOOPBACK_TEST
|
||||||
volatile uint8_t * obuf = usb_ep2out_buffer[usb_ep2out_wr_ptr];
|
volatile uint8_t * obuf = usb_ep2out_buffer[usb_ep2out_wr_ptr];
|
||||||
int sz = 0;
|
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()) {
|
while (!usb_ep_2_out_obuf_empty_read()) {
|
||||||
if (sz < EP2OUT_BUFFER_SIZE)
|
if (sz < EP2OUT_BUFFER_SIZE)
|
||||||
obuf[sz++] = usb_ep_2_out_obuf_head_read() + 1;
|
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_buffer_len[usb_ep2out_wr_ptr] = sz - 2; /* Strip off CRC16 */
|
||||||
usb_ep2out_wr_ptr = (usb_ep2out_wr_ptr + 1) & (EP2OUT_BUFFERS-1);
|
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_respond_write(EPF_ACK);
|
||||||
usb_ep_2_out_ev_pending_write(ep2out_pending);
|
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) {
|
void usb_ack_in(void) {
|
||||||
@ -236,6 +260,7 @@ void usb_err(void) {
|
|||||||
usb_ep_0_in_respond_write(EPF_STALL);
|
usb_ep_0_in_respond_write(EPF_STALL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
int usb_recv(void *buffer, unsigned int buffer_len) {
|
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.
|
// 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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void usb_poll(void) {
|
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();
|
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 */
|
#endif /* CSR_USB_EP_0_OUT_EV_PENDING_ADDR */
|
@ -8,16 +8,30 @@
|
|||||||
static uint8_t reply_buffer[8];
|
static uint8_t reply_buffer[8];
|
||||||
static uint8_t usb_configuration = 0;
|
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;
|
const uint8_t *data = NULL;
|
||||||
uint32_t datalen = 0;
|
uint32_t datalen = 0;
|
||||||
const usb_descriptor_list_t *list;
|
const usb_descriptor_list_t *list;
|
||||||
|
uint32_t max_length = setup->wLength;//((setup->wLength >> 8) & 0xff) | ((setup->wLength << 8) & 0xff00);
|
||||||
|
|
||||||
switch (setup->wRequestAndType)
|
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 0x2021: // Set Line Coding
|
||||||
|
case 0x20A1: // Set Line Coding
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x2221: // Set control line state
|
case 0x2221: // Set control line state
|
||||||
@ -49,7 +63,7 @@ void usb_setup(const struct usb_setup_request *setup)
|
|||||||
if (setup->wIndex > 0)
|
if (setup->wIndex > 0)
|
||||||
{
|
{
|
||||||
usb_err();
|
usb_err();
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
reply_buffer[0] = 0;
|
reply_buffer[0] = 0;
|
||||||
reply_buffer[1] = 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?
|
// TODO: do we need to handle IN vs OUT here?
|
||||||
usb_err();
|
usb_err();
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -73,7 +87,7 @@ void usb_setup(const struct usb_setup_request *setup)
|
|||||||
{
|
{
|
||||||
// TODO: do we need to handle IN vs OUT here?
|
// TODO: do we need to handle IN vs OUT here?
|
||||||
usb_err();
|
usb_err();
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
// XXX: Should we set the stall bit?
|
// XXX: Should we set the stall bit?
|
||||||
// USB->DIEP0CTL |= USB_DIEP_CTL_STALL;
|
// USB->DIEP0CTL |= USB_DIEP_CTL_STALL;
|
||||||
@ -104,20 +118,20 @@ void usb_setup(const struct usb_setup_request *setup)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
usb_err();
|
usb_err();
|
||||||
return;
|
return 0;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
usb_err();
|
usb_err();
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
send:
|
send:
|
||||||
if (data && datalen) {
|
if (data && datalen) {
|
||||||
if (datalen > setup->wLength)
|
if (datalen > max_length)
|
||||||
datalen = setup->wLength;
|
datalen = max_length;
|
||||||
usb_send(data, datalen);
|
usb_send(data, datalen);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
usb_ack_in();
|
usb_ack_in();
|
||||||
return;
|
return 2;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user