1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
diff --git a/firmware/export/config/sansafuze.h b/firmware/export/config/sansafuze.h
index 7e722d6..c85340f 100644
--- a/firmware/export/config/sansafuze.h
+++ b/firmware/export/config/sansafuze.h
@@ -186,13 +186,12 @@

 #ifndef BOOTLOADER

-#define USB_HANDLED_BY_OF
-
 /* USB On-the-go */
 #define CONFIG_USBOTG USBOTG_AS3525

 /* enable these for the experimental usb stack */
 #define HAVE_USBSTACK
+#define USE_ROCKBOX_USB
 #define USB_VENDOR_ID 0x0781
 #define USB_PRODUCT_ID 0x74c1

diff --git a/firmware/target/arm/as3525/system-as3525.c b/firmware/target/arm/as3525/system-as3525.c
index 4e1714b..6021556 100644
--- a/firmware/target/arm/as3525/system-as3525.c
+++ b/firmware/target/arm/as3525/system-as3525.c
@@ -113,6 +113,7 @@ struct vec_int_src vec_int_srcs[] =
     { INT_SRC_NAND, INT_NAND },
     { INT_SRC_I2C_AUDIO, INT_I2C_AUDIO },
     { INT_SRC_AUDIO, INT_AUDIO },
+    { INT_SRC_USB, INT_USB, },
 #ifdef HAVE_MULTIDRIVE
     { INT_SRC_MCI0, INT_MCI0 },
 #endif
@@ -263,11 +264,11 @@ void system_init(void)
     CGU_PLLA = AS3525_PLLA_SETTING;
     while(!(CGU_INTCTRL & (1<<0)));           /* wait until PLLA is locked */

-#if (AS3525_MCLK_SEL == AS3525_CLK_PLLB)
+//#if (AS3525_MCLK_SEL == AS3525_CLK_PLLB)
     CGU_PLLBSUP = 0;        /* enable PLLB */
     CGU_PLLB = AS3525_PLLB_SETTING;
     while(!(CGU_INTCTRL & (1<<1)));           /* wait until PLLB is locked */
-#endif
+//#endif

 #if CONFIG_CPU == AS3525
     /*  Set FCLK frequency */
diff --git a/firmware/target/arm/as3525/usb-drv-as3525.c b/firmware/target/arm/as3525/usb-drv-as3525.c
index 496d434..8bb6040 100644
--- a/firmware/target/arm/as3525/usb-drv-as3525.c
+++ b/firmware/target/arm/as3525/usb-drv-as3525.c
@@ -95,6 +95,33 @@
 #define USB_USER_CONF4          *((volatile unsigned long*) USB_BASE + 0x2020)
 #define USB_USER_CONF5          *((volatile unsigned long*) USB_BASE + 0x2024)

