Skip to content

Commit 4652de4

Browse files
committed
USBHost: adapt to internal FS Hub
1 parent 64433f3 commit 4652de4

File tree

11 files changed

+597
-44
lines changed

11 files changed

+597
-44
lines changed

libraries/USBHOST/examples/KeyboardController/KeyboardController.ino

+2-1
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,8 @@ static const tusbh_class_reg_t class_table[] = {
9595
void setup()
9696
{
9797
Serial1.begin(115200);
98-
usb.Init(class_table);
98+
usb.Init(USB_CORE_ID_HS, class_table);
99+
//usb.Init(USB_CORE_ID_FS, class_table);
99100
}
100101

101102
void loop() {

libraries/USBHOST/examples/Shell/Shell.ino

+5-10
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
SOFTWARE.
3333
*/
3434

35-
#include "USBHOST.h"
35+
#include "USBHost.h"
3636

3737
extern "C" {
3838
#include "teeny_usb.h"
@@ -60,14 +60,6 @@ extern "C" {
6060
" |___/ \n"
6161

6262

63-
extern "C" {
64-
// host need accurate delay
65-
void tusb_delay_ms(uint32_t ms)
66-
{
67-
delayMicroseconds(ms*1000);
68-
}
69-
}
70-
7163
static int process_key(tusbh_ep_info_t* ep, const uint8_t* key);
7264

7365
static tusbh_root_hub_t root_fs;
@@ -276,6 +268,7 @@ static void command_loop(void)
276268
}
277269

278270
#include "usb_phy_api.h"
271+
#include "Wire.h"
279272

280273
tusbh_msg_q_t* mq;
281274

@@ -284,7 +277,7 @@ void setup()
284277
Serial1.begin(115200);
285278
printf("\n" TEENYUSB_LOGO PROMPT);
286279

287-
get_usb_phy()->deinit();
280+
//get_usb_phy()->deinit();
288281

289282
mq = tusbh_mq_create();
290283
tusbh_mq_init(mq);
@@ -315,6 +308,8 @@ void setup()
315308
hs = 0;
316309
#endif
317310

311+
start_hub();
312+
318313
//usb_fakeirq.start(mbed::callback(usb_irq_thread));
319314

320315
//NVIC_DisableIRQ(OTG_HS_IRQn);
+126
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
#define u8 uint8_t
2+
#define u16 uint16_t
3+
4+
/* Internal Register Set Addresses & Default Values acc. to DS00001692C */
5+
#define USB251XB_ADDR_VENDOR_ID_LSB 0x00
6+
#define USB251XB_ADDR_VENDOR_ID_MSB 0x01
7+
#define USB251XB_DEF_VENDOR_ID 0x0424
8+
9+
#define USB251XB_ADDR_PRODUCT_ID_LSB 0x02
10+
#define USB251XB_ADDR_PRODUCT_ID_MSB 0x03
11+
12+
#define USB251XB_ADDR_DEVICE_ID_LSB 0x04
13+
#define USB251XB_ADDR_DEVICE_ID_MSB 0x05
14+
#define USB251XB_DEF_DEVICE_ID 0x0BB3
15+
16+
#define USB251XB_ADDR_CONFIG_DATA_1 0x06
17+
#define USB251XB_DEF_CONFIG_DATA_1 0x9B
18+
#define USB251XB_ADDR_CONFIG_DATA_2 0x07
19+
#define USB251XB_DEF_CONFIG_DATA_2 0x20
20+
#define USB251XB_ADDR_CONFIG_DATA_3 0x08
21+
#define USB251XB_DEF_CONFIG_DATA_3 0x02
22+
23+
#define USB251XB_ADDR_NON_REMOVABLE_DEVICES 0x09
24+
#define USB251XB_DEF_NON_REMOVABLE_DEVICES 0x00
25+
26+
#define USB251XB_ADDR_PORT_DISABLE_SELF 0x0A
27+
#define USB251XB_DEF_PORT_DISABLE_SELF 0x00
28+
#define USB251XB_ADDR_PORT_DISABLE_BUS 0x0B
29+
#define USB251XB_DEF_PORT_DISABLE_BUS 0x00
30+
31+
#define USB251XB_ADDR_MAX_POWER_SELF 0x0C
32+
#define USB251XB_DEF_MAX_POWER_SELF 0x01
33+
#define USB251XB_ADDR_MAX_POWER_BUS 0x0D
34+
#define USB251XB_DEF_MAX_POWER_BUS 0x32
35+
36+
#define USB251XB_ADDR_MAX_CURRENT_SELF 0x0E
37+
#define USB251XB_DEF_MAX_CURRENT_SELF 0x01
38+
#define USB251XB_ADDR_MAX_CURRENT_BUS 0x0F
39+
#define USB251XB_DEF_MAX_CURRENT_BUS 0x32
40+
41+
#define USB251XB_ADDR_POWER_ON_TIME 0x10
42+
#define USB251XB_DEF_POWER_ON_TIME 0x32
43+
44+
#define USB251XB_ADDR_LANGUAGE_ID_HIGH 0x11
45+
#define USB251XB_ADDR_LANGUAGE_ID_LOW 0x12
46+
#define USB251XB_DEF_LANGUAGE_ID 0x0000
47+
48+
#define USB251XB_STRING_BUFSIZE 62
49+
#define USB251XB_ADDR_MANUFACTURER_STRING_LEN 0x13
50+
#define USB251XB_ADDR_MANUFACTURER_STRING 0x16
51+
#define USB251XB_DEF_MANUFACTURER_STRING "Microchip"
52+
53+
#define USB251XB_ADDR_PRODUCT_STRING_LEN 0x14
54+
#define USB251XB_ADDR_PRODUCT_STRING 0x54
55+
56+
#define USB251XB_ADDR_SERIAL_STRING_LEN 0x15
57+
#define USB251XB_ADDR_SERIAL_STRING 0x92
58+
#define USB251XB_DEF_SERIAL_STRING ""
59+
60+
#define USB251XB_ADDR_BATTERY_CHARGING_ENABLE 0xD0
61+
#define USB251XB_DEF_BATTERY_CHARGING_ENABLE 0x00
62+
63+
#define USB251XB_ADDR_BOOST_UP 0xF6
64+
#define USB251XB_DEF_BOOST_UP 0x00
65+
#define USB251XB_ADDR_BOOST_57 0xF7
66+
#define USB251XB_DEF_BOOST_57 0x00
67+
#define USB251XB_ADDR_BOOST_14 0xF8
68+
#define USB251XB_DEF_BOOST_14 0x00
69+
70+
#define USB251XB_ADDR_PORT_SWAP 0xFA
71+
#define USB251XB_DEF_PORT_SWAP 0x00
72+
73+
#define USB251XB_ADDR_PORT_MAP_12 0xFB
74+
#define USB251XB_DEF_PORT_MAP_12 0x00
75+
#define USB251XB_ADDR_PORT_MAP_34 0xFC
76+
#define USB251XB_DEF_PORT_MAP_34 0x00 /* USB251{3B/i,4B/i,7/i} only */
77+
#define USB251XB_ADDR_PORT_MAP_56 0xFD
78+
#define USB251XB_DEF_PORT_MAP_56 0x00 /* USB2517/i only */
79+
#define USB251XB_ADDR_PORT_MAP_7 0xFE
80+
#define USB251XB_DEF_PORT_MAP_7 0x00 /* USB2517/i only */
81+
82+
#define USB251XB_ADDR_STATUS_COMMAND 0xFF
83+
#define USB251XB_STATUS_COMMAND_SMBUS_DOWN 0x04
84+
#define USB251XB_STATUS_COMMAND_RESET 0x02
85+
#define USB251XB_STATUS_COMMAND_ATTACH 0x01
86+
87+
#define USB251XB_I2C_REG_SZ 0x100
88+
#define USB251XB_I2C_WRITE_SZ 0x10
89+
90+
#define DRIVER_NAME "usb251xb"
91+
#define DRIVER_DESC "Microchip USB 2.0 Hi-Speed Hub Controller"
92+
93+
struct usb251xb {
94+
u8 skip_config;
95+
u16 vendor_id;
96+
u16 product_id;
97+
u16 device_id;
98+
u8 conf_data1;
99+
u8 conf_data2;
100+
u8 conf_data3;
101+
u8 non_rem_dev;
102+
u8 port_disable_sp;
103+
u8 port_disable_bp;
104+
u8 max_power_sp;
105+
u8 max_power_bp;
106+
u8 max_current_sp;
107+
u8 max_current_bp;
108+
u8 power_on_time;
109+
u16 lang_id;
110+
u8 manufacturer_len;
111+
u8 product_len;
112+
u8 serial_len;
113+
char manufacturer[USB251XB_STRING_BUFSIZE];
114+
char product[USB251XB_STRING_BUFSIZE];
115+
char serial[USB251XB_STRING_BUFSIZE];
116+
u8 bat_charge_en;
117+
u8 boost_up;
118+
u8 boost_57;
119+
u8 boost_14;
120+
u8 port_swap;
121+
u8 port_map12;
122+
u8 port_map34;
123+
u8 port_map56;
124+
u8 port_map7;
125+
u8 status;
126+
};
+149
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
#include "Wire.h"
2+
#include "hub.h"
3+
4+
struct usb251xb hub;
5+
6+
void start_hub() {
7+
configure_hub(&hub);
8+
write_hub_configuration(&hub);
9+
}
10+
11+
void configure_hub(struct usb251xb* hub) {
12+
hub->vendor_id = USB251XB_DEF_VENDOR_ID;
13+
hub->product_id = 0x2512;
14+
hub->device_id = USB251XB_DEF_DEVICE_ID;
15+
hub->conf_data1 = USB251XB_DEF_CONFIG_DATA_1;
16+
#if 0
17+
if (of_get_property(np, "self-powered", NULL)) {
18+
hub->conf_data1 |= BIT(7);
19+
20+
/* Configure Over-Current sens when self-powered */
21+
hub->conf_data1 &= ~BIT(2);
22+
if (of_get_property(np, "ganged-sensing", NULL))
23+
hub->conf_data1 &= ~BIT(1);
24+
else if (of_get_property(np, "individual-sensing", NULL))
25+
hub->conf_data1 |= BIT(1);
26+
} else if (of_get_property(np, "bus-powered", NULL)) {
27+
hub->conf_data1 &= ~BIT(7);
28+
29+
/* Disable Over-Current sense when bus-powered */
30+
hub->conf_data1 |= BIT(2);
31+
}
32+
if (of_get_property(np, "disable-hi-speed", NULL))
33+
hub->conf_data1 |= BIT(5);
34+
35+
if (of_get_property(np, "multi-tt", NULL))
36+
hub->conf_data1 |= BIT(4);
37+
else if (of_get_property(np, "single-tt", NULL))
38+
hub->conf_data1 &= ~BIT(4);
39+
40+
if (of_get_property(np, "disable-eop", NULL))
41+
hub->conf_data1 |= BIT(3);
42+
43+
if (of_get_property(np, "individual-port-switching", NULL))
44+
hub->conf_data1 |= BIT(0);
45+
else if (of_get_property(np, "ganged-port-switching", NULL))
46+
hub->conf_data1 &= ~BIT(0);
47+
#else
48+
hub->conf_data1 |= (1 << 7);
49+
hub->conf_data1 |= (1 << 5);
50+
hub->conf_data1 &= ~(1 << 2);
51+
#endif
52+
hub->conf_data2 = USB251XB_DEF_CONFIG_DATA_2;
53+
hub->conf_data3 = USB251XB_DEF_CONFIG_DATA_3;
54+
hub->non_rem_dev = USB251XB_DEF_NON_REMOVABLE_DEVICES;
55+
hub->port_disable_sp = USB251XB_DEF_PORT_DISABLE_SELF;
56+
hub->port_disable_bp = USB251XB_DEF_PORT_DISABLE_BUS;
57+
hub->max_power_sp = USB251XB_DEF_MAX_POWER_SELF;
58+
hub->max_power_bp = USB251XB_DEF_MAX_POWER_BUS;
59+
hub->max_current_sp = USB251XB_DEF_MAX_CURRENT_SELF;
60+
hub->max_current_bp = USB251XB_DEF_MAX_CURRENT_BUS;
61+
hub->power_on_time = USB251XB_DEF_POWER_ON_TIME;
62+
hub->lang_id = USB251XB_DEF_LANGUAGE_ID;
63+
hub->port_swap = USB251XB_DEF_PORT_SWAP;
64+
hub->bat_charge_en = USB251XB_DEF_BATTERY_CHARGING_ENABLE;
65+
hub->bat_charge_en |= (0xF << 1);
66+
hub->boost_up = USB251XB_DEF_BOOST_UP;
67+
hub->boost_57 = USB251XB_DEF_BOOST_57;
68+
hub->boost_14 = USB251XB_DEF_BOOST_14;
69+
hub->port_map12 = USB251XB_DEF_PORT_MAP_12;
70+
hub->port_map34 = USB251XB_DEF_PORT_MAP_34;
71+
hub->port_map56 = USB251XB_DEF_PORT_MAP_56;
72+
hub->port_map7 = USB251XB_DEF_PORT_MAP_7;
73+
}
74+
75+
76+
void write_hub_configuration(struct usb251xb* hub) {
77+
char i2c_wb[USB251XB_I2C_REG_SZ];
78+
memset(i2c_wb, 0, USB251XB_I2C_REG_SZ);
79+
80+
i2c_wb[USB251XB_ADDR_VENDOR_ID_MSB] = (hub->vendor_id >> 8) & 0xFF;
81+
i2c_wb[USB251XB_ADDR_VENDOR_ID_LSB] = hub->vendor_id & 0xFF;
82+
i2c_wb[USB251XB_ADDR_PRODUCT_ID_MSB] = (hub->product_id >> 8) & 0xFF;
83+
i2c_wb[USB251XB_ADDR_PRODUCT_ID_LSB] = hub->product_id & 0xFF;
84+
i2c_wb[USB251XB_ADDR_DEVICE_ID_MSB] = (hub->device_id >> 8) & 0xFF;
85+
i2c_wb[USB251XB_ADDR_DEVICE_ID_LSB] = hub->device_id & 0xFF;
86+
i2c_wb[USB251XB_ADDR_CONFIG_DATA_1] = hub->conf_data1;
87+
i2c_wb[USB251XB_ADDR_CONFIG_DATA_2] = hub->conf_data2;
88+
i2c_wb[USB251XB_ADDR_CONFIG_DATA_3] = hub->conf_data3;
89+
i2c_wb[USB251XB_ADDR_NON_REMOVABLE_DEVICES] = hub->non_rem_dev;
90+
i2c_wb[USB251XB_ADDR_PORT_DISABLE_SELF] = hub->port_disable_sp;
91+
i2c_wb[USB251XB_ADDR_PORT_DISABLE_BUS] = hub->port_disable_bp;
92+
i2c_wb[USB251XB_ADDR_MAX_POWER_SELF] = hub->max_power_sp;
93+
i2c_wb[USB251XB_ADDR_MAX_POWER_BUS] = hub->max_power_bp;
94+
i2c_wb[USB251XB_ADDR_MAX_CURRENT_SELF] = hub->max_current_sp;
95+
i2c_wb[USB251XB_ADDR_MAX_CURRENT_BUS] = hub->max_current_bp;
96+
i2c_wb[USB251XB_ADDR_POWER_ON_TIME] = hub->power_on_time;
97+
i2c_wb[USB251XB_ADDR_LANGUAGE_ID_HIGH] = (hub->lang_id >> 8) & 0xFF;
98+
i2c_wb[USB251XB_ADDR_LANGUAGE_ID_LOW] = hub->lang_id & 0xFF;
99+
i2c_wb[USB251XB_ADDR_MANUFACTURER_STRING_LEN] = hub->manufacturer_len;
100+
i2c_wb[USB251XB_ADDR_PRODUCT_STRING_LEN] = hub->product_len;
101+
i2c_wb[USB251XB_ADDR_SERIAL_STRING_LEN] = hub->serial_len;
102+
memcpy(&i2c_wb[USB251XB_ADDR_MANUFACTURER_STRING], hub->manufacturer,
103+
USB251XB_STRING_BUFSIZE);
104+
memcpy(&i2c_wb[USB251XB_ADDR_SERIAL_STRING], hub->serial,
105+
USB251XB_STRING_BUFSIZE);
106+
memcpy(&i2c_wb[USB251XB_ADDR_PRODUCT_STRING], hub->product,
107+
USB251XB_STRING_BUFSIZE);
108+
i2c_wb[USB251XB_ADDR_BATTERY_CHARGING_ENABLE] = hub->bat_charge_en;
109+
i2c_wb[USB251XB_ADDR_BOOST_UP] = hub->boost_up;
110+
i2c_wb[USB251XB_ADDR_BOOST_57] = hub->boost_57;
111+
i2c_wb[USB251XB_ADDR_BOOST_14] = hub->boost_14;
112+
i2c_wb[USB251XB_ADDR_PORT_SWAP] = hub->port_swap;
113+
i2c_wb[USB251XB_ADDR_PORT_MAP_12] = hub->port_map12;
114+
i2c_wb[USB251XB_ADDR_PORT_MAP_34] = hub->port_map34;
115+
i2c_wb[USB251XB_ADDR_PORT_MAP_56] = hub->port_map56;
116+
i2c_wb[USB251XB_ADDR_PORT_MAP_7] = hub->port_map7;
117+
i2c_wb[USB251XB_ADDR_STATUS_COMMAND] = USB251XB_STATUS_COMMAND_ATTACH;
118+
119+
Wire.begin();
120+
Wire.setClock(100000);
121+
122+
if (hub->skip_config) {
123+
Wire.beginTransmission(0x2C);
124+
Wire.write(USB251XB_ADDR_STATUS_COMMAND);
125+
Wire.write(1);
126+
Wire.write(USB251XB_STATUS_COMMAND_ATTACH);
127+
Wire.endTransmission();
128+
return;
129+
}
130+
131+
for (int i = 0; i < (USB251XB_I2C_REG_SZ / USB251XB_I2C_WRITE_SZ); i++) {
132+
int offset = i * USB251XB_I2C_WRITE_SZ;
133+
uint8_t wbuf[USB251XB_I2C_WRITE_SZ + 1];
134+
135+
/* The first data byte transferred tells the hub how many data
136+
bytes will follow (byte count).
137+
*/
138+
wbuf[0] = USB251XB_I2C_WRITE_SZ;
139+
memcpy(&wbuf[1], &i2c_wb[offset], USB251XB_I2C_WRITE_SZ);
140+
141+
printf("writing %d byte block %d to 0x%02X\n",
142+
USB251XB_I2C_WRITE_SZ, i, offset);
143+
144+
Wire.beginTransmission(0x2C);
145+
Wire.write(offset);
146+
Wire.write(wbuf, USB251XB_I2C_WRITE_SZ + 1);
147+
Wire.endTransmission();
148+
}
149+
}

0 commit comments

Comments
 (0)