aboutsummaryrefslogtreecommitdiff
path: root/include/libopenstm32/usb.h
blob: 6edfee31e981d4cb4973c4c61917c6eb8f92a12e (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
/*
 * This file is part of the libopenstm32 project.
 *
 * Copyright (C) 2009 Piotr Esden-Tempski <piotr@esden.net>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef LIBOPENSTM32_USB_H
#define LIBOPENSTM32_USB_H

#include <libopenstm32/memorymap.h>
#include <libopenstm32/common.h>
#include <libopenstm32/tools.h>

/******************************************************************************
 * USB base addresses
 ******************************************************************************/

#define USB_PMA_BASE    (0x40006000L) /* USB packet buffer memory base
                                         address */

/******************************************************************************
 * USB general registers
 ******************************************************************************/

/* USB Control register */
#define USB_CNTR_REG   ((volatile u32 *)(USB_DEV_FS_BASE + 0x40))
/* USB Interrupt status register */
#define USB_ISTR_REG   ((volatile u32 *)(USB_DEV_FS_BASE + 0x44))
/* USB Frame number register */
#define USB_FNR_REG    ((volatile u32 *)(USB_DEV_FS_BASE + 0x48))
/* USB Device address register */
#define USB_DADDR_REG  ((volatile u32 *)(USB_DEV_FS_BASE + 0x4C))
/* USB Buffer table address register */
#define USB_BTABLE_REG ((volatile u32 *)(USB_DEV_FS_BASE + 0x50))
/* USB EP register */
#define USB_EP_REG(EP) ((volatile u32 *)(USB_DEV_FS_BASE) + (EP))

/******************************************************************************
 * USB control register masks / bits
 ******************************************************************************/

/* Interrupt mask bits, set to 1 to enable interrupt generation */
#define USB_CNTR_CTRM    (0x8000)
#define USB_CNTR_PMAOVRM (0x4000)
#define USB_CNTR_ERRM    (0x2000)
#define USB_CNTR_WKUPM   (0x1000)
#define USB_CNTR_SUSPM   (0x0800)
#define USB_CNTR_RESETM  (0x0400)
#define USB_CNTR_SOFM    (0x0200)
#define USB_CNTR_ESOFM   (0x0100)

/* Request/Force bits */

#define USB_CNTR_RESUME  (0x0010) /* Resume request */
#define USB_CNTR_FSUSP   (0x0008) /* Force suspend */
#define USB_CNTR_LP_MODE (0x0004) /* Low-power mode */
#define USB_CNTR_PWDN    (0x0002) /* Power down */
#define USB_CNTR_FRES    (0x0001) /* Force reset */

/******************************************************************************
 * USB interrupt status register masks / bits
 ******************************************************************************/

#define USB_ISTR_CTR    0x8000 /* Correct Transfer */
#define USB_ISTR_PMAOVR 0x4000 /* Packet Memory Area Over / Underrun */
#define USB_ISTR_ERR    0x2000 /* Error */
#define USB_ISTR_WKUP   0x1000 /* Wake up */
#define USB_ISTR_SUSP   0x0800 /* Suspend mode request */
#define USB_ISTR_RESET  0x0400 /* USB RESET request */
#define USB_ISTR_SOF    0x0200 /* Start Of Frame */
#define USB_ISTR_ESOF   0x0100 /* Expected Start Of Frame */
#define USB_ISTR_DIR    0x0010 /* Direction of transaction */
#define USB_ISTR_EP_ID  0x000F /* Endpoint Identifier */

/******************************************************************************
 * USB interrupt status register manipulators
 ******************************************************************************/

//#define USB_CLR_ISTR_CTR()    CLR_REG_BIT(USB_ISTR_REG, USB_ISTR_CTR) /* CTR is read only! */
#define USB_CLR_ISTR_PMAOVR() CLR_REG_BIT(USB_ISTR_REG, USB_ISTR_PMAOVR)
#define USB_CLR_ISTR_ERR()    CLR_REG_BIT(USB_ISTR_REG, USB_ISTR_ERR)
#define USB_CLR_ISTR_WKUP()   CLR_REG_BIT(USB_ISTR_REG, USB_ISTR_WKUP)
#define USB_CLR_ISTR_SUSP()   CLR_REG_BIT(USB_ISTR_REG, USB_ISTR_SUSP)
#define USB_CLR_ISTR_RESET()  CLR_REG_BIT(USB_ISTR_REG, USB_ISTR_RESET)
#define USB_CLR_ISTR_SOF()    CLR_REG_BIT(USB_ISTR_REG, USB_ISTR_SOF)
#define USB_CLR_ISTR_ESOF()   CLR_REG_BIT(USB_ISTR_REG, USB_ISTR_ESOF)

/******************************************************************************
 * USB device addres register masks / bits
 ******************************************************************************/

#define USB_DADDR_ENABLE 0x0080
#define USB_DADDR_ADDR   0x007F

/******************************************************************************
 * USB device addres register manipulators
 ******************************************************************************/

/******************************************************************************
 * USB endpoint register offsets
 ******************************************************************************/

#define USB_EP0 ((u8)0)
#define USB_EP1 ((u8)1)
#define USB_EP2 ((u8)2)
#define USB_EP3 ((u8)3)
#define USB_EP4 ((u8)4)
#define USB_EP5 ((u8)5)
#define USB_EP6 ((u8)6)
#define USB_EP7 ((u8)7)

/******************************************************************************
 * USB endpoint register masks / bits
 ******************************************************************************/

/* masks and toggle bits */
#define USB_EP_RX_CTR  (0x8000) /* Correct transfer RX */
#define USB_EP_RX_DTOG (0x4000) /* Data toggle RX */
#define USB_EP_RX_STAT (0x3000) /* Endpoint status for RX */

#define USB_EP_SETUP   (0x0800) /* Setup transaction completed */
#define USB_EP_TYPE    (0x0600) /* Endpoint type */
#define USB_EP_KIND    (0x0100) /* Endpoint kind.
                                 * When set and type=bulk    -> double buffer
                                 * When set and type=control -> status out
                                 */

#define USB_EP_TX_CTR  (0x0080) /* Correct transfer TX */
#define USB_EP_TX_DTOG (0x0040) /* Data toggle TX */
#define USB_EP_TX_STAT (0x0030) /* Endpoint status for TX */

#define USB_EP_ADDR    (0x000F) /* Endpoint Address */

/* Masking all toggle bits */
#define USB_EP_NTOGGLE_MSK (USB_EP_RX_CTR |     \
                            USB_EP_SETUP  |     \
                            USB_EP_TYPE   |     \
                            USB_EP_KIND   |     \
                            USB_EP_TX_CTR |     \
                            USB_EP_ADDR)

