altos: Massive product config cleanup
[fw/altos] / src / stm / ao_usb_stm.c
1 /*
2  * Copyright © 2012 Keith Packard <keithp@keithp.com>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; version 2 of the License.
7  *
8  * This program is distributed in the hope that it will be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11  * General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License along
14  * with this program; if not, write to the Free Software Foundation, Inc.,
15  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
16  */
17
18 #include "ao.h"
19 #include "ao_usb.h"
20 #include "ao_product.h"
21
22 #define USB_DEBUG       0
23 #define USB_DEBUG_DATA  0
24
25 #if USB_DEBUG
26 #define debug(format, args...)  printf(format, ## args);
27 #else
28 #define debug(format, args...)
29 #endif
30
31 #if USB_DEBUG_DATA
32 #define debug_data(format, args...)     printf(format, ## args);
33 #else
34 #define debug_data(format, args...)
35 #endif
36
37 struct ao_task ao_usb_task;
38
39 struct ao_usb_setup {
40         uint8_t         dir_type_recip;
41         uint8_t         request;
42         uint16_t        value;
43         uint16_t        index;
44         uint16_t        length;
45 } ao_usb_setup;
46
47 static uint8_t  ao_usb_ep0_state;
48 static const uint8_t * ao_usb_ep0_in_data;
49 static uint8_t  ao_usb_ep0_in_len;
50 static uint8_t  ao_usb_ep0_in_pending;
51 static uint8_t  ao_usb_ep0_in_buf[2];
52 static uint8_t  ao_usb_ep0_out_len;
53 static uint8_t *ao_usb_ep0_out_data;
54 static union stm_usb_bdt        *ao_usb_bdt;
55 static uint16_t ao_usb_sram_addr;
56 static uint8_t  ao_usb_tx_buffer[AO_USB_IN_SIZE];
57 static uint8_t  ao_usb_tx_count;
58 static uint8_t  ao_usb_rx_buffer[AO_USB_OUT_SIZE];
59 static uint8_t  ao_usb_rx_count, ao_usb_rx_pos;
60
61 #define AO_USB_INT_EPR  1
62 #define AO_USB_OUT_EPR  2
63 #define AO_USB_IN_EPR   3
64
65 /*
66  * Pointers into the USB packet buffer area
67  */
68 static uint32_t *ao_usb_ep0_tx_buffer;
69 static uint32_t *ao_usb_ep0_rx_buffer;
70
71 static uint32_t *ao_usb_in_tx_buffer;
72 static uint32_t *ao_usb_out_rx_buffer;
73
74 static uint8_t  ao_usb_in_flushed;
75 static uint8_t  ao_usb_in_pending;
76 static uint8_t  ao_usb_out_avail;
77 static uint8_t  ao_usb_running;
78 static uint8_t  ao_usb_configuration;
79 static uint8_t  ueienx_0;
80
81 #define AO_USB_EP0_GOT_RESET    1
82 #define AO_USB_EP0_GOT_SETUP    2
83 #define AO_USB_EP0_GOT_RX_DATA  4
84 #define AO_USB_EP0_GOT_TX_ACK   8
85
86 static uint8_t  ao_usb_ep0_receive;
87 static uint8_t  ao_usb_address;
88 static uint8_t  ao_usb_address_pending;
89
90 static inline uint32_t set_toggle(uint32_t      current_value,
91                                    uint32_t     mask,
92                                    uint32_t     desired_value)
93 {
94         return (current_value ^ desired_value) & mask;
95 }
96
97 static inline uint32_t *ao_usb_packet_buffer_addr(uint16_t sram_addr)
98 {
99         return (uint32_t *) (stm_usb_sram + 2 * sram_addr);
100 }
101
102 static inline uint32_t ao_usb_epr_stat_rx(uint32_t epr) {
103         return (epr >> STM_USB_EPR_STAT_RX) & STM_USB_EPR_STAT_RX_MASK;
104 }
105
106 static inline uint32_t ao_usb_epr_stat_tx(uint32_t epr) {
107         return (epr >> STM_USB_EPR_STAT_TX) & STM_USB_EPR_STAT_TX_MASK;
108 }
109
110 static inline uint32_t ao_usb_epr_ctr_rx(uint32_t epr) {
111         return (epr >> STM_USB_EPR_CTR_RX) & 1;
112 }
113
114 static inline uint32_t ao_usb_epr_ctr_tx(uint32_t epr) {
115         return (epr >> STM_USB_EPR_CTR_TX) & 1;
116 }
117
118 static inline uint32_t ao_usb_epr_setup(uint32_t epr) {
119         return (epr >> STM_USB_EPR_SETUP) & 1;
120 }
121
122 static inline uint32_t ao_usb_epr_dtog_rx(uint32_t epr) {
123         return (epr >> STM_USB_EPR_DTOG_RX) & 1;
124 }
125
126 static inline uint32_t ao_usb_epr_dtog_tx(uint32_t epr) {
127         return (epr >> STM_USB_EPR_DTOG_TX) & 1;
128 }
129
130 /*
131  * Set current device address and mark the
132  * interface as active
133  */
134 void
135 ao_usb_set_address(uint8_t address)
136 {
137         debug("ao_usb_set_address %02x\n", address);
138         stm_usb.daddr = (1 << STM_USB_DADDR_EF) | address;
139         ao_usb_address_pending = 0;
140 }
141
142 /*
143  * Set just endpoint 0, for use during startup
144  */
145
146 static void
147 ao_usb_set_ep0(void)
148 {
149         uint32_t                epr;
150         int                     e;
151
152         ao_usb_sram_addr = 0;
153
154         /* buffer table is at the start of USB memory */
155         stm_usb.btable = 0;
156         ao_usb_bdt = (void *) stm_usb_sram;
157
158         ao_usb_sram_addr += 8 * STM_USB_BDT_SIZE;
159
160         /* Set up EP 0 - a Control end point with 32 bytes of in and out buffers */
161
162         ao_usb_bdt[0].single.addr_tx = ao_usb_sram_addr;
163         ao_usb_bdt[0].single.count_tx = 0;
164         ao_usb_ep0_tx_buffer = ao_usb_packet_buffer_addr(ao_usb_sram_addr);
165         ao_usb_sram_addr += AO_USB_CONTROL_SIZE;
166
167         ao_usb_bdt[0].single.addr_rx = ao_usb_sram_addr;
168         ao_usb_bdt[0].single.count_rx = ((1 << STM_USB_BDT_COUNT_RX_BL_SIZE) |
169                                   (((AO_USB_CONTROL_SIZE / 32) - 1) << STM_USB_BDT_COUNT_RX_NUM_BLOCK));
170         ao_usb_ep0_rx_buffer = ao_usb_packet_buffer_addr(ao_usb_sram_addr);
171         ao_usb_sram_addr += AO_USB_CONTROL_SIZE;
172
173         cli();
174         epr = stm_usb.epr[0];
175         epr = ((STM_USB_EPR_CTR_RX_WRITE_INVARIANT << STM_USB_EPR_CTR_RX) |
176                (STM_USB_EPR_DTOG_RX_WRITE_INVARIANT << STM_USB_EPR_DTOG_RX) |
177                set_toggle(epr,
178                           (STM_USB_EPR_STAT_RX_MASK << STM_USB_EPR_STAT_RX),
179                           (STM_USB_EPR_STAT_RX_VALID << STM_USB_EPR_STAT_RX)) |
180                (STM_USB_EPR_EP_TYPE_CONTROL << STM_USB_EPR_EP_TYPE) |
181                (0 << STM_USB_EPR_EP_KIND) |
182                (STM_USB_CTR_TX_WRITE_INVARIANT << STM_USB_EPR_CTR_TX) |
183                (STM_USB_EPR_DTOG_TX_WRITE_INVARIANT << STM_USB_EPR_DTOG_TX) |
184                set_toggle(epr,
185                           (STM_USB_EPR_STAT_TX_MASK << STM_USB_EPR_STAT_TX),
186                           (STM_USB_EPR_STAT_TX_NAK << STM_USB_EPR_STAT_TX)) |
187                (AO_USB_CONTROL_EP << STM_USB_EPR_EA));
188         stm_usb.epr[0] = epr;
189         sei();
190         debug ("epr 0 now %x\n", stm_usb.epr[0]);
191
192         /* Clear all of the other endpoints */
193         for (e = 1; e < 8; e++) {
194                 cli();
195                 epr = stm_usb.epr[e];
196                 epr = ((STM_USB_EPR_CTR_RX_WRITE_INVARIANT << STM_USB_EPR_CTR_RX) |
197                        (STM_USB_EPR_DTOG_RX_WRITE_INVARIANT << STM_USB_EPR_DTOG_RX) |
198                        set_toggle(epr,
199                                   (STM_USB_EPR_STAT_RX_MASK << STM_USB_EPR_STAT_RX),
200                                   (STM_USB_EPR_STAT_RX_DISABLED << STM_USB_EPR_STAT_RX)) |
201                        (STM_USB_EPR_EP_TYPE_CONTROL << STM_USB_EPR_EP_TYPE) |
202                        (0 << STM_USB_EPR_EP_KIND) |
203                        (STM_USB_CTR_TX_WRITE_INVARIANT << STM_USB_EPR_CTR_TX) |
204                        (STM_USB_EPR_DTOG_TX_WRITE_INVARIANT << STM_USB_EPR_DTOG_TX) |
205                        set_toggle(epr,
206                                   (STM_USB_EPR_STAT_TX_MASK << STM_USB_EPR_STAT_TX),
207                                   (STM_USB_EPR_STAT_TX_DISABLED << STM_USB_EPR_STAT_TX)) |
208                        (0 << STM_USB_EPR_EA));
209                 stm_usb.epr[e] = epr;
210                 sei();
211         }
212
213         ao_usb_set_address(0);
214 }
215
216 static void
217 ao_usb_set_configuration(void)
218 {
219         uint32_t                epr;
220
221         debug ("ao_usb_set_configuration\n");
222
223         /* Set up the INT end point */
224         ao_usb_bdt[AO_USB_INT_EPR].single.addr_tx = ao_usb_sram_addr;
225         ao_usb_bdt[AO_USB_INT_EPR].single.count_tx = 0;
226         ao_usb_in_tx_buffer = ao_usb_packet_buffer_addr(ao_usb_sram_addr);
227         ao_usb_sram_addr += AO_USB_INT_SIZE;
228
229         cli();
230         epr = stm_usb.epr[AO_USB_INT_EPR];
231         epr = ((0 << STM_USB_EPR_CTR_RX) |
232                (epr & (1 << STM_USB_EPR_DTOG_RX)) |
233                set_toggle(epr,
234                           (STM_USB_EPR_STAT_RX_MASK << STM_USB_EPR_STAT_RX),
235                           (STM_USB_EPR_STAT_RX_DISABLED << STM_USB_EPR_STAT_RX)) |
236                (STM_USB_EPR_EP_TYPE_CONTROL << STM_USB_EPR_EP_TYPE) |
237                (0 << STM_USB_EPR_EP_KIND) |
238                (0 << STM_USB_EPR_CTR_TX) |
239                (epr & (1 << STM_USB_EPR_DTOG_TX)) |
240                set_toggle(epr,
241                           (STM_USB_EPR_STAT_TX_MASK << STM_USB_EPR_STAT_TX),
242                           (STM_USB_EPR_STAT_TX_NAK << STM_USB_EPR_STAT_TX)) |
243                (AO_USB_INT_EP << STM_USB_EPR_EA));
244         stm_usb.epr[AO_USB_INT_EPR] = epr;
245         sei();
246         debug ("writing epr[%d] 0x%08x wrote 0x%08x\n",
247                AO_USB_INT_EPR, epr, stm_usb.epr[AO_USB_INT_EPR]);
248
249         /* Set up the OUT end point */
250         ao_usb_bdt[AO_USB_OUT_EPR].single.addr_rx = ao_usb_sram_addr;
251         ao_usb_bdt[AO_USB_OUT_EPR].single.count_rx = ((1 << STM_USB_BDT_COUNT_RX_BL_SIZE) |
252                                                       (((AO_USB_OUT_SIZE / 32) - 1) << STM_USB_BDT_COUNT_RX_NUM_BLOCK));
253         ao_usb_out_rx_buffer = ao_usb_packet_buffer_addr(ao_usb_sram_addr);
254         ao_usb_sram_addr += AO_USB_OUT_SIZE;
255
256         cli();
257         epr = stm_usb.epr[AO_USB_OUT_EPR];
258         epr = ((0 << STM_USB_EPR_CTR_RX) |
259                (epr & (1 <<  STM_USB_EPR_DTOG_RX)) |
260                set_toggle(epr,
261                           (STM_USB_EPR_STAT_RX_MASK << STM_USB_EPR_STAT_RX),
262                           (STM_USB_EPR_STAT_RX_VALID << STM_USB_EPR_STAT_RX)) |
263                (STM_USB_EPR_EP_TYPE_CONTROL << STM_USB_EPR_EP_TYPE) |
264                (0 << STM_USB_EPR_EP_KIND) |
265                (0 << STM_USB_EPR_CTR_TX) |
266                (epr & (1 << STM_USB_EPR_DTOG_TX)) |
267                set_toggle(epr,
268                           (STM_USB_EPR_STAT_TX_MASK << STM_USB_EPR_STAT_TX),
269                           (STM_USB_EPR_STAT_TX_DISABLED << STM_USB_EPR_STAT_TX)) |
270                (AO_USB_OUT_EP << STM_USB_EPR_EA));
271         stm_usb.epr[AO_USB_OUT_EPR] = epr;
272         sei();
273         debug ("writing epr[%d] 0x%08x wrote 0x%08x\n",
274                AO_USB_OUT_EPR, epr, stm_usb.epr[AO_USB_OUT_EPR]);
275         
276         /* Set up the IN end point */
277         ao_usb_bdt[AO_USB_IN_EPR].single.addr_tx = ao_usb_sram_addr;
278         ao_usb_bdt[AO_USB_IN_EPR].single.count_tx = 0;
279         ao_usb_in_tx_buffer = ao_usb_packet_buffer_addr(ao_usb_sram_addr);
280         ao_usb_sram_addr += AO_USB_IN_SIZE;
281
282         cli();
283         epr = stm_usb.epr[AO_USB_IN_EPR];
284         epr = ((0 << STM_USB_EPR_CTR_RX) |
285                (epr & (1 << STM_USB_EPR_DTOG_RX)) |
286                set_toggle(epr,
287                           (STM_USB_EPR_STAT_RX_MASK << STM_USB_EPR_STAT_RX),
288                           (STM_USB_EPR_STAT_RX_DISABLED << STM_USB_EPR_STAT_RX)) |
289                (STM_USB_EPR_EP_TYPE_CONTROL << STM_USB_EPR_EP_TYPE) |
290                (0 << STM_USB_EPR_EP_KIND) |
291                (0 << STM_USB_EPR_CTR_TX) |
292                (epr & (1 << STM_USB_EPR_DTOG_TX)) |
293                set_toggle(epr,
294                           (STM_USB_EPR_STAT_TX_MASK << STM_USB_EPR_STAT_TX),
295                           (STM_USB_EPR_STAT_TX_NAK << STM_USB_EPR_STAT_TX)) |
296                (AO_USB_IN_EP << STM_USB_EPR_EA));
297         stm_usb.epr[AO_USB_IN_EPR] = epr;
298         sei();
299         debug ("writing epr[%d] 0x%08x wrote 0x%08x\n",
300                AO_USB_IN_EPR, epr, stm_usb.epr[AO_USB_IN_EPR]);
301         ao_usb_running = 1;
302 }
303
304 static uint16_t control_count;
305 static uint16_t in_count;
306 static uint16_t out_count;
307 static uint16_t reset_count;
308
309 /*
310  * Write these values to preserve register contents under HW changes
311  */
312
313 #define STM_USB_EPR_INVARIANT   ((1 << STM_USB_EPR_CTR_RX) |            \
314                                  (STM_USB_EPR_DTOG_RX_WRITE_INVARIANT << STM_USB_EPR_DTOG_RX) | \
315                                  (STM_USB_EPR_STAT_RX_WRITE_INVARIANT << STM_USB_EPR_STAT_RX) | \
316                                  (1 << STM_USB_EPR_CTR_TX) |            \
317                                  (STM_USB_EPR_DTOG_TX_WRITE_INVARIANT << STM_USB_EPR_DTOG_TX) | \
318                                  (STM_USB_EPR_STAT_TX_WRITE_INVARIANT << STM_USB_EPR_STAT_TX))
319
320 #define STM_USB_EPR_INVARIANT_MASK      ((1 << STM_USB_EPR_CTR_RX) |    \
321                                          (STM_USB_EPR_DTOG_RX_MASK << STM_USB_EPR_DTOG_RX) | \
322                                          (STM_USB_EPR_STAT_RX_MASK << STM_USB_EPR_STAT_RX) | \
323                                          (1 << STM_USB_EPR_CTR_TX) |    \
324                                          (STM_USB_EPR_DTOG_TX_MASK << STM_USB_EPR_DTOG_TX) | \
325                                          (STM_USB_EPR_STAT_TX_MASK << STM_USB_EPR_STAT_TX))
326
327 /*
328  * These bits are purely under sw control, so preserve them in the
329  * register by re-writing what was read
330  */
331 #define STM_USB_EPR_PRESERVE_MASK       ((STM_USB_EPR_EP_TYPE_MASK << STM_USB_EPR_EP_TYPE) | \
332                                          (1 << STM_USB_EPR_EP_KIND) |   \
333                                          (STM_USB_EPR_EA_MASK << STM_USB_EPR_EA))
334
335 void
336 stm_usb_lp_isr(void)
337 {
338         uint32_t        istr = stm_usb.istr;
339
340         if (istr & (1 << STM_USB_ISTR_CTR)) {
341                 uint8_t         ep = istr & STM_USB_ISTR_EP_ID_MASK;
342                 uint32_t        epr, epr_write;
343
344                 /* Preserve the SW write bits, don't mess with most HW writable bits,
345                  * clear the CTR_RX and CTR_TX bits
346                  */
347                 epr = stm_usb.epr[ep];
348                 epr_write = epr;
349                 epr_write &= STM_USB_EPR_PRESERVE_MASK;
350                 epr_write |= STM_USB_EPR_INVARIANT;
351                 epr_write &= ~(1 << STM_USB_EPR_CTR_RX);
352                 epr_write &= ~(1 << STM_USB_EPR_CTR_TX);
353                 stm_usb.epr[ep] = epr_write;
354
355                 switch (ep) {
356                 case 0:
357                         ++control_count;
358                         if (ao_usb_epr_ctr_rx(epr)) {
359                                 if (ao_usb_epr_setup(epr))
360                                         ao_usb_ep0_receive |= AO_USB_EP0_GOT_SETUP;
361                                 else
362                                         ao_usb_ep0_receive |= AO_USB_EP0_GOT_RX_DATA;
363                         }
364                         if (ao_usb_epr_ctr_tx(epr))
365                                 ao_usb_ep0_receive |= AO_USB_EP0_GOT_TX_ACK;
366                         ao_wakeup(&ao_usb_ep0_receive);
367                         break;
368                 case AO_USB_OUT_EPR:
369                         ++out_count;
370                         if (ao_usb_epr_ctr_rx(epr)) {
371                                 ao_usb_out_avail = 1;
372                                 ao_wakeup(&ao_stdin_ready);
373                         }
374                         break;
375                 case AO_USB_IN_EPR:
376                         ++in_count;
377                         if (ao_usb_epr_ctr_tx(epr)) {
378                                 ao_usb_in_pending = 0;
379                                 ao_wakeup(&ao_usb_in_pending);
380                         }
381                         break;
382                 }
383                 return;
384         }
385
386         if (istr & (1 << STM_USB_ISTR_RESET)) {
387                 ++reset_count;
388                 stm_usb.istr &= ~(1 << STM_USB_ISTR_RESET);
389                 ao_usb_ep0_receive |= AO_USB_EP0_GOT_RESET;
390                 ao_wakeup(&ao_usb_ep0_receive);
391         }
392 }
393
394 void
395 stm_usb_hp_isr(void)
396 {
397         stm_usb_lp_isr();
398 }
399
400 void
401 stm_usb_fs_wkup(void)
402 {
403         /* USB wakeup, just clear the bit for now */
404         stm_usb.istr &= ~(1 << STM_USB_ISTR_WKUP);
405 }
406
407 static struct ao_usb_line_coding ao_usb_line_coding = {115200, 0, 0, 8};
408
409 /* Walk through the list of descriptors and find a match
410  */
411 static void
412 ao_usb_get_descriptor(uint16_t value)
413 {
414         const uint8_t           *descriptor;
415         uint8_t         type = value >> 8;
416         uint8_t         index = value;
417
418         descriptor = ao_usb_descriptors;
419         while (descriptor[0] != 0) {
420                 if (descriptor[1] == type && index-- == 0) {
421                         if (type == AO_USB_DESC_CONFIGURATION)
422                                 ao_usb_ep0_in_len = descriptor[2];
423                         else
424                                 ao_usb_ep0_in_len = descriptor[0];
425                         ao_usb_ep0_in_data = descriptor;
426                         break;
427                 }
428                 descriptor += descriptor[0];
429         }
430 }
431
432 static void
433 ao_usb_ep0_set_in_pending(uint8_t in_pending)
434 {
435         ao_usb_ep0_in_pending = in_pending;
436
437 #if 0
438         if (in_pending)
439                 ueienx_0 = ((1 << RXSTPE) | (1 << RXOUTE) | (1 << TXINE));      /* Enable IN interrupt */
440 #endif
441 }
442
443 /* The USB memory holds 16 bit values on 32 bit boundaries
444  * and must be accessed only in 32 bit units. Sigh.
445  */
446
447 static inline void
448 ao_usb_write_byte(uint8_t byte, uint32_t *base, uint16_t offset)
449 {
450         base += offset >> 1;
451         if (offset & 1) {
452                 *base = (*base & 0xff) | ((uint32_t) byte << 8);
453         } else {
454                 *base = (*base & 0xff00) | byte;
455         }
456 }
457
458 static inline void
459 ao_usb_write_short(uint16_t data, uint32_t *base, uint16_t offset)
460 {
461         base[offset>>1] = data;
462 }
463
464 static void
465 ao_usb_write(const uint8_t *src, uint32_t *base, uint16_t offset, uint16_t bytes)
466 {
467         if (!bytes)
468                 return;
469         if (offset & 1) {
470                 debug_data (" %02x", src[0]);
471                 ao_usb_write_byte(*src++, base, offset++);
472                 bytes--;
473         }
474         while (bytes >= 2) {
475                 debug_data (" %02x %02x", src[0], src[1]);
476                 ao_usb_write_short((src[1] << 8) | src[0], base, offset);
477                 offset += 2;
478                 src += 2;
479                 bytes -= 2;
480         }
481         if (bytes) {
482                 debug_data (" %02x", src[0]);
483                 ao_usb_write_byte(*src, base, offset);
484         }
485 }
486
487 static inline uint8_t
488 ao_usb_read_byte(uint32_t *base, uint16_t offset)
489 {
490         base += offset >> 1;
491         if (offset & 1)
492                 return (*base >> 8) & 0xff;
493         else
494                 return *base & 0xff;
495 }
496
497 static inline uint16_t
498 ao_usb_read_short(uint32_t *base, uint16_t offset)
499 {
500         return base[offset>>1];
501 }
502
503 static void
504 ao_usb_read(uint8_t *dst, uint32_t *base, uint16_t offset, uint16_t bytes)
505 {
506         if (!bytes)
507                 return;
508         if (offset & 1) {
509                 *dst++ = ao_usb_read_byte(base, offset++);
510                 debug_data (" %02x", dst[-1]);
511                 bytes--;
512         }
513         while (bytes >= 2) {
514                 uint16_t        s = ao_usb_read_short(base, offset);
515                 dst[0] = s;
516                 dst[1] = s >> 8;
517                 debug_data (" %02x %02x", dst[0], dst[1]);
518                 offset += 2;
519                 dst += 2;
520                 bytes -= 2;
521         }
522         if (bytes) {
523                 *dst = ao_usb_read_byte(base, offset);
524                 debug_data (" %02x", dst[0]);
525         }
526 }
527
528 static inline void
529 ao_usb_set_stat_tx(int ep, uint32_t stat_tx) {
530         uint32_t        epr_write, epr_old, epr_new, epr_want;
531
532         cli();
533         epr_write = epr_old = stm_usb.epr[ep];
534         epr_write &= STM_USB_EPR_PRESERVE_MASK;
535         epr_write |= STM_USB_EPR_INVARIANT;
536         epr_write |= set_toggle(epr_old,
537                               STM_USB_EPR_STAT_TX_MASK << STM_USB_EPR_STAT_TX,
538                               stat_tx << STM_USB_EPR_STAT_TX);
539         stm_usb.epr[ep] = epr_write;
540         epr_new = stm_usb.epr[ep];
541         sei();
542         epr_want = (epr_old & ~(STM_USB_EPR_STAT_TX_MASK << STM_USB_EPR_STAT_TX)) |
543                 (stat_tx << STM_USB_EPR_STAT_TX);
544         if (epr_new != epr_want) {
545                 debug ("**** set_stat_tx to %x. old %08x want %08x write %08x new %08x\n",
546                        stat_tx, epr_old, epr_want, epr_write, epr_new);
547         }
548 }
549
550 /* Send an IN data packet */
551 static void
552 ao_usb_ep0_flush(void)
553 {
554         uint8_t this_len;
555
556         /* Check to see if the endpoint is still busy */
557         if (ao_usb_epr_stat_tx(stm_usb.epr[0]) == STM_USB_EPR_STAT_TX_VALID) {
558                 debug("EP0 not accepting IN data\n");
559                 ao_usb_ep0_set_in_pending(1);
560         } else {
561                 this_len = ao_usb_ep0_in_len;
562                 if (this_len > AO_USB_CONTROL_SIZE)
563                         this_len = AO_USB_CONTROL_SIZE;
564
565                 ao_usb_ep0_in_len -= this_len;
566
567                 /* Set IN interrupt enable */
568                 if (ao_usb_ep0_in_len == 0 && this_len != AO_USB_CONTROL_SIZE)
569                         ao_usb_ep0_set_in_pending(0);
570                 else
571                         ao_usb_ep0_set_in_pending(1);
572
573                 debug_data ("Flush EP0 len %d:", this_len);
574                 ao_usb_write(ao_usb_ep0_in_data, ao_usb_ep0_tx_buffer, 0, this_len);
575                 debug_data ("\n");
576                 ao_usb_ep0_in_data += this_len;
577
578                 /* Mark the endpoint as TX valid to send the packet */
579                 ao_usb_bdt[0].single.count_tx = this_len;
580                 ao_usb_set_stat_tx(0, STM_USB_EPR_STAT_TX_VALID);
581                 debug ("queue tx. epr 0 now %08x\n", stm_usb.epr[0]);
582         }
583 }
584
585 static inline void
586 ao_usb_set_stat_rx(int ep, uint32_t stat_rx) {
587         uint32_t        epr_write, epr_old, epr_new, epr_want;
588
589         cli();
590         epr_write = epr_old = stm_usb.epr[ep];
591         epr_write &= STM_USB_EPR_PRESERVE_MASK;
592         epr_write |= STM_USB_EPR_INVARIANT;
593         epr_write |= set_toggle(epr_old,
594                               STM_USB_EPR_STAT_RX_MASK << STM_USB_EPR_STAT_RX,
595                               stat_rx << STM_USB_EPR_STAT_RX);
596         stm_usb.epr[ep] = epr_write;
597         epr_new = stm_usb.epr[ep];
598         sei();
599         epr_want = (epr_old & ~(STM_USB_EPR_STAT_RX_MASK << STM_USB_EPR_STAT_RX)) |
600                 (stat_rx << STM_USB_EPR_STAT_RX);
601         if (epr_new != epr_want) {
602                 debug ("**** set_stat_rx to %x. old %08x want %08x write %08x new %08x\n",
603                        stat_rx, epr_old, epr_want, epr_write, epr_new);
604         }
605 }
606
607 /* Read data from the ep0 OUT fifo */
608 static void
609 ao_usb_ep0_fill(void)
610 {
611         uint16_t        len = ao_usb_bdt[0].single.count_rx & STM_USB_BDT_COUNT_RX_COUNT_RX_MASK;
612
613         if (len > ao_usb_ep0_out_len)
614                 len = ao_usb_ep0_out_len;
615         ao_usb_ep0_out_len -= len;
616
617         /* Pull all of the data out of the packet */
618         debug_data ("Fill EP0 len %d:", len);
619         ao_usb_read(ao_usb_ep0_out_data, ao_usb_ep0_rx_buffer, 0, len);
620         debug_data ("\n");
621         ao_usb_ep0_out_data += len;
622
623         /* ACK the packet */
624         ao_usb_set_stat_rx(0, STM_USB_EPR_STAT_RX_VALID);
625 }
626
627 void
628 ao_usb_ep0_queue_byte(uint8_t a)
629 {
630         ao_usb_ep0_in_buf[ao_usb_ep0_in_len++] = a;
631 }
632
633 static void
634 ao_usb_ep0_setup(void)
635 {
636         /* Pull the setup packet out of the fifo */
637         ao_usb_ep0_out_data = (uint8_t *) &ao_usb_setup;
638         ao_usb_ep0_out_len = 8;
639         ao_usb_ep0_fill();
640         if (ao_usb_ep0_out_len != 0) {
641                 debug ("invalid setup packet length\n");
642                 return;
643         }
644
645         /* Figure out how to ACK the setup packet */
646         if (ao_usb_setup.dir_type_recip & AO_USB_DIR_IN) {
647                 if (ao_usb_setup.length)
648                         ao_usb_ep0_state = AO_USB_EP0_DATA_IN;
649                 else
650                         ao_usb_ep0_state = AO_USB_EP0_IDLE;
651         } else {
652                 if (ao_usb_setup.length)
653                         ao_usb_ep0_state = AO_USB_EP0_DATA_OUT;
654                 else
655                         ao_usb_ep0_state = AO_USB_EP0_IDLE;
656         }
657
658         ao_usb_ep0_in_data = ao_usb_ep0_in_buf;
659         ao_usb_ep0_in_len = 0;
660         switch(ao_usb_setup.dir_type_recip & AO_USB_SETUP_TYPE_MASK) {
661         case AO_USB_TYPE_STANDARD:
662                 debug ("Standard setup packet\n");
663                 switch(ao_usb_setup.dir_type_recip & AO_USB_SETUP_RECIP_MASK) {
664                 case AO_USB_RECIP_DEVICE:
665                         debug ("Device setup packet\n");
666                         switch(ao_usb_setup.request) {
667                         case AO_USB_REQ_GET_STATUS:
668                                 debug ("get status\n");
669                                 ao_usb_ep0_queue_byte(0);
670                                 ao_usb_ep0_queue_byte(0);
671                                 break;
672                         case AO_USB_REQ_SET_ADDRESS:
673                                 debug ("set address %d\n", ao_usb_setup.value);
674                                 ao_usb_address = ao_usb_setup.value;
675                                 ao_usb_address_pending = 1;
676                                 break;
677                         case AO_USB_REQ_GET_DESCRIPTOR:
678                                 debug ("get descriptor %d\n", ao_usb_setup.value);
679                                 ao_usb_get_descriptor(ao_usb_setup.value);
680                                 break;
681                         case AO_USB_REQ_GET_CONFIGURATION:
682                                 debug ("get configuration %d\n", ao_usb_configuration);
683                                 ao_usb_ep0_queue_byte(ao_usb_configuration);
684                                 break;
685                         case AO_USB_REQ_SET_CONFIGURATION:
686                                 ao_usb_configuration = ao_usb_setup.value;
687                                 debug ("set configuration %d\n", ao_usb_configuration);
688                                 ao_usb_set_configuration();
689                                 break;
690                         }
691                         break;
692                 case AO_USB_RECIP_INTERFACE:
693                         debug ("Interface setup packet\n");
694                         switch(ao_usb_setup.request) {
695                         case AO_USB_REQ_GET_STATUS:
696                                 ao_usb_ep0_queue_byte(0);
697                                 ao_usb_ep0_queue_byte(0);
698                                 break;
699                         case AO_USB_REQ_GET_INTERFACE:
700                                 ao_usb_ep0_queue_byte(0);
701                                 break;
702                         case AO_USB_REQ_SET_INTERFACE:
703                                 break;
704                         }
705                         break;
706                 case AO_USB_RECIP_ENDPOINT:
707                         debug ("Endpoint setup packet\n");
708                         switch(ao_usb_setup.request) {
709                         case AO_USB_REQ_GET_STATUS:
710                                 ao_usb_ep0_queue_byte(0);
711                                 ao_usb_ep0_queue_byte(0);
712                                 break;
713                         }
714                         break;
715                 }
716                 break;
717         case AO_USB_TYPE_CLASS:
718                 debug ("Class setup packet\n");
719                 switch (ao_usb_setup.request) {
720                 case AO_USB_SET_LINE_CODING:
721                         debug ("set line coding\n");
722                         ao_usb_ep0_out_len = 7;
723                         ao_usb_ep0_out_data = (uint8_t *) &ao_usb_line_coding;
724                         break;
725                 case AO_USB_GET_LINE_CODING:
726                         debug ("get line coding\n");
727                         ao_usb_ep0_in_len = 7;
728                         ao_usb_ep0_in_data = (uint8_t *) &ao_usb_line_coding;
729                         break;
730                 case AO_USB_SET_CONTROL_LINE_STATE:
731                         break;
732                 }
733                 break;
734         }
735         if (ao_usb_ep0_state != AO_USB_EP0_DATA_OUT) {
736                 if (ao_usb_setup.length < ao_usb_ep0_in_len)
737                         ao_usb_ep0_in_len = ao_usb_setup.length;
738                 ao_usb_ep0_flush();
739         }
740 }
741
742 /* End point 0 receives all of the control messages. */
743 static void
744 ao_usb_ep0(void)
745 {
746         uint8_t intx, udint;
747
748         debug ("usb task started\n");
749         ao_usb_ep0_state = AO_USB_EP0_IDLE;
750         for (;;) {
751                 uint8_t receive;
752                 ao_arch_critical(
753                         while (!(receive = ao_usb_ep0_receive))
754                                 ao_sleep(&ao_usb_ep0_receive);
755                         ao_usb_ep0_receive = 0;
756                         );
757                 
758                 if (receive & AO_USB_EP0_GOT_RESET) {
759                         debug ("\treset\n");
760                         ao_usb_set_ep0();
761                         continue;
762                 }
763                 if (receive & AO_USB_EP0_GOT_SETUP) {
764                         debug ("\tsetup\n");
765                         ao_usb_ep0_setup();
766                 }
767                 if (receive & AO_USB_EP0_GOT_RX_DATA) {
768                         debug ("\tgot rx data\n");
769                         ao_usb_ep0_fill();
770                         ao_usb_ep0_set_in_pending(1);
771                 }
772                 if (receive & AO_USB_EP0_GOT_TX_ACK) {
773                         debug ("\tgot tx ack\n");
774                         ao_usb_ep0_flush();
775                         if (ao_usb_address_pending) {
776                                 ao_usb_set_address(ao_usb_address);
777                                 ao_usb_set_configuration();
778                         }
779                 }
780         }
781 }
782
783 /* Queue the current IN buffer for transmission */
784 static void
785 ao_usb_in_send(void)
786 {
787         debug ("send %d\n", ao_usb_tx_count);
788         ao_usb_write(ao_usb_tx_buffer, ao_usb_in_tx_buffer, 0, ao_usb_tx_count);
789         ao_usb_bdt[AO_USB_IN_EPR].single.count_tx = ao_usb_tx_count;
790         ao_usb_set_stat_tx(AO_USB_IN_EPR, STM_USB_EPR_STAT_TX_VALID);
791         ao_usb_in_pending = 1;
792         ao_usb_tx_count = 0;
793 }
794
795 /* Wait for a free IN buffer */
796 static void
797 ao_usb_in_wait(void)
798 {
799         for (;;) {
800                 /* Check if the current buffer is writable */
801                 if (ao_usb_tx_count < AO_USB_IN_SIZE)
802                         break;
803
804                 cli();
805                 /* Wait for an IN buffer to be ready */
806                 while (ao_usb_in_pending)
807                         ao_sleep(&ao_usb_in_pending);
808                 sei();
809         }
810 }
811
812 void
813 ao_usb_flush(void) __critical
814 {
815         if (!ao_usb_running)
816                 return;
817
818         /* Anytime we've sent a character since
819          * the last time we flushed, we'll need
820          * to send a packet -- the only other time
821          * we would send a packet is when that
822          * packet was full, in which case we now
823          * want to send an empty packet
824          */
825         if (!ao_usb_in_flushed) {
826                 ao_usb_in_flushed = 1;
827                 cli();
828                 /* Wait for an IN buffer to be ready */
829                 while (ao_usb_in_pending)
830                         ao_sleep(&ao_usb_in_pending);
831                 sei();
832                 ao_usb_in_send();
833         }
834 }
835
836 void
837 ao_usb_putchar(char c) __critical __reentrant
838 {
839         if (!ao_usb_running)
840                 return;
841
842         ao_usb_in_wait();
843
844         ao_usb_tx_buffer[ao_usb_tx_count++] = (uint8_t) c;
845
846         /* Send the packet when full */
847         if (ao_usb_tx_count == AO_USB_IN_SIZE)
848                 ao_usb_in_send();
849         ao_usb_in_flushed = 0;
850 }
851
852 static void
853 ao_usb_out_recv(void)
854 {
855         ao_usb_out_avail = 0;
856
857         ao_usb_rx_count = ao_usb_bdt[AO_USB_OUT_EPR].single.count_rx & STM_USB_BDT_COUNT_RX_COUNT_RX_MASK;
858
859         debug ("recv %d\n", ao_usb_rx_count);
860         debug_data("Fill OUT len %d:", ao_usb_rx_count);
861         ao_usb_read(ao_usb_rx_buffer, ao_usb_out_rx_buffer, 0, ao_usb_rx_count);
862         debug_data("\n");
863         ao_usb_rx_pos = 0;
864
865         /* ACK the packet */
866         ao_usb_set_stat_rx(AO_USB_OUT_EPR, STM_USB_EPR_STAT_RX_VALID);
867 }
868
869 static char
870 _ao_usb_pollchar(void)
871 {
872         char c;
873
874         if (!ao_usb_running)
875                 return AO_READ_AGAIN;
876
877         for (;;) {
878                 if (ao_usb_rx_pos != ao_usb_rx_count)
879                         break;
880
881                 /* Check to see if a packet has arrived */
882                 if (!ao_usb_out_avail)
883                         return AO_READ_AGAIN;
884                 ao_usb_out_recv();
885         }
886
887         /* Pull a character out of the fifo */
888         c = ao_usb_rx_buffer[ao_usb_rx_pos++];
889         return c;
890 }
891
892 char
893 ao_usb_pollchar(void)
894 {
895         char    c;
896         cli();
897         c = _ao_usb_pollchar();
898         sei();
899         return c;
900 }
901
902 char
903 ao_usb_getchar(void) __critical
904 {
905         char    c;
906
907         cli();
908         while ((c = _ao_usb_pollchar()) == AO_READ_AGAIN)
909                 ao_sleep(&ao_stdin_ready);
910         sei();
911         return c;
912 }
913
914 void
915 ao_usb_disable(void)
916 {
917         stm_usb.cntr = (1 << STM_USB_CNTR_FRES);
918         stm_usb.istr = 0;
919
920         /* Disable USB pull-up */
921         stm_syscfg.pmc &= ~(1 << STM_SYSCFG_PMC_USB_PU);
922
923         /* Switch off the device */
924         stm_usb.cntr = (1 << STM_USB_CNTR_PDWN) | (1 << STM_USB_CNTR_FRES);
925
926         /* Disable the interface */
927         stm_rcc.apb1enr &+ ~(1 << STM_RCC_APB1ENR_USBEN);
928 }
929
930 void
931 ao_usb_enable(void)
932 {
933         uint16_t        tick;
934
935         /* Enable SYSCFG */
936         stm_rcc.apb2enr |= (1 << STM_RCC_APB2ENR_SYSCFGEN);
937
938         /* Disable USB pull-up */
939         stm_syscfg.pmc &= ~(1 << STM_SYSCFG_PMC_USB_PU);
940
941         /* Enable USB device */
942         stm_rcc.apb1enr |= (1 << STM_RCC_APB1ENR_USBEN);
943
944         /* Do not touch the GPIOA configuration; USB takes priority
945          * over GPIO on pins A11 and A12, but if you select alternate
946          * input 10 (the documented correct selection), then USB is
947          * pulled low and doesn't work at all
948          */
949
950         /* Route interrupts */
951         stm_nvic_set_priority(STM_ISR_USB_LP_POS, 3);
952         stm_nvic_set_enable(STM_ISR_USB_LP_POS);
953
954         ao_usb_configuration = 0;
955
956         stm_usb.cntr = (1 << STM_USB_CNTR_FRES);
957
958         /* Clear the power down bit */
959         stm_usb.cntr = 0;
960
961         /* Clear any spurious interrupts */
962         stm_usb.istr = 0;
963         
964         debug ("ao_usb_enable\n");
965
966         /* Enable interrupts */
967         stm_usb.cntr = ((1 << STM_USB_CNTR_CTRM) |
968                         (0 << STM_USB_CNTR_PMAOVRM) |
969                         (0 << STM_USB_CNTR_ERRM) |
970                         (0 << STM_USB_CNTR_WKUPM) |
971                         (0 << STM_USB_CNTR_SUSPM) |
972                         (1 << STM_USB_CNTR_RESETM) |
973                         (0 << STM_USB_CNTR_SOFM) |
974                         (0 << STM_USB_CNTR_ESOFM) |
975                         (0 << STM_USB_CNTR_RESUME) |
976                         (0 << STM_USB_CNTR_FSUSP) |
977                         (0 << STM_USB_CNTR_LP_MODE) |
978                         (0 << STM_USB_CNTR_PDWN) |
979                         (0 << STM_USB_CNTR_FRES));
980
981         /* Enable USB pull-up */
982         stm_syscfg.pmc |= (1 << STM_SYSCFG_PMC_USB_PU);
983 }
984
985 #if USB_DEBUG
986 struct ao_task ao_usb_echo_task;
987
988 static void
989 ao_usb_echo(void)
990 {
991         char    c;
992
993         for (;;) {
994                 c = ao_usb_getchar();
995                 ao_usb_putchar(c);
996                 ao_usb_flush();
997         }
998 }
999 #endif
1000
1001 static void
1002 ao_usb_irq(void)
1003 {
1004         printf ("control: %d out: %d in: %d reset: %d\n",
1005                 control_count, out_count, in_count, reset_count);
1006 }
1007
1008 __code struct ao_cmds ao_usb_cmds[] = {
1009         { ao_usb_irq, "I\0Show USB interrupt counts" },
1010         { 0, NULL }
1011 };
1012
1013 void
1014 ao_usb_init(void)
1015 {
1016         ao_usb_enable();
1017
1018         debug ("ao_usb_init\n");
1019         ao_add_task(&ao_usb_task, ao_usb_ep0, "usb");
1020 #if USB_DEBUG
1021         ao_add_task(&ao_usb_echo_task, ao_usb_echo, "usb echo");
1022 #endif
1023         ao_cmd_register(&ao_usb_cmds[0]);
1024 #if !USB_DEBUG
1025         ao_add_stdio(ao_usb_pollchar, ao_usb_putchar, ao_usb_flush);
1026 #endif
1027 }