+
+/* register bits */
+
+/* write bits 31..16 */
+#define USB_GPIO_IDDIG_SEL              (1<<30)
+#define USB_GPIO_FS_DATA_EXT            (1<<29)
+#define USB_GPIO_FS_SE0_EXT             (1<<28)
+#define USB_GPIO_FS_XCVR_OWNER          (1<<27)
+#define USB_GPIO_TX_ENABLE_N            (1<<26)
+#define USB_GPIO_TX_BIT_STUFF_EN        (1<<25)
+#define USB_GPIO_BSESSVLD_EXT           (1<<24)
+#define USB_GPIO_ASESSVLD_EXT           (1<<23)
+#define USB_GPIO_VBUS_VLD_EXT           (1<<22)
+#define USB_GPIO_VBUS_VLD_EXT_SEL       (1<<21)
+#define USB_GPIO_XO_ON                  (1<<20)
+#define USB_GPIO_CLK_SEL11              (3<<18)
+#define USB_GPIO_CLK_SEL10              (2<<18)
+#define USB_GPIO_CLK_SEL01              (1<<18)
+#define USB_GPIO_CLK_SEL00              (0<<18)
+#define USB_GPIO_XO_EXT_CLK_ENBN        (1<<17)
+#define USB_GPIO_XO_REFCLK_ENB          (1<<16)
+/* readronly bits 15..0 */
+#define USB_GPIO_PHY_VBUSDRV            (1<<1)
+#define USB_GPIO_HS_INTR                (1<<0)
+
+
+
 struct usb_endpoint
 {
     void *buf;
@@ -121,76 +148,79 @@ void usb_drv_init(void)
     for(i = 0; i < USB_NUM_ENDPOINTS * 2; i++)
         endpoints[i].busy = false;

+    /* length regulator: normal operation */
     ascodec_write(AS3514_CVDD_DCDC3, ascodec_read(AS3514_CVDD_DCDC3) | 1<<2);
-    ascodec_write(AS3517_USB_UTIL, ascodec_read(AS3517_USB_UTIL) & ~(1<<4));
-
-    /* PHY part */
-    CGU_USB = 1<<5 /* enable */
-        | (CLK_DIV(AS3525_PLLA_FREQ, 48000000) / 2) << 2
-        | 1; /* source = PLLA */

     /* AHB part */
     CGU_PERI |= CGU_USB_CLOCK_ENABLE;

-    USB_GPIO_CSR = 0x6180000;
-    USB_DEV_CFG = (USB_DEV_CFG & ~3) | 1; /* full speed */
-    USB_DEV_CTRL |= 0x400; /* soft disconnect */
+    /* PHY part */
+    CGU_USB = 1<<5 /* enable */
+        | (CLK_DIV(AS3525_PLLB_FREQ, 48000000) / 2) << 2
+        | 2; /* source = PLLB */

-    /* UVDD */
+    /* UVDD on */
     ascodec_write(AS3517_USB_UTIL, ascodec_read(AS3517_USB_UTIL) | (1<<4));
-    sleep(10); //msleep(100)
+    sleep(HZ/10);

-    USB_GPIO_CSR = 0x6180000;
+    USB_GPIO_CSR = USB_GPIO_CLK_SEL10
+         | USB_GPIO_TX_BIT_STUFF_EN
+         | USB_GPIO_TX_ENABLE_N
+         | USB_GPIO_XO_ON
+         | USB_GPIO_IDDIG_SEL;

-    USB_GPIO_CSR |= 0x1C00000;
-    sleep(1); //msleep(3)
-    USB_GPIO_CSR |= 0x200000;
-    sleep(1); //msleep(10)
+    /* device init */

-    USB_DEV_CTRL |= 0x400; /* soft disconnect */
+    USB_DEV_EP_INTR_MASK = 0xffffffff;   /* unmask all flags */
+    USB_DEV_INTR_MASK = 0;

-    USB_GPIO_CSR &= ~0x1C00000;
-    sleep(1); //msleep(3)
-    USB_GPIO_CSR &= ~0x200000;
-    sleep(1); //msleep(10)
-    USB_DEV_CTRL &= ~0x400; /* clear soft disconnect */
+    USB_DEV_CFG = (1<<1) /* low speed */ |
+                  (0<<2)  /* remote wakeup */ |
+                  (1<<3)  /* self powered */ |
+                  (0<<5)  /* 16 bit phy */ |
+                  (1<<6)  /* bidir phy */ |
+                  (0<<17) /* csr prog */ ;

-#if defined(SANSA_CLIP)
-    GPIOA_DIR |= (1<<6);
-    GPIOA_PIN(6) = (1<<6);
-    GPIOA_DIR &= ~(1<<6);   /* restore direction for usb_detect() */
-#elif defined(SANSA_FUZE) || defined(SANSA_E200V2)
-    GPIOA_DIR |= (1<<3);
-    GPIOA_PIN(3) = (1<<3);
-    GPIOA_DIR &= ~(1<<3);   /* restore direction for usb_detect() */
-#elif defined(SANSA_C200V2)
-    GPIOA_DIR |= (1<<1);
-    GPIOA_PIN(1) = (1<<1);
-    GPIOA_DIR &= ~(1<<1);   /* restore direction for usb_detect() */
-#endif
+    USB_DEV_CTRL = (1<<8) /* burst control */ |
+                   (1<<4) /* descriptor update */ |
+                   (1<<2) /* dma */ |
+                   (1<<10) /* soft disconnect */ |
+                   (3 << 16) /* burst len  = 8 dwords */;

-#if 0 /* linux */
-    USB_DEV_CFG |= (1<<17)  /* csr programming */
-                |  (1<<3)   /* self powered */
-                |  (1<<2);  /* remote wakeup */
+    /* control endpoint setup (in/out) */
+    USB_IEP_CTRL(0) = USB_OEP_CTRL(0) = 0;

-    USB_DEV_CFG &= ~3; /* high speed */
-#endif
+    USB_IEP_CTRL(0) &= ~(3 << 4); /* control endpoint */
+    USB_OEP_CTRL(0) &= ~(3 << 4); /* control endpoint */

-    USB_IEP_CTRL(0) &= (3 << 4); /* control endpoint */
-    USB_IEP_DESC_PTR(0) = 0;
+    USB_IEP_TXFSIZE(0) = 32; // full speed
+    USB_IEP_MPS(0) = 64; // max packet size
+    USB_OEP_MPS(0) = 64; //max packet size

-    USB_OEP_CTRL(0) &= (3 << 4); /* control endpoint */
-    USB_OEP_DESC_PTR(0) = 0;
+    USB_PHY_EP0_INFO = 0 /* number */ |
+            (0<<4) /* direction */ |
+            (0<<5) /* ctrl ep */ |
+            (1<< 7) /* config num  */ |
+            (0<<11) /* interface num */ |
+            (0<<15) /* alternat setting number */ |
+            (64 << 19); // max packet size

-    USB_DEV_INTR_MASK &= ~0xff;   /* unmask all flags */
+    //USB_IEP_CTRL(0) |= (1<<0); // stall bit
+    USB_IEP_CTRL(0) |= (1<<7)|(1<<1); // Set NAK, FLUSH
+    USB_OEP_CTRL(0) |= (1<<8)|(1<<1); // clear NAK, FLUSH

-    USB_DEV_EP_INTR_MASK &= ~((1<<0) | (1<<16));    /* ep 0 */
+    /* TODO : dma setup */

-    VIC_INT_ENABLE = INTERRUPT_USB;
+    USB_DEV_EP_INTR |= (1<<0) | (1<<16); /* clear interrupts */
+    USB_DEV_EP_INTR_MASK &= ~((1<<0) | (1<<16));    /* ep 0 in & out */
+
+    /* unmask status */
+    USB_IEP_STS_MASK(0) &= ~0x1ff0;  // bits 12-4: mask for all status
+    USB_OEP_STS_MASK(0) &= ~0x1ff0;  // bits 12-4: mask for all status
+
+    USB_DEV_CFG &= ~(1<<10); /* clear soft disconnect */

-    USB_IEP_CTRL(0) |= (1<<7); /* set NAK */
-    USB_OEP_CTRL(0) |= (1<<7); /* set NAK */
+    VIC_INT_ENABLE = INTERRUPT_USB;
 }

 void usb_drv_exit(void)