/* All non toggle bits plus EP_RX toggle bits */
#define USB_EP_RX_STAT_TOG_MSK (USB_EP_RX_STAT | USB_EP_NTOGGLE_MSK)
/* All non toggle bits plus EP_TX toggle bits */
#define USB_EP_TX_STAT_TOG_MSK (USB_EP_TX_STAT | USB_EP_NTOGGLE_MSK)

/* Endpoint status bits for USB_EP_RX_STAT bit field */
#define USB_EP_RX_STAT_DISABLED (0x0000)
#define USB_EP_RX_STAT_STALL    (0x1000)
#define USB_EP_RX_STAT_NAK      (0x2000)
#define USB_EP_RX_STAT_VALID    (0x3000)

/* Endpoint status bits for USB_EP_TX_STAT bit field */
#define USB_EP_TX_STAT_DISABLED (0x0000)
#define USB_EP_TX_STAT_STALL    (0x0010)
#define USB_EP_TX_STAT_NAK      (0x0020)
#define USB_EP_TX_STAT_VALID    (0x0030)

/* Endpoint type bits for USB_EP_TYPE bit field */
#define USB_EP_TYPE_BULK      (0x0000)
#define USB_EP_TYPE_CONTROL   (0x0200)
#define USB_EP_TYPE_ISO       (0x0400)
#define USB_EP_TYPE_INTERRUPT (0x0600)

/******************************************************************************
 * USB endpoint register manipulators
 ******************************************************************************/

/* Set USB endpoint tx/rx status.
 *
 * USB status field is changed using an awkward toggle mechanism, that
 * is why we use some helper macros for that.
 */
#define USB_SET_EP_RX_STAT(EP, STAT)            \
    TOG_SET_REG_BIT_MSK(USB_EP_REG(EP),         \
                        USB_EP_RX_STAT_TOG_MSK, \
                        STAT)

#define USB_SET_EP_TX_STAT(EP, STAT)            \
    TOG_SET_REG_BIT_MSK(USB_EP_REG(EP),         \
                        USB_EP_TX_STAT_TOG_MSK, \
                        STAT)

/* Macros for clearing and setting USB endpoint register bits that do
 * not use the toggle mechanism.
 *
 * Because the register contains some bits that use the toggle
 * mechanism we need a helper macro here. Otherwise the code gets
 * really messy.
 */
#define USB_CLR_EP_NTOGGLE_BIT(EP, BIT)         \
    CLR_REG_BIT_MSK(USB_EP_REG(EP),             \
                    USB_EP_NTOGGLE_MSK,         \
                    BIT)

#define USB_CLR_EP_RX_CTR(EP)                   \
    USB_CLR_EP_NTOGGLE_BIT(EP,                  \
                           USB_EP_RX_CTR)

