aboutsummaryrefslogtreecommitdiffstats
path: root/libmaple/usb/stm32f1/usb_reg_map.h
blob: ea483d2a163e2fde041ca09b658612441351671e (plain)
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
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
/******************************************************************************
 * The MIT License
 *
 * Copyright (c) 2011 LeafLabs, LLC.
 *
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use, copy,
 * modify, merge, publish, distribute, sublicense, and/or sell copies
 * of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 *****************************************************************************/

#include <libmaple/libmaple_types.h>
#include <libmaple/util.h>

#ifndef _USB_REG_MAP_H_
#define _USB_REG_MAP_H_

/* TODO:
 * - Pick one of "endp", "ep" "endpt"
 */

/*
 * Register map and base pointer
 */

#define USB_NR_EP_REGS                  8

/** USB register map type */
typedef struct usb_reg_map {
    __io uint32 EP[USB_NR_EP_REGS]; /**< Endpoint registers */
    const uint32 RESERVED[8];       /**< Reserved */
    __io uint32 CNTR;               /**< Control register */
    __io uint32 ISTR;               /**< Interrupt status register */
    __io uint32 FNR;                /**< Frame number register */
    __io uint32 DADDR;              /**< Device address */
    __io uint32 BTABLE;             /**< @brief Buffer table address
                                     *
                                     * Address offset within the USB
                                     * packet memory area which points
                                     * to the base of the buffer
                                     * descriptor table.  Must be
                                     * aligned to an 8 byte boundary.
                                     */
} usb_reg_map;

/** USB register map base pointer */
#define USB_BASE                        ((struct usb_reg_map*)0x40005C00)

/*
 * Register bit definitions
 */

/* Endpoint registers (USB_EPnR) */

#define USB_EP_CTR_RX_BIT              15
#define USB_EP_DTOG_RX_BIT             14
#define USB_EP_SETUP_BIT               11
#define USB_EP_EP_KIND_BIT             8
#define USB_EP_CTR_TX_BIT              7
#define USB_EP_DTOG_TX_BIT             6

#define USB_EP_CTR_RX                  BIT(USB_EP_CTR_RX_BIT)
#define USB_EP_DTOG_RX                 BIT(USB_EP_DTOG_RX_BIT)
#define USB_EP_STAT_RX                 (0x3 << 12)
#define USB_EP_STAT_RX_DISABLED        (0x0 << 12)
#define USB_EP_STAT_RX_STALL           (0x1 << 12)
#define USB_EP_STAT_RX_NAK             (0x2 << 12)
#define USB_EP_STAT_RX_VALID           (0x3 << 12)
#define USB_EP_SETUP                   BIT(USB_EP_SETUP_BIT)
#define USB_EP_EP_TYPE                 (0x3 << 9)
#define USB_EP_EP_TYPE_BULK            (0x0 << 9)
#define USB_EP_EP_TYPE_CONTROL         (0x1 << 9)
#define USB_EP_EP_TYPE_ISO             (0x2 << 9)
#define USB_EP_EP_TYPE_INTERRUPT       (0x3 << 9)
#define USB_EP_EP_KIND                 BIT(USB_EP_EP_KIND_BIT)
#define USB_EP_CTR_TX                  BIT(USB_EP_CTR_TX_BIT)
#define USB_EP_DTOG_TX                 BIT(USB_EP_DTOG_TX_BIT)
#define USB_EP_STAT_TX                 (0x3 << 4)
#define USB_EP_STAT_TX_DISABLED        (0x0 << 4)
#define USB_EP_STAT_TX_STALL           (0x1 << 4)
#define USB_EP_STAT_TX_NAK             (0x2 << 4)
#define USB_EP_STAT_TX_VALID           (0x3 << 4)
#define USB_EP_EA                      0xF

/* Control register (USB_CNTR) */

#define USB_CNTR_CTRM_BIT              15
#define USB_CNTR_PMAOVERM_BIT          14
#define USB_CNTR_ERRM_BIT              13
#define USB_CNTR_WKUPM_BIT             12
#define USB_CNTR_SUSPM_BIT             11
#define USB_CNTR_RESETM_BIT            10
#define USB_CNTR_SOFM_BIT              9
#define USB_CNTR_ESOFM_BIT             8
#define USB_CNTR_RESUME_BIT            4
#define USB_CNTR_FSUSP_BIT             3
#define USB_CNTR_LP_MODE_BIT           2
#define USB_CNTR_PDWN_BIT              1
#define USB_CNTR_FRES_BIT              0