@@ -209,6 +239,7 @@ int usb_drv_port_speed(void)

 int usb_drv_request_endpoint(int type, int dir)
 {
+    panicf("%s(%d,%d)",__func__,type,dir);
     (void) type;
     int i = dir == USB_DIR_IN ? 0 : 1;

@@ -227,9 +258,11 @@ int usb_drv_request_endpoint(int type, int dir)
 void usb_drv_release_endpoint(int ep)
 {
     int i = (ep & 0x7f) * 2;
-    if(ep & USB_DIR_OUT)
+    if(!(ep & USB_DIR_IN))
         i++;
     endpoints[i].busy = false;
+
+    ep &= ~USB_DIR_IN;
     USB_DEV_EP_INTR_MASK |= (1<<ep) | (1<<(16+ep));
 }

@@ -239,19 +272,31 @@ void usb_drv_cancel_all_transfers(void)

 int usb_drv_recv(int ep, void *ptr, int len)
 {
-    (void)ep;(void)ptr;(void)len;
+    panicf("%s(%d,%p,%d)", __func__,ep,ptr,len);
+    int i = (ep & 0x7f) * 2;
+    if(!(ep & USB_DIR_IN))
+        i++;
+
     if(ep >= 2)
         return -1;

+    (void)ptr;(void)len;
+
     return -1;
 }

 int usb_drv_send(int ep, void *ptr, int len)
 {
-    (void)ep;(void)ptr;(void)len;
+    panicf("%s(%d,%p,%d)", __func__,ep,ptr,len);
+    int i = (ep & 0x7f) * 2;
+    if(!(ep & USB_DIR_IN))
+        i++;
+
     if(ep >= 2)
         return -1;

+    (void)ptr;(void)len;
+
     return -1;
 }

@@ -264,7 +309,37 @@ int usb_drv_send_nonblocking(int ep, void *ptr, int len)
 /* interrupt service routine */
 void INT_USB(void)
 {
-    panicf("USB interrupt !");
+    int intr = USB_DEV_INTR;
+    if(intr)
+    {
+        panicf("USB devintr: 0x%x", intr);
+        USB_DEV_INTR = intr;
+    }
+
+    int ep = USB_DEV_EP_INTR; // = 0x10001 (in/out)
+    if(ep)
+    {
+        if(ep & (1<<0)) // ctrl in
+        {
+            panicf("ctrl in 0x%x",USB_IEP_STS(0));
+        }
+        if(ep & (1<<1)) // bulk in
+        {
+        }
+        if(ep & (1<<3)) // intr in
+        {
+        }
+        if(ep & (1<<16)) // ctrl out
+        {
+            panicf("ctrl in 0x%x",USB_OEP_STS(0));
+        }
+        if(ep & (1<<17)) // bulk out
+        {
+        }
+
+        panicf("USB : 0x%x 0x%x", intr, ep);
+        USB_DEV_EP_INTR = ep;
+    }
 }

 /* (not essential? , not implemented in usb-tcc.c) */