#define USB_CLR_EP_TX_CTR(EP)                   \
    USB_CLR_EP_NTOGGLE_BIT(EP,                  \
                           USB_EP_TX_CTR)

#define USB_SET_EP_TYPE(EP, TYPE)               \
    SET_REG(USB_EP_REG(EP),                     \
            (GET_REG(USB_EP_REG(EP)) &          \
             (USB_EP_NTOGGLE_MSK &              \
              (~USB_EP_TYPE))) | TYPE)

#define USB_SET_EP_KIND(EP)                     \
    SET_REG(USB_EP_REG(EP),                     \
            (GET_REG(USB_EP_REG(EP)) &          \
             (USB_EP_NTOGGLE_MSK &              \
              (~USB_EP_KIND))) | USB_EP_KIND)

#define USB_CLR_EP_KIND(EP)                     \
    SET_REG(USB_EP_REG(EP),                     \
            (GET_REG(USB_EP_REG(EP)) &          \
             (USB_EP_NTOGGLE_MSK &              \
              (~USB_EP_KIND))))

#define USB_SET_EP_STAT_OUT(EP)                 \
    USB_SET_EP_KIND(EP)

#define USB_CLR_EP_STAT_OUT(EP)                 \
    USB_CLR_EP_KIND(EP)

#define USB_SET_EP_ADDR(EP, ADDR)               \
    SET_REG(USB_EP_REG(EP),                     \
            ((GET_REG(USB_EP_REG(EP)) &         \
              (USB_EP_NTOGGLE_MSK &             \
               (~USB_EP_ADDR))) | ADDR))

/* Macros for clearing DTOG bits */
#define USB_CLR_EP_TX_DTOG(EP)			\
	SET_REG(USB_EP_REG(EP), 		\
		(GET_REG(USB_EP_REG(EP)) &	\
		USB_EP_NTOGGLE_MSK) | USB_EP_TX_DTOG)

#define USB_CLR_EP_RX_DTOG(EP)			\
	SET_REG(USB_EP_REG(EP), 		\
		(GET_REG(USB_EP_REG(EP)) &	\
		USB_EP_NTOGGLE_MSK) | USB_EP_RX_DTOG)


/******************************************************************************
 * USB BTABLE registers
 ******************************************************************************/
#define USB_GET_BTABLE GET_REG(USB_BTABLE_REG)

#define USB_EP_TX_ADDR(EP)  ((u32 *)(USB_PMA_BASE +                     \
                                     (USB_GET_BTABLE+EP*8  ) * 2))

#define USB_EP_TX_COUNT(EP) ((u32 *)(USB_PMA_BASE +                     \
                                     (USB_GET_BTABLE+EP*8+2) * 2))

#define USB_EP_RX_ADDR(EP)  ((u32 *)(USB_PMA_BASE +                     \
                                     (USB_GET_BTABLE+EP*8+4) * 2))

#define USB_EP_RX_COUNT(EP) ((u32 *)(USB_PMA_BASE +                     \
                                     (USB_GET_BTABLE+EP*8+6) * 2))

/******************************************************************************
 * USB BTABLE manipulators
 ******************************************************************************/

#define USB_GET_EP_TX_ADDR(EP)                  \
    GET_REG(USB_EP_TX_ADDR(EP))

#define USB_GET_EP_TX_COUNT(EP)                 \
    GET_REG(USB_EP_TX_COUNT(EP))

#define USB_GET_EP_RX_ADDR(EP)                  \
    GET_REG(USB_EP_RX_ADDR(EP))

#define USB_GET_EP_RX_COUNT(EP)                 \
    GET_REG(USB_EP_RX_COUNT(EP))

#define USB_SET_EP_TX_ADDR(EP, ADDR)            \
    SET_REG(USB_EP_TX_ADDR(EP), ADDR)

#define USB_SET_EP_TX_COUNT(EP, COUNT)          \
    SET_REG(USB_EP_TX_COUNT(EP), COUNT)

#define USB_SET_EP_RX_ADDR(EP, ADDR)            \
    SET_REG(USB_EP_RX_ADDR(EP), ADDR)

#define USB_SET_EP_RX_COUNT(EP, COUNT)          \
    SET_REG(USB_EP_RX_COUNT(EP), COUNT)

#define USB_GET_EP_TX_BUFF(EP)                  \
    (USB_PMA_BASE +                             \
     (u8 *)(USB_GET_EP_TX_ADDR(EP) * 2))

#define USB_GET_EP_RX_BUFF(EP)                  \
    (USB_PMA_BASE +                             \
     (u8 *)(USB_GET_EP_RX_ADDR(EP) * 2))

#endif