#define USB_CNTR_CTRM                  BIT(USB_CNTR_CTRM_BIT)
#define USB_CNTR_PMAOVERM              BIT(USB_CNTR_PMAOVERM_BIT)
#define USB_CNTR_ERRM                  BIT(USB_CNTR_ERRM_BIT)
#define USB_CNTR_WKUPM                 BIT(USB_CNTR_WKUPM_BIT)
#define USB_CNTR_SUSPM                 BIT(USB_CNTR_SUSPM_BIT)
#define USB_CNTR_RESETM                BIT(USB_CNTR_RESETM_BIT)
#define USB_CNTR_SOFM                  BIT(USB_CNTR_SOFM_BIT)
#define USB_CNTR_ESOFM                 BIT(USB_CNTR_ESOFM_BIT)
#define USB_CNTR_RESUME                BIT(USB_CNTR_RESUME_BIT)
#define USB_CNTR_FSUSP                 BIT(USB_CNTR_FSUSP_BIT)
#define USB_CNTR_LP_MODE               BIT(USB_CNTR_LP_MODE_BIT)
#define USB_CNTR_PDWN                  BIT(USB_CNTR_PDWN_BIT)
#define USB_CNTR_FRES                  BIT(USB_CNTR_FRES_BIT)

/* Interrupt status register (USB_ISTR) */

#define USB_ISTR_CTR_BIT               15
#define USB_ISTR_PMAOVR_BIT            14
#define USB_ISTR_ERR_BIT               13
#define USB_ISTR_WKUP_BIT              12
#define USB_ISTR_SUSP_BIT              11
#define USB_ISTR_RESET_BIT             10
#define USB_ISTR_SOF_BIT               9
#define USB_ISTR_ESOF_BIT              8
#define USB_ISTR_DIR_BIT               4

#define USB_ISTR_CTR                   BIT(USB_ISTR_CTR_BIT)
#define USB_ISTR_PMAOVR                BIT(USB_ISTR_PMAOVR_BIT)
#define USB_ISTR_ERR                   BIT(USB_ISTR_ERR_BIT)
#define USB_ISTR_WKUP                  BIT(USB_ISTR_WKUP_BIT)
#define USB_ISTR_SUSP                  BIT(USB_ISTR_SUSP_BIT)
#define USB_ISTR_RESET                 BIT(USB_ISTR_RESET_BIT)
#define USB_ISTR_SOF                   BIT(USB_ISTR_SOF_BIT)
#define USB_ISTR_ESOF                  BIT(USB_ISTR_ESOF_BIT)
#define USB_ISTR_DIR                   BIT(USB_ISTR_DIR_BIT)
#define USB_ISTR_EP_ID                 0xF

/* Frame number register (USB_FNR) */

#define USB_FNR_RXDP_BIT                15
#define USB_FNR_RXDM_BIT                14
#define USB_FNR_LCK_BIT                 13

#define USB_FNR_RXDP                    BIT(USB_FNR_RXDP_BIT)
#define USB_FNR_RXDM                    BIT(USB_FNR_RXDM_BIT)
#define USB_FNR_LCK                     BIT(USB_FNR_LCK_BIT)
#define USB_FNR_LSOF                    (0x3 << 11)
#define USB_FNR_FN                      0x7FF

/* Device address (USB_DADDR) */

#define USB_DADDR_EF_BIT                7
#define USB_DADDR_ADD6_BIT              6
#define USB_DADDR_ADD5_BIT              5
#define USB_DADDR_ADD4_BIT              4
#define USB_DADDR_ADD3_BIT              3
#define USB_DADDR_ADD2_BIT              2
#define USB_DADDR_ADD1_BIT              1
#define USB_DADDR_ADD0_BIT              0

#define USB_DADDR_EF                    BIT(USB_DADDR_EF_BIT)
#define USB_DADDR_ADD6                  BIT(USB_DADDR_ADD6_BIT)
#define USB_DADDR_ADD5                  BIT(USB_DADDR_ADD5_BIT)
#define USB_DADDR_ADD4                  BIT(USB_DADDR_ADD4_BIT)
#define USB_DADDR_ADD3                  BIT(USB_DADDR_ADD3_BIT)
#define USB_DADDR_ADD2                  BIT(USB_DADDR_ADD2_BIT)
#define USB_DADDR_ADD1                  BIT(USB_DADDR_ADD1_BIT)
#define USB_DADDR_ADD0                  BIT(USB_DADDR_ADD0_BIT)

/* Buffer table address (USB_BTABLE) */

#define USB_BTABLE_BTABLE               (0x1FFF << 3)

/*
 * Register convenience routines
 */

#define __EP_CTR_NOP                    (USB_EP_CTR_RX | USB_EP_CTR_TX)
#define __EP_NONTOGGLE                  (USB_EP_CTR_RX | USB_EP_SETUP |    \
                                         USB_EP_EP_TYPE | USB_EP_EP_KIND | \
                                         USB_EP_CTR_TX | USB_EP_EA)

