mirror of
https://github.com/mist-devel/mist-firmware.git
synced 2026-04-17 00:15:25 +00:00
Small joystick fixes
This commit is contained in:
4
Makefile
4
Makefile
@@ -9,7 +9,7 @@ TODAY = `date +"%m/%d/%y"`
|
||||
|
||||
PRJ = firmware
|
||||
SRC = Cstartup_SAM7.c fat.c fdd.c firmware.c fpga.c hardware.c hdd.c main.c menu.c mmc.c osd.c syscalls.c user_io.c boot_print.c boot_logo.c rafile.c config.c tos.c ikbd.c
|
||||
SRC += usb/max3421e.c usb/usb.c usb/hub.c usb/hid.c usb/hidparser.c usb/timer.c
|
||||
SRC += usb/max3421e.c usb/usb.c usb/hub.c usb/hid.c usb/hidparser.c usb/timer.c usb/asix.c
|
||||
SRC += cdc_enumerate.c cdc_control.c
|
||||
|
||||
OBJ = $(SRC:.c=.o)
|
||||
@@ -20,7 +20,7 @@ LIBDIR =
|
||||
|
||||
# Commandline options for each tool.
|
||||
DFLAGS = -I. -Iusb -DMIST
|
||||
CFLAGS = $(DFLAGS) -c -fno-common -O3 -fsigned-char -DVDATE=\"`date +"%y%m%d"`\"
|
||||
CFLAGS = $(DFLAGS) -c -fno-common -O2 -fsigned-char -DVDATE=\"`date +"%y%m%d"`\"
|
||||
AFLAGS = -ahls -mapcs-32
|
||||
LFLAGS = -nostartfiles -Wl,-Map,$(PRJ).map -T$(LINKMAP) $(LIBDIR)
|
||||
CPFLAGS = --output-target=ihex
|
||||
|
||||
8
debug.h
8
debug.h
@@ -55,4 +55,12 @@
|
||||
#define bit8_debugf(...)
|
||||
#endif
|
||||
|
||||
|
||||
#if 1
|
||||
// usb asix debug output in blue
|
||||
#define asix_debugf(a, ...) iprintf("\033[1;34mASIX: " a "\033[0m\n", ##__VA_ARGS__)
|
||||
#else
|
||||
#define asix_debugf(...)
|
||||
#endif
|
||||
|
||||
#endif // DEBUG_H
|
||||
|
||||
@@ -152,7 +152,10 @@ void USART_Poll(void) {
|
||||
}
|
||||
|
||||
void USART_Write(unsigned char c) {
|
||||
|
||||
#if 0
|
||||
while(!(AT91C_BASE_US0->US_CSR & AT91C_US_TXRDY));
|
||||
AT91C_BASE_US0->US_THR = c;
|
||||
#else
|
||||
if((AT91C_BASE_US0->US_CSR & AT91C_US_TXRDY) && (tx_wptr == tx_rptr)) {
|
||||
// transmitter ready and buffer empty? -> send directly
|
||||
AT91C_BASE_US0->US_THR = c;
|
||||
@@ -165,6 +168,7 @@ void USART_Write(unsigned char c) {
|
||||
}
|
||||
|
||||
AT91C_BASE_US0->US_IER = AT91C_US_TXRDY; // enable interrupt
|
||||
#endif
|
||||
}
|
||||
|
||||
void USART_Init(unsigned long baudrate) {
|
||||
|
||||
557
usb/asix.c
Normal file
557
usb/asix.c
Normal file
@@ -0,0 +1,557 @@
|
||||
//
|
||||
// asix.c
|
||||
//
|
||||
// http://lxr.free-electrons.com/source/drivers/net/usb/asix.c?v=3.1
|
||||
|
||||
/*
|
||||
Interface Descriptor:
|
||||
bLength 9
|
||||
bDescriptorType 4
|
||||
bInterfaceNumber 0
|
||||
bAlternateSetting 0
|
||||
bNumEndpoints 3
|
||||
bInterfaceClass 255 Vendor Specific Class
|
||||
bInterfaceSubClass 255 Vendor Specific Subclass
|
||||
bInterfaceProtocol 0
|
||||
iInterface 7
|
||||
Endpoint Descriptor:
|
||||
bLength 7
|
||||
bDescriptorType 5
|
||||
bEndpointAddress 0x81 EP 1 IN
|
||||
bmAttributes 3
|
||||
Transfer Type Interrupt
|
||||
Synch Type None
|
||||
Usage Type Data
|
||||
wMaxPacketSize 0x0008 1x 8 bytes
|
||||
bInterval 11
|
||||
Endpoint Descriptor:
|
||||
bLength 7
|
||||
bDescriptorType 5
|
||||
bEndpointAddress 0x82 EP 2 IN
|
||||
bmAttributes 2
|
||||
Transfer Type Bulk
|
||||
Synch Type None
|
||||
Usage Type Data
|
||||
wMaxPacketSize 0x0200 1x 512 bytes
|
||||
bInterval 0
|
||||
Endpoint Descriptor:
|
||||
bLength 7
|
||||
bDescriptorType 5
|
||||
bEndpointAddress 0x03 EP 3 OUT
|
||||
bmAttributes 2
|
||||
Transfer Type Bulk
|
||||
Synch Type None
|
||||
Usage Type Data
|
||||
wMaxPacketSize 0x0200 1x 512 bytes
|
||||
bInterval 0
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "debug.h"
|
||||
#include "usb.h"
|
||||
#include "asix.h"
|
||||
#include "timer.h"
|
||||
#include "mii.h"
|
||||
#include "max3421e.h"
|
||||
|
||||
// currently only AX88772 is supported as that's the only
|
||||
// device i have
|
||||
#define ASIX_TYPE_AX88772 0x01
|
||||
|
||||
// list of suppoerted/tested devices
|
||||
static const struct {
|
||||
uint16_t vid;
|
||||
uint16_t pid;
|
||||
uint8_t type;
|
||||
} asix_devs[] = {
|
||||
// DLink DUB-E100 H/W Ver B1 Alternate
|
||||
{ 0x2001, 0x3c05, ASIX_TYPE_AX88772 },
|
||||
{ 0, 0, 0 }
|
||||
};
|
||||
|
||||
#define ETH_ALEN 6
|
||||
|
||||
/* ASIX AX8817X based USB 2.0 Ethernet Devices */
|
||||
#define AX_CMD_SET_SW_MII 0x06
|
||||
#define AX_CMD_READ_MII_REG 0x07
|
||||
#define AX_CMD_WRITE_MII_REG 0x08
|
||||
#define AX_CMD_SET_HW_MII 0x0a
|
||||
#define AX_CMD_READ_EEPROM 0x0b
|
||||
#define AX_CMD_WRITE_EEPROM 0x0c
|
||||
#define AX_CMD_WRITE_ENABLE 0x0d
|
||||
#define AX_CMD_WRITE_DISABLE 0x0e
|
||||
#define AX_CMD_READ_RX_CTL 0x0f
|
||||
#define AX_CMD_WRITE_RX_CTL 0x10
|
||||
#define AX_CMD_READ_IPG012 0x11
|
||||
#define AX_CMD_WRITE_IPG0 0x12
|
||||
#define AX_CMD_WRITE_IPG1 0x13
|
||||
#define AX_CMD_READ_NODE_ID 0x13
|
||||
#define AX_CMD_WRITE_IPG2 0x14
|
||||
#define AX_CMD_WRITE_MULTI_FILTER 0x16
|
||||
#define AX88172_CMD_READ_NODE_ID 0x17
|
||||
#define AX_CMD_READ_PHY_ID 0x19
|
||||
#define AX_CMD_READ_MEDIUM_STATUS 0x1a
|
||||
#define AX_CMD_WRITE_MEDIUM_MODE 0x1b
|
||||
#define AX_CMD_READ_MONITOR_MODE 0x1c
|
||||
#define AX_CMD_WRITE_MONITOR_MODE 0x1d
|
||||
#define AX_CMD_READ_GPIOS 0x1e
|
||||
#define AX_CMD_WRITE_GPIOS 0x1f
|
||||
#define AX_CMD_SW_RESET 0x20
|
||||
#define AX_CMD_SW_PHY_STATUS 0x21
|
||||
#define AX_CMD_SW_PHY_SELECT 0x22
|
||||
|
||||
#define AX_SWRESET_CLEAR 0x00
|
||||
#define AX_SWRESET_RR 0x01
|
||||
#define AX_SWRESET_RT 0x02
|
||||
#define AX_SWRESET_PRTE 0x04
|
||||
#define AX_SWRESET_PRL 0x08
|
||||
#define AX_SWRESET_BZ 0x10
|
||||
#define AX_SWRESET_IPRL 0x20
|
||||
#define AX_SWRESET_IPPD 0x40
|
||||
|
||||
/* AX88772 & AX88178 RX_CTL values */
|
||||
#define AX_RX_CTL_SO 0x0080
|
||||
#define AX_RX_CTL_AP 0x0020
|
||||
#define AX_RX_CTL_AM 0x0010
|
||||
#define AX_RX_CTL_AB 0x0008
|
||||
#define AX_RX_CTL_SEP 0x0004
|
||||
#define AX_RX_CTL_AMALL 0x0002
|
||||
#define AX_RX_CTL_PRO 0x0001
|
||||
#define AX_RX_CTL_MFB_2048 0x0000
|
||||
#define AX_RX_CTL_MFB_4096 0x0100
|
||||
#define AX_RX_CTL_MFB_8192 0x0200
|
||||
#define AX_RX_CTL_MFB_16384 0x0300
|
||||
|
||||
#define AX88772_IPG0_DEFAULT 0x15
|
||||
#define AX88772_IPG1_DEFAULT 0x0c
|
||||
#define AX88772_IPG2_DEFAULT 0x12
|
||||
|
||||
/* AX88772 & AX88178 Medium Mode Register */
|
||||
#define AX_MEDIUM_PF 0x0080
|
||||
#define AX_MEDIUM_JFE 0x0040
|
||||
#define AX_MEDIUM_TFC 0x0020
|
||||
#define AX_MEDIUM_RFC 0x0010
|
||||
#define AX_MEDIUM_ENCK 0x0008
|
||||
#define AX_MEDIUM_AC 0x0004
|
||||
#define AX_MEDIUM_FD 0x0002
|
||||
#define AX_MEDIUM_GM 0x0001
|
||||
#define AX_MEDIUM_SM 0x1000
|
||||
#define AX_MEDIUM_SBP 0x0800
|
||||
#define AX_MEDIUM_PS 0x0200
|
||||
#define AX_MEDIUM_RE 0x0100
|
||||
|
||||
#define AX88178_MEDIUM_DEFAULT \
|
||||
(AX_MEDIUM_PS | AX_MEDIUM_FD | AX_MEDIUM_AC | \
|
||||
AX_MEDIUM_RFC | AX_MEDIUM_TFC | AX_MEDIUM_JFE | \
|
||||
AX_MEDIUM_RE )
|
||||
|
||||
#define AX88772_MEDIUM_DEFAULT \
|
||||
(AX_MEDIUM_FD | AX_MEDIUM_RFC | \
|
||||
AX_MEDIUM_TFC | AX_MEDIUM_PS | \
|
||||
AX_MEDIUM_AC | AX_MEDIUM_RE )
|
||||
|
||||
/* AX88772 & AX88178 RX_CTL values */
|
||||
#define AX_RX_CTL_SO 0x0080
|
||||
#define AX_RX_CTL_AP 0x0020
|
||||
#define AX_RX_CTL_AM 0x0010
|
||||
#define AX_RX_CTL_AB 0x0008
|
||||
#define AX_RX_CTL_SEP 0x0004
|
||||
#define AX_RX_CTL_AMALL 0x0002
|
||||
#define AX_RX_CTL_PRO 0x0001
|
||||
#define AX_RX_CTL_MFB_2048 0x0000
|
||||
#define AX_RX_CTL_MFB_4096 0x0100
|
||||
#define AX_RX_CTL_MFB_8192 0x0200
|
||||
#define AX_RX_CTL_MFB_16384 0x0300
|
||||
|
||||
#define AX_DEFAULT_RX_CTL \
|
||||
(AX_RX_CTL_SO | AX_RX_CTL_AB )
|
||||
|
||||
/* GPIO 0 .. 2 toggles */
|
||||
#define AX_GPIO_GPO0EN 0x01 /* GPIO0 Output enable */
|
||||
#define AX_GPIO_GPO_0 0x02 /* GPIO0 Output value */
|
||||
#define AX_GPIO_GPO1EN 0x04 /* GPIO1 Output enable */
|
||||
#define AX_GPIO_GPO_1 0x08 /* GPIO1 Output value */
|
||||
#define AX_GPIO_GPO2EN 0x10 /* GPIO2 Output enable */
|
||||
#define AX_GPIO_GPO_2 0x20 /* GPIO2 Output value */
|
||||
#define AX_GPIO_RESERVED 0x40 /* Reserved */
|
||||
#define AX_GPIO_RSE 0x80 /* Reload serial EEPROM */
|
||||
|
||||
#define ASIX_REQ_OUT USB_SETUP_HOST_TO_DEVICE|USB_SETUP_TYPE_VENDOR|USB_SETUP_RECIPIENT_DEVICE
|
||||
#define ASIX_REQ_IN USB_SETUP_DEVICE_TO_HOST|USB_SETUP_TYPE_VENDOR|USB_SETUP_RECIPIENT_DEVICE
|
||||
|
||||
static uint8_t asix_write_cmd(usb_device_t *dev, uint8_t cmd, uint16_t value, uint16_t index,
|
||||
uint16_t size, uint8_t *data) {
|
||||
asix_debugf("%s() cmd=0x%02x value=0x%04x index=0x%04x size=%d", __FUNCTION__,
|
||||
cmd, value, index, size);
|
||||
|
||||
return(usb_ctrl_req( dev, ASIX_REQ_OUT, cmd, index, value, 0, size, data));
|
||||
}
|
||||
|
||||
static uint8_t asix_read_cmd(usb_device_t *dev, uint8_t cmd, uint16_t value, uint16_t index,
|
||||
uint16_t size, void *data) {
|
||||
uint8_t buf[size];
|
||||
|
||||
asix_debugf("asix_read_cmd() cmd=0x%02x value=0x%04x index=0x%04x size=%d",
|
||||
cmd, value, index, size);
|
||||
|
||||
return(usb_ctrl_req( dev, ASIX_REQ_IN, cmd, index, value, 0, size, data));
|
||||
}
|
||||
|
||||
static uint8_t asix_write_gpio(usb_device_t *dev, uint16_t value, uint16_t sleep) {
|
||||
uint8_t rcode;
|
||||
|
||||
asix_debugf("%s() value=0x%04x sleep=%d", __FUNCTION__, value, sleep);
|
||||
|
||||
rcode = asix_write_cmd(dev, AX_CMD_WRITE_GPIOS, value, 0, 0, NULL);
|
||||
if(rcode) asix_debugf("Failed to write GPIO value 0x%04x: %02x\n", value, rcode);
|
||||
|
||||
if (sleep) timer_delay_msec(sleep);
|
||||
|
||||
return rcode;
|
||||
}
|
||||
|
||||
static uint8_t asix_write_medium_mode(usb_device_t *dev, uint16_t mode) {
|
||||
uint8_t rcode;
|
||||
|
||||
asix_debugf("asix_write_medium_mode() - mode = 0x%04x", mode);
|
||||
rcode = asix_write_cmd(dev, AX_CMD_WRITE_MEDIUM_MODE, mode, 0, 0, NULL);
|
||||
if(rcode != 0)
|
||||
asix_debugf("Failed to write Medium Mode mode to 0x%04x: %02x", mode, rcode);
|
||||
|
||||
return rcode;
|
||||
}
|
||||
|
||||
static uint16_t asix_read_medium_status(usb_device_t *dev) {
|
||||
uint16_t v;
|
||||
|
||||
uint8_t rcode = asix_read_cmd(dev, AX_CMD_READ_MEDIUM_STATUS, 0, 0, 2, (uint8_t*)&v);
|
||||
if (rcode != 0) {
|
||||
asix_debugf("Error reading Medium Status register: %02x", rcode);
|
||||
return rcode;
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
static inline uint8_t asix_set_sw_mii(usb_device_t *dev) {
|
||||
uint8_t rcode = asix_write_cmd(dev, AX_CMD_SET_SW_MII, 0x0000, 0, 0, NULL);
|
||||
if(rcode != 0)
|
||||
asix_debugf("Failed to enable software MII access");
|
||||
|
||||
return rcode;
|
||||
}
|
||||
|
||||
static inline uint8_t asix_set_hw_mii(usb_device_t *dev) {
|
||||
uint8_t rcode = asix_write_cmd(dev, AX_CMD_SET_HW_MII, 0x0000, 0, 0, NULL);
|
||||
if(rcode != 0)
|
||||
asix_debugf("Failed to enable hardware MII access");
|
||||
|
||||
return rcode;
|
||||
}
|
||||
|
||||
static inline int8_t asix_get_phy_addr(usb_device_t *dev) {
|
||||
union {
|
||||
uint8_t b[2];
|
||||
uint16_t w;
|
||||
} buf;
|
||||
|
||||
uint8_t ret = asix_read_cmd(dev, AX_CMD_READ_PHY_ID, 0, 0, sizeof(buf), &buf);
|
||||
|
||||
asix_debugf("%s()", __FUNCTION__);
|
||||
|
||||
if (ret != 0) {
|
||||
asix_debugf("Error reading PHYID register: %02x", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
asix_debugf("returning 0x%04x", buf.w);
|
||||
|
||||
return buf.b[1];
|
||||
}
|
||||
|
||||
static uint16_t asix_mdio_read(usb_device_t *dev, uint8_t phy_id, uint8_t loc) {
|
||||
uint16_t res;
|
||||
|
||||
asix_set_sw_mii(dev);
|
||||
asix_read_cmd(dev, AX_CMD_READ_MII_REG, phy_id, loc, 2, &res);
|
||||
asix_set_hw_mii(dev);
|
||||
|
||||
asix_debugf("asix_mdio_read() phy_id=0x%02x, loc=0x%02x, returns=0x%04x", phy_id, loc, res);
|
||||
return res;
|
||||
}
|
||||
|
||||
static void asix_mdio_write(usb_device_t *dev, uint8_t phy_id, uint8_t loc, uint16_t val) {
|
||||
asix_debugf("asix_mdio_write() phy_id=0x%02x, loc=0x%02x, val=0x%04x", phy_id, loc, val);
|
||||
|
||||
asix_set_sw_mii(dev);
|
||||
asix_write_cmd(dev, AX_CMD_WRITE_MII_REG, phy_id, loc, 2, (uint8_t*)&val);
|
||||
asix_set_hw_mii(dev);
|
||||
}
|
||||
|
||||
/* Get the PHY Identifier from the PHYSID1 & PHYSID2 MII registers */
|
||||
static uint32_t asix_get_phyid(usb_device_t *dev) {
|
||||
usb_asix_info_t *info = &(dev->asix_info);
|
||||
|
||||
int16_t phy_reg;
|
||||
uint32_t phy_id;
|
||||
|
||||
phy_reg = asix_mdio_read(dev, info->phy_id, MII_PHYSID1);
|
||||
if(phy_reg < 0) return 0;
|
||||
|
||||
phy_id = (phy_reg & 0xffff) << 16;
|
||||
phy_reg = asix_mdio_read(dev, info->phy_id, MII_PHYSID2);
|
||||
if(phy_reg < 0) return 0;
|
||||
|
||||
phy_id |= (phy_reg & 0xffff);
|
||||
return phy_id;
|
||||
}
|
||||
|
||||
static uint8_t asix_sw_reset(usb_device_t *dev, uint8_t flags) {
|
||||
uint8_t rcode;
|
||||
|
||||
rcode = asix_write_cmd(dev, AX_CMD_SW_RESET, flags, 0, 0, NULL);
|
||||
if (rcode != 0)
|
||||
asix_debugf("Failed to send software reset: %02x", rcode);
|
||||
|
||||
return rcode;
|
||||
}
|
||||
|
||||
static uint16_t asix_read_rx_ctl(usb_device_t *dev) {
|
||||
// this only works on little endian which the arm is
|
||||
uint16_t v;
|
||||
uint8_t rcode = asix_read_cmd(dev, AX_CMD_READ_RX_CTL, 0, 0, 2, &v);
|
||||
if(rcode != 0) {
|
||||
asix_debugf("Error reading RX_CTL register: %02x", rcode);
|
||||
return rcode;
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
static uint16_t asix_write_rx_ctl(usb_device_t *dev, uint16_t mode) {
|
||||
uint8_t rcode = asix_write_cmd(dev, AX_CMD_WRITE_RX_CTL, mode, 0, 0, NULL);
|
||||
if(rcode != 0)
|
||||
asix_debugf("Error writing RX_CTL register: %02x", rcode);
|
||||
|
||||
return rcode;
|
||||
}
|
||||
|
||||
/**
|
||||
* mii_nway_restart - restart NWay (autonegotiation) for this interface
|
||||
* @mii: the MII interface
|
||||
*
|
||||
* Returns 0 on success, negative on error.
|
||||
*/
|
||||
void mii_nway_restart(usb_device_t *dev) {
|
||||
usb_asix_info_t *info = &(dev->asix_info);
|
||||
|
||||
/* if autoneg is off, it's an error */
|
||||
uint16_t bmcr = asix_mdio_read(dev, info->phy_id, MII_BMCR);
|
||||
|
||||
if(bmcr & BMCR_ANENABLE) {
|
||||
bmcr |= BMCR_ANRESTART;
|
||||
asix_mdio_write(dev, info->phy_id, MII_BMCR, bmcr);
|
||||
} else
|
||||
asix_debugf("%s() failed", __FUNCTION__);
|
||||
}
|
||||
|
||||
static uint8_t usb_asix_init(usb_device_t *dev) {
|
||||
usb_asix_info_t *info = &(dev->asix_info);
|
||||
uint8_t i, rcode = 0;
|
||||
|
||||
// reset status
|
||||
info->qNextPollTime = 0;
|
||||
info->bPollEnable = false;
|
||||
|
||||
info->ep.epAddr = 1;
|
||||
info->ep.maxPktSize = 8;
|
||||
info->ep.epAttribs = 0;
|
||||
info->ep.bmNakPower = USB_NAK_NOWAIT;
|
||||
|
||||
asix_debugf("%s(%d)", __FUNCTION__, dev->bAddress);
|
||||
|
||||
union {
|
||||
usb_device_descriptor_t dev_desc;
|
||||
usb_configuration_descriptor_t conf_desc;
|
||||
uint8_t eaddr[ETH_ALEN];
|
||||
} buf;
|
||||
|
||||
// read full device descriptor
|
||||
rcode = usb_get_dev_descr( dev, sizeof(usb_device_descriptor_t), &buf.dev_desc );
|
||||
if( rcode ) {
|
||||
asix_debugf("failed to get device descriptor");
|
||||
return rcode;
|
||||
}
|
||||
|
||||
// If device class is not vendor specific return
|
||||
if (buf.dev_desc.bDeviceClass != USB_CLASS_VENDOR_SPECIFIC)
|
||||
return USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED;
|
||||
|
||||
asix_debugf("vid/pid = %x/%x", buf.dev_desc.idVendor, buf.dev_desc.idProduct);
|
||||
|
||||
// search for vid/pid in supported device list
|
||||
for(i=0;asix_devs[i].type &&
|
||||
((asix_devs[i].vid != buf.dev_desc.idVendor) ||
|
||||
(asix_devs[i].pid != buf.dev_desc.idProduct));i++);
|
||||
|
||||
if(!asix_devs[i].type) {
|
||||
asix_debugf("Not a supported ASIX device");
|
||||
return USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
asix_debugf("supported device");
|
||||
|
||||
if((rcode = asix_write_gpio(dev, AX_GPIO_RSE | AX_GPIO_GPO_2 | AX_GPIO_GPO2EN, 5)) != 0) {
|
||||
asix_debugf("setting gpio failed\n");
|
||||
return rcode;
|
||||
}
|
||||
|
||||
/* 0x10 is the phy id of the embedded 10/100 ethernet phy */
|
||||
int8_t embd_phy = ((asix_get_phy_addr(dev) & 0x1f) == 0x10 ? 1 : 0);
|
||||
if((rcode = asix_write_cmd(dev, AX_CMD_SW_PHY_SELECT, embd_phy, 0, 0, NULL)) != 0) {
|
||||
asix_debugf("Select PHY #1 failed");
|
||||
return rcode;
|
||||
}
|
||||
|
||||
if ((rcode = asix_sw_reset(dev, AX_SWRESET_IPPD | AX_SWRESET_PRL)) != 0) {
|
||||
asix_debugf("reset(AX_SWRESET_IPPD | AX_SWRESET_PRL) failed");
|
||||
return rcode;
|
||||
}
|
||||
|
||||
timer_delay_msec(150);
|
||||
|
||||
if ((rcode = asix_sw_reset(dev, AX_SWRESET_CLEAR)) != 0) {
|
||||
asix_debugf("reset(AX_SWRESET_CLEAR) failed");
|
||||
return rcode;
|
||||
}
|
||||
|
||||
timer_delay_msec(150);
|
||||
|
||||
if (embd_phy) {
|
||||
if ((rcode = asix_sw_reset(dev, AX_SWRESET_IPRL)) != 0) {
|
||||
asix_debugf("reset(AX_SWRESET_IPRL) failed");
|
||||
return rcode;
|
||||
}
|
||||
} else {
|
||||
if ((rcode = asix_sw_reset(dev, AX_SWRESET_PRTE)) != 0) {
|
||||
asix_debugf("reset(AX_SWRESET_PRTE) failed");
|
||||
return rcode;
|
||||
}
|
||||
}
|
||||
|
||||
timer_delay_msec(150);
|
||||
|
||||
uint16_t rx_ctl = asix_read_rx_ctl(dev);
|
||||
asix_debugf("RX_CTL is 0x%04x after software reset", rx_ctl);
|
||||
|
||||
if((rcode = asix_write_rx_ctl(dev, 0x0000)) != 0) {
|
||||
asix_debugf("write_rx_ctl(0) failed");
|
||||
return rcode;
|
||||
}
|
||||
|
||||
rx_ctl = asix_read_rx_ctl(dev);
|
||||
asix_debugf("RX_CTL is 0x%04x setting to 0x0000", rx_ctl);
|
||||
|
||||
/* Get the MAC address */
|
||||
if ((rcode = asix_read_cmd(dev, AX_CMD_READ_NODE_ID,
|
||||
0, 0, ETH_ALEN, &buf.eaddr)) != 0) {
|
||||
asix_debugf("Failed to read MAC address: %d", rcode);
|
||||
return rcode;
|
||||
}
|
||||
|
||||
iprintf("ASIX: MAC %02x:%02x:%02x:%02x:%02x:%02x\n",
|
||||
buf.eaddr[0], buf.eaddr[1], buf.eaddr[2],
|
||||
buf.eaddr[3], buf.eaddr[4], buf.eaddr[5]);
|
||||
|
||||
info->phy_id = asix_get_phy_addr(dev);
|
||||
|
||||
uint32_t phyid = asix_get_phyid(dev);
|
||||
iprintf("ASIX: PHYID=0x%08x\n", phyid);
|
||||
|
||||
if ((rcode = asix_sw_reset(dev, AX_SWRESET_PRL)) != 0) {
|
||||
asix_debugf("reset(AX_SWRESET_PRL) failed");
|
||||
return rcode;
|
||||
}
|
||||
|
||||
timer_delay_msec(150);
|
||||
|
||||
if ((rcode = asix_sw_reset(dev, AX_SWRESET_IPRL | AX_SWRESET_PRL)) != 0) {
|
||||
asix_debugf("reset(AX_SWRESET_IPRL | AX_SWRESET_PRL) failed");
|
||||
return rcode;
|
||||
}
|
||||
|
||||
timer_delay_msec(150);
|
||||
|
||||
asix_mdio_write(dev, info->phy_id, MII_BMCR, BMCR_RESET);
|
||||
asix_mdio_write(dev, info->phy_id, MII_ADVERTISE, ADVERTISE_ALL | ADVERTISE_CSMA);
|
||||
|
||||
mii_nway_restart(dev);
|
||||
|
||||
if ((rcode = asix_write_medium_mode(dev, AX88772_MEDIUM_DEFAULT)) != 0) {
|
||||
asix_debugf("asix_write_medium_mode(AX88772_MEDIUM_DEFAULT) failed\n");
|
||||
return rcode;
|
||||
}
|
||||
|
||||
if ((rcode = asix_write_cmd(dev, AX_CMD_WRITE_IPG0,
|
||||
AX88772_IPG0_DEFAULT | AX88772_IPG1_DEFAULT,
|
||||
AX88772_IPG2_DEFAULT, 0, NULL)) != 0) {
|
||||
asix_debugf("Write IPG,IPG1,IPG2 failed: %d", rcode);
|
||||
return rcode;
|
||||
}
|
||||
|
||||
/* Set RX_CTL to default values with 2k buffer, and enable cactus */
|
||||
if ((rcode = asix_write_rx_ctl(dev, AX_DEFAULT_RX_CTL)) != 0)
|
||||
return rcode;
|
||||
|
||||
iprintf("status = %x (%x)\n", asix_mdio_read(dev, info->phy_id, MII_BMSR), 12);
|
||||
|
||||
rx_ctl = asix_read_rx_ctl(dev);
|
||||
iprintf("ASIX: RX_CTL is 0x%04x after all initializations\n", rx_ctl);
|
||||
|
||||
rx_ctl = asix_read_medium_status(dev);
|
||||
iprintf("ASIX: Medium Status is 0x%04x after all initializations\n", rx_ctl);
|
||||
|
||||
info->bPollEnable = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint8_t usb_asix_release(usb_device_t *dev) {
|
||||
asix_debugf("%s()", __FUNCTION__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint8_t usb_asix_poll(usb_device_t *dev) {
|
||||
usb_asix_info_t *info = &(dev->asix_info);
|
||||
uint8_t rcode = 0;
|
||||
|
||||
if (!info->bPollEnable)
|
||||
return 0;
|
||||
|
||||
if (info->qNextPollTime <= timer_get_msec()) {
|
||||
uint16_t read = 1; // info->ep.maxPktSize;
|
||||
uint8_t buf[info->ep.maxPktSize];
|
||||
uint8_t rcode =
|
||||
usb_in_transfer(dev, &(info->ep), &read, buf);
|
||||
|
||||
/* d = hrJERR */
|
||||
|
||||
if (rcode) {
|
||||
// if (rcode != hrNAK)
|
||||
// iprintf("%s() error: %x\n", __FUNCTION__, rcode);
|
||||
// else
|
||||
// puts("nak");
|
||||
} else {
|
||||
iprintf("ASIX: %d bytes\n", read);
|
||||
|
||||
|
||||
}
|
||||
|
||||
info->qNextPollTime = timer_get_msec() + 1000; // poll 1 times a second
|
||||
}
|
||||
|
||||
return rcode;
|
||||
}
|
||||
|
||||
const usb_device_class_config_t usb_asix_class = {
|
||||
usb_asix_init, usb_asix_release, usb_asix_poll };
|
||||
17
usb/asix.h
Normal file
17
usb/asix.h
Normal file
@@ -0,0 +1,17 @@
|
||||
#ifndef ASIX_H
|
||||
#define ASIX_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
typedef struct {
|
||||
ep_t ep;
|
||||
uint16_t phy_id;
|
||||
uint32_t qNextPollTime; // next poll time
|
||||
bool bPollEnable;
|
||||
} usb_asix_info_t;
|
||||
|
||||
// interface to usb core
|
||||
extern const usb_device_class_config_t usb_asix_class;
|
||||
|
||||
#endif // ASIX_H
|
||||
14
usb/hid.c
14
usb/hid.c
@@ -56,7 +56,7 @@ static uint8_t hid_get_report_descr(usb_device_t *dev, uint8_t iface, uint16_t s
|
||||
uint8_t buf[size];
|
||||
usb_hid_info_t *info = &(dev->hid_info);
|
||||
uint8_t rcode = usb_ctrl_req( dev, HID_REQ_HIDREPORT, USB_REQUEST_GET_DESCRIPTOR, 0x00,
|
||||
HID_DESCRIPTOR_REPORT, iface, size, size, buf, NULL);
|
||||
HID_DESCRIPTOR_REPORT, iface, size, buf);
|
||||
|
||||
if(!rcode) {
|
||||
iprintf("HID report descriptor:\n");
|
||||
@@ -81,14 +81,14 @@ static uint8_t hid_set_idle(usb_device_t *dev, uint8_t iface, uint8_t reportID,
|
||||
iprintf("%s(%x, if=%d id=%d, dur=%d)\n", __FUNCTION__, dev->bAddress, iface, reportID, duration);
|
||||
|
||||
return( usb_ctrl_req( dev, HID_REQ_HIDOUT, HID_REQUEST_SET_IDLE, reportID,
|
||||
duration, iface, 0x0000, 0x0000, NULL, NULL ));
|
||||
duration, iface, 0x0000, NULL));
|
||||
}
|
||||
|
||||
static uint8_t hid_set_protocol(usb_device_t *dev, uint8_t iface, uint8_t protocol) {
|
||||
iprintf("%s(%x, if=%d proto=%d)\n", __FUNCTION__, dev->bAddress, iface, protocol);
|
||||
|
||||
return( usb_ctrl_req( dev, HID_REQ_HIDOUT, HID_REQUEST_SET_PROTOCOL, protocol,
|
||||
0x00, iface, 0x0000, 0x0000, NULL, NULL ));
|
||||
0x00, iface, 0x0000, NULL));
|
||||
}
|
||||
|
||||
static uint8_t hid_set_report(usb_device_t *dev, uint8_t iface, uint8_t report_type, uint8_t report_id,
|
||||
@@ -96,7 +96,7 @@ static uint8_t hid_set_report(usb_device_t *dev, uint8_t iface, uint8_t report_t
|
||||
// iprintf("%s(%x, if=%d data=%x)\n", __FUNCTION__, dev->bAddress, iface, dataptr[0]);
|
||||
|
||||
return( usb_ctrl_req(dev, HID_REQ_HIDOUT, HID_REQUEST_SET_REPORT, report_id,
|
||||
report_type, iface, nbytes, nbytes, dataptr, NULL ));
|
||||
report_type, iface, nbytes, dataptr));
|
||||
}
|
||||
|
||||
/* todo: handle parsing in chunks */
|
||||
@@ -121,7 +121,6 @@ static uint8_t usb_hid_parse_conf(usb_device_t *dev, uint8_t conf, uint16_t len)
|
||||
/* scan through all descriptors */
|
||||
p = &buf;
|
||||
while(len > 0) {
|
||||
|
||||
switch(p->conf_desc.bDescriptorType) {
|
||||
case USB_DESCRIPTOR_CONFIGURATION:
|
||||
iprintf("conf descriptor size %d\n", p->conf_desc.bLength);
|
||||
@@ -160,7 +159,6 @@ static uint8_t usb_hid_parse_conf(usb_device_t *dev, uint8_t conf, uint16_t len)
|
||||
case HID_PROTOCOL_KEYBOARD:
|
||||
iprintf("HID protocol is KEYBOARD\n");
|
||||
info->iface_info[info->bNumIfaces].device_type = HID_DEVICE_KEYBOARD;
|
||||
// hid_set_report(dev, info->iface_info[info->bNumIfaces].iface_idx, 2, 0, 1, &kbd_led_state);
|
||||
break;
|
||||
|
||||
case HID_PROTOCOL_MOUSE:
|
||||
@@ -226,8 +224,6 @@ static uint8_t usb_hid_parse_conf(usb_device_t *dev, uint8_t conf, uint16_t len)
|
||||
return USB_ERROR_CONFIGURAION_SIZE_MISMATCH;
|
||||
}
|
||||
|
||||
iprintf("done\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -372,7 +368,7 @@ static uint8_t usb_hid_poll(usb_device_t *dev) {
|
||||
// iprintf("poll %d...\n", info->ep[i].epAddr);
|
||||
|
||||
uint16_t read = info->ep[i].maxPktSize;
|
||||
uint8_t buf[32];
|
||||
uint8_t buf[info->ep[i].maxPktSize];
|
||||
uint8_t rcode =
|
||||
usb_in_transfer(dev, &(info->ep[i]), &read, buf);
|
||||
|
||||
|
||||
@@ -153,7 +153,7 @@ bool parse_report_descriptor(uint8_t *rep, uint16_t rep_size) {
|
||||
for(c=0;c<2;c++) {
|
||||
if(axis[c] >= 0) {
|
||||
uint16_t cnt = bit_count + report_size * axis[c];
|
||||
hidp_debugf("%c-AXIS @ %d (byte %d)\n", 'X'+c,
|
||||
hidp_debugf(" (%c-AXIS @ %d (byte %d))\n", 'X'+c,
|
||||
cnt, cnt/8);
|
||||
|
||||
// only 8 bit axes at byte boundaries are supported for
|
||||
@@ -194,6 +194,7 @@ bool parse_report_descriptor(uint8_t *rep, uint16_t rep_size) {
|
||||
case 10:
|
||||
hidp_extreme_debugf("COLLECTION(%d)\n", value);
|
||||
collection_depth++;
|
||||
usage_count = 0;
|
||||
|
||||
if(value == 1) { // app collection
|
||||
hidp_extreme_debugf(" -> application\n");
|
||||
@@ -335,9 +336,7 @@ bool parse_report_descriptor(uint8_t *rep, uint16_t rep_size) {
|
||||
|
||||
hidp_debugf(" -> Pointer\n");
|
||||
|
||||
} else if((value == USAGE_X || value == USAGE_Y ||
|
||||
value == USAGE_Z || value == USAGE_WHEEL) &&
|
||||
app_collection) {
|
||||
} else if((value == USAGE_X || value == USAGE_Y) && app_collection) {
|
||||
// usage(x) and usage(y) are allowed within the app collection
|
||||
hidp_extreme_debugf(" -> axis usage\n");
|
||||
|
||||
|
||||
24
usb/hub.c
24
usb/hub.c
@@ -5,32 +5,31 @@
|
||||
|
||||
static uint8_t usb_hub_clear_hub_feature(usb_device_t *dev, uint8_t fid ) {
|
||||
return( usb_ctrl_req( dev, USB_HUB_REQ_CLEAR_HUB_FEATURE,
|
||||
USB_REQUEST_CLEAR_FEATURE, fid, 0, 0, 0, 0, NULL, NULL ));
|
||||
USB_REQUEST_CLEAR_FEATURE, fid, 0, 0, 0, NULL));
|
||||
}
|
||||
|
||||
// Clear Port Feature
|
||||
static uint8_t usb_hub_clear_port_feature(usb_device_t *dev, uint8_t fid, uint8_t port, uint8_t sel ) {
|
||||
return( usb_ctrl_req( dev , USB_HUB_REQ_CLEAR_PORT_FEATURE,
|
||||
USB_REQUEST_CLEAR_FEATURE, fid, 0, ((0x0000|port)|(sel<<8)), 0, 0, NULL, NULL ));
|
||||
USB_REQUEST_CLEAR_FEATURE, fid, 0, ((0x0000|port)|(sel<<8)), 0, NULL));
|
||||
}
|
||||
// Get Hub Descriptor
|
||||
static uint8_t usb_hub_get_hub_descriptor(usb_device_t *dev, uint8_t index,
|
||||
uint16_t nbytes, usb_hub_descriptor_t *dataptr ) {
|
||||
return( usb_ctrl_req( dev, USB_HUB_REQ_GET_HUB_DESCRIPTOR,
|
||||
USB_REQUEST_GET_DESCRIPTOR, index, 0x29, 0, nbytes, nbytes,
|
||||
(uint8_t*)dataptr, NULL ));
|
||||
USB_REQUEST_GET_DESCRIPTOR, index, 0x29, 0, nbytes, (uint8_t*)dataptr));
|
||||
}
|
||||
|
||||
// Set Port Feature
|
||||
static uint8_t usb_hub_set_port_feature(usb_device_t *dev, uint8_t fid, uint8_t port, uint8_t sel ) {
|
||||
return( usb_ctrl_req( dev, USB_HUB_REQ_SET_PORT_FEATURE,
|
||||
USB_REQUEST_SET_FEATURE, fid, 0, (((0x0000|sel)<<8)|port), 0, 0, NULL, NULL ));
|
||||
USB_REQUEST_SET_FEATURE, fid, 0, (((0x0000|sel)<<8)|port), 0, NULL));
|
||||
}
|
||||
|
||||
// Get Port Status
|
||||
static uint8_t usb_hub_get_port_status(usb_device_t *dev, uint8_t port, uint16_t nbytes, uint8_t* dataptr ) {
|
||||
return( usb_ctrl_req( dev, USB_HUB_REQ_GET_PORT_STATUS,
|
||||
USB_REQUEST_GET_STATUS, 0, 0, port, nbytes, nbytes, dataptr, NULL ));
|
||||
USB_REQUEST_GET_STATUS, 0, 0, port, nbytes, dataptr));
|
||||
}
|
||||
|
||||
static uint8_t usb_hub_init(usb_device_t *dev) {
|
||||
@@ -209,7 +208,8 @@ static uint8_t usb_hub_check_hub_status(usb_device_t *dev, uint8_t ports) {
|
||||
uint8_t buf[8];
|
||||
uint16_t read = 1;
|
||||
|
||||
// iprintf("%s(addr=%x)\n", __FUNCTION__, addr);
|
||||
// iprintf("%s(addr=%x)\n", __FUNCTION__, dev->bAddress);
|
||||
|
||||
rcode = usb_in_transfer(dev, &(info->ep), &read, buf);
|
||||
if(rcode)
|
||||
return rcode;
|
||||
@@ -219,13 +219,11 @@ static uint8_t usb_hub_check_hub_status(usb_device_t *dev, uint8_t ports) {
|
||||
if (buf[0] & mask) {
|
||||
hub_event_t evt;
|
||||
evt.bmEvent = 0;
|
||||
|
||||
// TODO XXXX: try sizeof(evt.evtBuff)
|
||||
rcode = usb_hub_get_port_status(dev, port, 4, evt.evtBuff);
|
||||
|
||||
|
||||
rcode = usb_hub_get_port_status(dev, port, sizeof(evt.evtBuff), evt.evtBuff);
|
||||
if (rcode)
|
||||
continue;
|
||||
|
||||
|
||||
rcode = usb_hub_port_status_change(dev, port, evt);
|
||||
|
||||
if (rcode == HUB_ERROR_PORT_HAS_BEEN_RESET)
|
||||
@@ -241,7 +239,6 @@ static uint8_t usb_hub_check_hub_status(usb_device_t *dev, uint8_t ports) {
|
||||
evt.bmEvent = 0;
|
||||
|
||||
rcode = usb_hub_get_port_status(dev, port, 4, evt.evtBuff);
|
||||
|
||||
if (rcode)
|
||||
continue;
|
||||
|
||||
@@ -252,7 +249,6 @@ static uint8_t usb_hub_check_hub_status(usb_device_t *dev, uint8_t ports) {
|
||||
evt.bmChange |= USB_HUB_PORT_STATUS_PORT_CONNECTION;
|
||||
|
||||
rcode = usb_hub_port_status_change(dev, port, evt);
|
||||
|
||||
if (rcode == HUB_ERROR_PORT_HAS_BEEN_RESET)
|
||||
return 0;
|
||||
|
||||
|
||||
48
usb/mii.h
Normal file
48
usb/mii.h
Normal file
@@ -0,0 +1,48 @@
|
||||
#ifndef MII_H
|
||||
#define MII_H
|
||||
|
||||
/* Generic MII registers. */
|
||||
#define MII_BMCR 0x00 /* Basic mode control register */
|
||||
#define MII_BMSR 0x01 /* Basic mode status register */
|
||||
#define MII_PHYSID1 0x02 /* PHYS ID 1 */
|
||||
#define MII_PHYSID2 0x03 /* PHYS ID 2 */
|
||||
#define MII_ADVERTISE 0x04 /* Advertisement control reg */
|
||||
|
||||
/* Basic mode control register. */
|
||||
#define BMCR_RESV 0x003f /* Unused... */
|
||||
#define BMCR_SPEED1000 0x0040 /* MSB of Speed (1000) */
|
||||
#define BMCR_CTST 0x0080 /* Collision test */
|
||||
#define BMCR_FULLDPLX 0x0100 /* Full duplex */
|
||||
#define BMCR_ANRESTART 0x0200 /* Auto negotiation restart */
|
||||
#define BMCR_ISOLATE 0x0400 /* Disconnect DP83840 from MII */
|
||||
#define BMCR_PDOWN 0x0800 /* Powerdown the DP83840 */
|
||||
#define BMCR_ANENABLE 0x1000 /* Enable auto negotiation */
|
||||
#define BMCR_SPEED100 0x2000 /* Select 100Mbps */
|
||||
#define BMCR_LOOPBACK 0x4000 /* TXD loopback bits */
|
||||
#define BMCR_RESET 0x8000 /* Reset the DP83840 */
|
||||
|
||||
/* Advertisement control register. */
|
||||
#define ADVERTISE_SLCT 0x001f /* Selector bits */
|
||||
#define ADVERTISE_CSMA 0x0001 /* Only selector supported */
|
||||
#define ADVERTISE_10HALF 0x0020 /* Try for 10mbps half-duplex */
|
||||
#define ADVERTISE_1000XFULL 0x0020 /* Try for 1000BASE-X full-duplex */
|
||||
#define ADVERTISE_10FULL 0x0040 /* Try for 10mbps full-duplex */
|
||||
#define ADVERTISE_1000XHALF 0x0040 /* Try for 1000BASE-X half-duplex */
|
||||
#define ADVERTISE_100HALF 0x0080 /* Try for 100mbps half-duplex */
|
||||
#define ADVERTISE_1000XPAUSE 0x0080 /* Try for 1000BASE-X pause */
|
||||
#define ADVERTISE_100FULL 0x0100 /* Try for 100mbps full-duplex */
|
||||
#define ADVERTISE_1000XPSE_ASYM 0x0100 /* Try for 1000BASE-X asym pause */
|
||||
#define ADVERTISE_100BASE4 0x0200 /* Try for 100mbps 4k packets */
|
||||
#define ADVERTISE_PAUSE_CAP 0x0400 /* Try for pause */
|
||||
#define ADVERTISE_PAUSE_ASYM 0x0800 /* Try for asymetric pause */
|
||||
#define ADVERTISE_RESV 0x1000 /* Unused... */
|
||||
#define ADVERTISE_RFAULT 0x2000 /* Say we can detect faults */
|
||||
#define ADVERTISE_LPACK 0x4000 /* Ack link partners response */
|
||||
#define ADVERTISE_NPAGE 0x8000 /* Next page bit */
|
||||
|
||||
#define ADVERTISE_FULL (ADVERTISE_100FULL | ADVERTISE_10FULL | \
|
||||
ADVERTISE_CSMA)
|
||||
#define ADVERTISE_ALL (ADVERTISE_10HALF | ADVERTISE_10FULL | \
|
||||
ADVERTISE_100HALF | ADVERTISE_100FULL)
|
||||
|
||||
#endif // MII_H
|
||||
50
usb/usb.c
50
usb/usb.c
@@ -278,8 +278,7 @@ uint8_t usb_OutTransfer(ep_t *pep, uint16_t nak_limit,
|
||||
|
||||
uint8_t usb_ctrl_req(usb_device_t *dev, uint8_t bmReqType,
|
||||
uint8_t bRequest, uint8_t wValLo, uint8_t wValHi,
|
||||
uint16_t wInd, uint16_t total, uint16_t nbytes,
|
||||
uint8_t* dataptr, usb_parser_t *p) {
|
||||
uint16_t wInd, uint16_t nbytes, uint8_t* dataptr) {
|
||||
iprintf("%s(addr=%x, len=%d, ptr=%p)\n", __FUNCTION__,
|
||||
dev->bAddress, nbytes, dataptr);
|
||||
bool direction = false; //request direction, IN or OUT
|
||||
@@ -299,7 +298,7 @@ uint8_t usb_ctrl_req(usb_device_t *dev, uint8_t bmReqType,
|
||||
setup_pkt.wVal_u.wValueLo = wValLo;
|
||||
setup_pkt.wVal_u.wValueHi = wValHi;
|
||||
setup_pkt.wIndex = wInd;
|
||||
setup_pkt.wLength = total;
|
||||
setup_pkt.wLength = nbytes;
|
||||
|
||||
// transfer to setup packet FIFO
|
||||
max3421e_write(MAX3421E_SUDFIFO, sizeof(setup_pkt_t), (uint8_t*)&setup_pkt );
|
||||
@@ -311,39 +310,15 @@ uint8_t usb_ctrl_req(usb_device_t *dev, uint8_t bmReqType,
|
||||
// data stage, if present
|
||||
if( dataptr != NULL ) {
|
||||
if( direction ) { //IN transfer
|
||||
uint16_t left = total;
|
||||
|
||||
dev->ep0.bmRcvToggle = 1; //bmRCVTOG1;
|
||||
|
||||
while (left) {
|
||||
// Bytes read into buffer
|
||||
uint16_t read = nbytes;
|
||||
//uint16_t read = (left<nbytes) ? left : nbytes;
|
||||
|
||||
rcode = usb_InTransfer( &(dev->ep0), nak_limit, &read, dataptr );
|
||||
|
||||
if (rcode)
|
||||
return rcode;
|
||||
|
||||
// Invoke callback function if inTransfer completed
|
||||
// successfuly and callback function pointer is specified
|
||||
if (!rcode && p)
|
||||
(*p)(read, dataptr, total - left);
|
||||
|
||||
left -= read;
|
||||
|
||||
if (read < nbytes)
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
//OUT transfer
|
||||
dev->ep0.bmRcvToggle = 1;
|
||||
rcode = usb_InTransfer( &(dev->ep0), nak_limit, &nbytes, dataptr );
|
||||
} else { //OUT transfer
|
||||
dev->ep0.bmSndToggle = 1;
|
||||
rcode = usb_OutTransfer( &(dev->ep0), nak_limit, nbytes, dataptr );
|
||||
}
|
||||
|
||||
//return error
|
||||
if( rcode )
|
||||
return( rcode );
|
||||
if( rcode ) return( rcode );
|
||||
}
|
||||
|
||||
// Status stage
|
||||
@@ -355,6 +330,7 @@ uint8_t usb_ctrl_req(usb_device_t *dev, uint8_t bmReqType,
|
||||
static const usb_device_class_config_t *class_list[] = {
|
||||
&usb_hub_class,
|
||||
&usb_hid_class,
|
||||
&usb_asix_class,
|
||||
NULL
|
||||
};
|
||||
|
||||
@@ -465,7 +441,7 @@ void usb_poll() {
|
||||
// poll all configured devices
|
||||
uint8_t i;
|
||||
for (i=0; i<USB_NUMDEVICES; i++)
|
||||
if(dev[i].bAddress)
|
||||
if(dev[i].bAddress && dev[i].class)
|
||||
rcode = dev[i].class->poll(dev+i);
|
||||
|
||||
switch( usb_task_state ) {
|
||||
@@ -474,7 +450,7 @@ void usb_poll() {
|
||||
|
||||
// just remove everything ...
|
||||
for (i=0; i<USB_NUMDEVICES; i++) {
|
||||
if (dev[i].bAddress) {
|
||||
if(dev[i].bAddress && dev[i].class) {
|
||||
rcode = dev[i].class->release(dev+i);
|
||||
dev[i].bAddress = 0;
|
||||
}
|
||||
@@ -556,21 +532,21 @@ uint8_t usb_release_device(uint8_t parent, uint8_t port) {
|
||||
|
||||
uint8_t usb_get_dev_descr( usb_device_t *dev, uint16_t nbytes, usb_device_descriptor_t* p ) {
|
||||
return( usb_ctrl_req( dev, USB_REQ_GET_DESCR, USB_REQUEST_GET_DESCRIPTOR,
|
||||
0x00, USB_DESCRIPTOR_DEVICE, 0x0000, nbytes, nbytes, (uint8_t*)p, NULL ));
|
||||
0x00, USB_DESCRIPTOR_DEVICE, 0x0000, nbytes, (uint8_t*)p));
|
||||
}
|
||||
|
||||
//get configuration descriptor
|
||||
uint8_t usb_get_conf_descr( usb_device_t *dev, uint16_t nbytes,
|
||||
uint8_t conf, usb_configuration_descriptor_t* p ) {
|
||||
return( usb_ctrl_req( dev, USB_REQ_GET_DESCR, USB_REQUEST_GET_DESCRIPTOR,
|
||||
conf, USB_DESCRIPTOR_CONFIGURATION, 0x0000, nbytes, nbytes, (uint8_t*)p, NULL ));
|
||||
conf, USB_DESCRIPTOR_CONFIGURATION, 0x0000, nbytes, (uint8_t*)p));
|
||||
}
|
||||
|
||||
uint8_t usb_set_addr( usb_device_t *dev, uint8_t newaddr ) {
|
||||
iprintf("%s(new=%x)\n", __FUNCTION__, newaddr);
|
||||
|
||||
uint8_t rcode = usb_ctrl_req( dev, USB_REQ_SET, USB_REQUEST_SET_ADDRESS, newaddr,
|
||||
0x00, 0x0000, 0x0000, 0x0000, NULL, NULL );
|
||||
0x00, 0x0000, 0x0000, NULL);
|
||||
if(!rcode) dev->bAddress = newaddr;
|
||||
return rcode;
|
||||
}
|
||||
@@ -578,7 +554,7 @@ uint8_t usb_set_addr( usb_device_t *dev, uint8_t newaddr ) {
|
||||
//set configuration
|
||||
uint8_t usb_set_conf( usb_device_t *dev, uint8_t conf_value ) {
|
||||
return( usb_ctrl_req( dev, USB_REQ_SET, USB_REQUEST_SET_CONFIGURATION,
|
||||
conf_value, 0x00, 0x0000, 0x0000, 0x0000, NULL, NULL ));
|
||||
conf_value, 0x00, 0x0000, 0x0000, NULL));
|
||||
}
|
||||
|
||||
void usb_SetHubPreMask() {
|
||||
|
||||
@@ -95,6 +95,7 @@ typedef struct {
|
||||
|
||||
#include "hub.h"
|
||||
#include "hid.h"
|
||||
#include "asix.h"
|
||||
|
||||
// entry used for list of connected devices
|
||||
typedef struct usb_device_entry {
|
||||
@@ -108,6 +109,7 @@ typedef struct usb_device_entry {
|
||||
union {
|
||||
usb_hub_info_t hub_info;
|
||||
usb_hid_info_t hid_info;
|
||||
usb_asix_info_t asix_info;
|
||||
};
|
||||
} usb_device_t;
|
||||
|
||||
@@ -228,8 +230,6 @@ typedef struct {
|
||||
#define USB_DESCRIPTOR_OTHER_SPEED 0x07 // bDescriptorType for a Other Speed Configuration.
|
||||
#define USB_DESCRIPTOR_INTERFACE_POWER 0x08 // bDescriptorType for Interface Power.
|
||||
|
||||
typedef void(*usb_parser_t)(const uint16_t, const uint8_t *, const uint16_t);
|
||||
|
||||
void usb_init();
|
||||
void usb_poll();
|
||||
void usb_SetHubPreMask(void);
|
||||
@@ -238,8 +238,7 @@ void usb_ResetHubPreMask(void);
|
||||
uint8_t usb_set_addr( usb_device_t *, uint8_t );
|
||||
uint8_t usb_ctrl_req( usb_device_t *, uint8_t bmReqType,
|
||||
uint8_t bRequest, uint8_t wValLo, uint8_t wValHi,
|
||||
uint16_t wInd, uint16_t total, uint16_t nbytes,
|
||||
uint8_t* dataptr, usb_parser_t *p);
|
||||
uint16_t wInd, uint16_t nbytes, uint8_t* dataptr);
|
||||
uint8_t usb_get_dev_descr( usb_device_t *, uint16_t nbytes, usb_device_descriptor_t* dataptr );
|
||||
uint8_t usb_get_conf_descr( usb_device_t *, uint16_t nbytes, uint8_t conf, usb_configuration_descriptor_t* dataptr );
|
||||
uint8_t usb_set_conf( usb_device_t *dev, uint8_t conf_value );
|
||||
|
||||
Reference in New Issue
Block a user