static inline void usb_clear_ctr_rx(uint8 ep) {
    uint32 epr = USB_BASE->EP[ep];
    USB_BASE->EP[ep] = epr & ~USB_EP_CTR_RX & __EP_NONTOGGLE;
}

static inline void usb_clear_ctr_tx(uint8 ep) {
    uint32 epr = USB_BASE->EP[ep];
    USB_BASE->EP[ep] = epr & ~USB_EP_CTR_TX & __EP_NONTOGGLE;
}

static inline void usb_set_ep_rx_stat(uint8 ep, uint32 status) {
    uint32 epr = USB_BASE->EP[ep];
    epr &= ~(USB_EP_STAT_TX | USB_EP_DTOG_RX | USB_EP_DTOG_TX);
    epr |= __EP_CTR_NOP;
    epr ^= status;
    USB_BASE->EP[ep] = epr;
}

static inline void usb_set_ep_tx_stat(uint8 ep, uint32 status) {
    uint32 epr = USB_BASE->EP[ep];
    epr &= ~(USB_EP_STAT_RX | USB_EP_DTOG_RX | USB_EP_DTOG_TX);
    epr |= __EP_CTR_NOP;
    epr ^= status;
    USB_BASE->EP[ep] = epr;
}

static inline void usb_set_ep_type(uint8 ep, uint32 type) {
    uint32 epr = USB_BASE->EP[ep];
    epr &= ~USB_EP_EP_TYPE & __EP_NONTOGGLE;
    epr |= type;
    USB_BASE->EP[ep] = epr;
}

static inline void usb_set_ep_kind(uint8 ep, uint32 kind) {
    uint32 epr = USB_BASE->EP[ep];
    epr &= ~USB_EP_EP_KIND & __EP_NONTOGGLE;
    epr |= kind;
    USB_BASE->EP[ep] = epr;
}

static inline void usb_clear_status_out(uint8 ep) {
    usb_set_ep_kind(ep, 0);
}

/*
 * Packet memory area (PMA) base pointer
 */

/**
 * @brief USB packet memory area (PMA) base pointer.
 *
 * The USB PMA is SRAM shared between USB and CAN.  The USB peripheral
 * accesses this memory directly via the packet buffer interface.  */
#define USB_PMA_BASE                    ((__io void*)0x40006000)

/*
 * PMA conveniences
 */

void usb_copy_to_pma(const uint8 *buf, uint16 len, uint16 pma_offset);
void usb_copy_from_pma(uint8 *buf, uint16 len, uint16 pma_offset);

static inline void* usb_pma_ptr(uint32 offset) {
    return (void*)(USB_PMA_BASE + 2 * offset);
}

/*
 * BTABLE
 */

/* (Forward-declared) BTABLE entry.
 *
 * The BTABLE can be viewed as an array of usb_btable_ent values;
 * these vary in structure according to the configuration of the
 * endpoint.
 */
union usb_btable_ent;

/* Bidirectional endpoint BTABLE entry */
typedef struct usb_btable_bidi {
        __io uint16 addr_tx;     const uint16 PAD1;
        __io uint16 count_tx;    const uint16 PAD2;
        __io uint16 addr_rx;     const uint16 PAD3;
        __io uint16 count_rx;    const uint16 PAD4;
} usb_btable_bidi;

/* Unidirectional receive-only endpoint BTABLE entry */
typedef struct usb_btable_uni_rx {
        __io uint16 empty1;      const uint16 PAD1;
        __io uint16 empty2;      const uint16 PAD2;
        __io uint16 addr_rx;     const uint16 PAD3;
        __io uint16 count_rx;    const uint16 PAD4;
} usb_btable_uni_rx;

/* Unidirectional transmit-only endpoint BTABLE entry */
typedef struct usb_btable_uni_tx {
        __io uint16 addr_tx;     const uint16 PAD1;
        __io uint16 count_tx;    const uint16 PAD2;
        __io uint16 empty1;      const uint16 PAD3;
        __io uint16 empty2;      const uint16 PAD4;
} usb_btable_uni_tx;

/* Double-buffered transmission endpoint BTABLE entry */
typedef struct usb_btable_dbl_tx {
        __io uint16 addr_tx0;     const uint16 PAD1;
        __io uint16 count_tx0;    const uint16 PAD2;
        __io uint16 addr_tx1;     const uint16 PAD3;
        __io uint16 count_tx1;    const uint16 PAD4;
} usb_btable_dbl_tx;

/* Double-buffered reception endpoint BTABLE entry */
typedef struct usb_btable_dbl_rx {
        __io uint16 addr_rx0;     const uint16 PAD1;
        __io uint16 count_rx0;    const uint16 PAD2;
        __io uint16 addr_rx1;     const uint16 PAD3;
        __io uint16 count_rx1;    const uint16 PAD4;
} usb_btable_dbl_rx;

/* TODO isochronous endpoint entries */

/* Definition for above forward-declared BTABLE entry. */
typedef union usb_btable_ent {
    usb_btable_bidi   bidi;
    usb_btable_uni_rx u_rx;
    usb_btable_uni_tx u_tx;
    usb_btable_dbl_tx d_tx;
    usb_btable_dbl_rx d_rx;
} usb_btable_ent;

/*
 * BTABLE conveniences
 */

/* TODO (?) Convert usages of the many (and lengthily-named)
 * accessors/mutators below to just manipulating usb_btable_entry
 * values.  */

static inline uint32* usb_btable_ptr(uint32 offset) {
    return (uint32*)usb_pma_ptr(USB_BASE->BTABLE + offset);
}

static inline usb_btable_ent *usb_btable(void) {
    return (usb_btable_ent*)usb_btable_ptr(0);
}

/* TX address */

static inline uint32* usb_ep_tx_addr_ptr(uint8 ep) {
    return usb_btable_ptr(ep * 8);
}

static inline uint16 usb_get_ep_tx_addr(uint8 ep) {
    return (uint16)*usb_ep_tx_addr_ptr(ep);
}

static inline void usb_set_ep_tx_addr(uint8 ep, uint16 addr) {
    uint32 *tx_addr = usb_ep_tx_addr_ptr(ep);
    *tx_addr = addr & ~0x1;
}

/* RX address */

static inline uint32* usb_ep_rx_addr_ptr(uint8 ep) {
    return usb_btable_ptr(ep * 8 + 4);
}

static inline uint16 usb_get_ep_rx_addr(uint8 ep) {
    return (uint16)*usb_ep_rx_addr_ptr(ep);
}

static inline void usb_set_ep_rx_addr(uint8 ep, uint16 addr) {
    uint32 *rx_addr = usb_ep_rx_addr_ptr(ep);
    *rx_addr = addr & ~0x1;
}

/* TX count (doesn't cover double-buffered and isochronous in) */

static inline uint32* usb_ep_tx_count_ptr(uint8 ep) {
    return usb_btable_ptr(ep * 8 + 2);
}

static inline uint16 usb_get_ep_tx_count(uint8 ep) {
    /* FIXME: this is broken somehow; calling it seems to
     * confuse/crash the chip. */
    return (uint16)(*usb_ep_tx_count_ptr(ep) & 0x3FF);
}

static inline void usb_set_ep_tx_count(uint8 ep, uint16 count) {
    uint32 *txc = usb_ep_tx_count_ptr(ep);
    *txc = count;
}

/* RX count */

static inline uint32* usb_ep_rx_count_ptr(uint8 ep) {
    return usb_btable_ptr(ep * 8 + 6);
}

static inline uint16 usb_get_ep_rx_count(uint8 ep) {
    return (uint16)*usb_ep_rx_count_ptr(ep) & 0x3FF;
}

void usb_set_ep_rx_count(uint8 ep, uint16 count);

/*
 * Misc. types
 */

typedef enum usb_ep {
    USB_EP0,
    USB_EP1,
    USB_EP2,
    USB_EP3,
    USB_EP4,
    USB_EP5,
    USB_EP6,
    USB_EP7,
} usb_ep;

typedef enum usb_ep_type {
    USB_EP_T_CTL   = USB_EP_EP_TYPE_CONTROL,
    USB_EP_T_BULK  = USB_EP_EP_TYPE_BULK,
    USB_EP_T_INT   = USB_EP_EP_TYPE_INTERRUPT,
    USB_EP_T_ISO   = USB_EP_EP_TYPE_ISO
} usb_ep_type;

typedef enum usb_ep_stat {
    USB_EP_ST_RX_DIS = USB_EP_STAT_RX_DISABLED,
    USB_EP_ST_RX_STL = USB_EP_STAT_RX_STALL,
    USB_EP_ST_RX_NAK = USB_EP_STAT_RX_NAK,
    USB_EP_ST_RX_VAL = USB_EP_STAT_RX_VALID,
    USB_EP_ST_TX_DIS = USB_EP_STAT_TX_DISABLED,
    USB_EP_ST_TX_STL = USB_EP_STAT_TX_STALL,
    USB_EP_ST_TX_NAK = USB_EP_STAT_TX_NAK,
    USB_EP_ST_TX_VAL = USB_EP_STAT_TX_VALID
} usb_ep_stat;

#endif