source: tt-loader/2nd/usb.c @ 15

Last change on this file since 15 was 12, checked in by guillaume, 16 years ago

Publication tt-loader v0.2

File size: 6.0 KB
Line 
1/*
2 * 2nd - OMAP "second stage" Flash Loader
3 *
4 * Copyright (C) 2008 Guillaume Bougard <gbougard@pkg.fr>
5 * Copyright (C) 2005 Luis Recuerda <lrec@helios.homeip.net>
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
20 *
21 */
22
23#include "types.h"
24#include "usb.h"
25
26#define USBS_OFFSET     0xfffb4000
27#define REG8(addr)      (*(volatile u8 *) (addr))
28#define REG16(addr)     (*(volatile u16 *) (addr))
29#define REG32(addr)     (*(volatile u32 *) (addr))
30#define UREG(addr)      REG16 (USBS_OFFSET + (addr))
31#define UREG8(addr)     REG8 (USBS_OFFSET + (addr))
32
33#define CLOCK_CTRL_REG  REG16 (0xfffe0830)
34#define FUNC_MUX_CTRL_D REG32 (0xfffe1038)
35
36#define USBS_REV        UREG (0x00)
37#define USBS_EP_NUM     UREG (0x04)
38#define USBS_DATA       UREG (0x08)
39#define USBS_DATA8      UREG8 (0x08)
40#define USBS_CTRL       UREG (0x0c)
41#define USBS_STAT_FLG   UREG (0x10)
42#define USBS_RXFSTAT    UREG (0x14)
43#define USBS_SYSCON1    UREG (0x18)
44#define USBS_SYSCON2    UREG (0x1c)
45#define USBS_DEVSTAT    UREG (0x20)
46#define USBS_SOF        UREG (0x24)
47#define USBS_IRQ_EN     UREG (0x28)
48#define USBS_DMA_IRQ_EN UREG (0x2c)
49#define USBS_IRQ_SRC    UREG (0x30)
50#define USBS_EPN_STAT   UREG (0x34)
51#define USBS_DMAN_STAT  UREG (0x38)
52#define USBS_RXDMA_CFG  UREG (0x40)
53#define USBS_TXDMA_CFG  UREG (0x44)
54#define USBS_DATA_DMA   UREG (0x48)
55#define USBS_TXDMA0     UREG (0x50)
56#define USBS_TXDMA1     UREG (0x54)
57#define USBS_TXDMA2     UREG (0x58)
58#define USBS_RXDMA0     UREG (0x60)
59#define USBS_RXDMA1     UREG (0x64)
60#define USBS_RXDMA2     UREG (0x68)
61#define USBS_EP0        UREG (0x80)
62#define USBS_EP_RX(ep)  UREG (0x80+((ep)<<2))
63#define USBS_EP_TX(ep)  UREG (0xc0+((ep)<<2))
64
65#define _SETUP_SEL      0x40
66#define _EP_SEL 0x20
67#define _EP_SEL_IN      0x10
68#define _EP_SEL_OUT     0x00
69
70static u16      old_sel= 0;
71static void inline select (u16 sel)
72{
73        if (old_sel)
74                USBS_EP_NUM= old_sel & ~(_SETUP_SEL | _EP_SEL);
75        USBS_EP_NUM= old_sel= sel;
76}
77static void inline unselect (void)
78{
79        if (old_sel)
80                USBS_EP_NUM= old_sel & ~(_SETUP_SEL | _EP_SEL);
81        old_sel= 0;
82}
83
84#define SELECT(info)    select (_EP_SEL | (info)->select)
85#define SELECT_RX(ep)   select (_EP_SEL | _EP_SEL_OUT | (ep))
86#define SELECT_TX(ep)   select (_EP_SEL | _EP_SEL_IN | (ep))
87#define SELECT_SETUP()  select (_SETUP_SEL)
88#define UNSELECT(info)  unselect ()
89#define UNSELECT_RX(ep) unselect ()
90#define UNSELECT_TX(ep) unselect ()
91#define UNSELECT_SETUP()        unselect ()
92
93
94// CTRL:
95#define _CLR_HALT       0x80
96#define _SET_HALT       0x40
97#define _SET_FIFO_EN    0x04
98#define _CLR_EP 0x02
99#define _RESET_EP       0x01
100#define STALL_EPn_RX(ep)        do { SELECT_RX (ep); USBS_CTRL= _SET_HALT; UNSELECT_RX (ep); } while (0)
101#define STALL_EPn_TX(ep)        do { SELECT_TX (ep); USBS_CTRL= _SET_HALT; UNSELECT_TX (ep); } while (0)
102
103// STAT_FLG:
104#define _STALL  0x20
105#define _NAK    0x10
106#define _ACK    0x08
107#define _FIFO_EN        0x04
108#define _NI_FIFO_EMPTY  0x02
109#define _NI_FIFO_FULL   0x01
110
111// SYSCON1:
112#define _CFG_LOCK       0x0100
113#define _NAK_EN 0x0010
114#define _AUTODEC_DIS    0x0008
115#define _SELF_PWR       0x0004
116#define _SOFF_DIS       0x0002
117#define _PULLUP_EN      0x0001
118
119// SYSCON2:
120#define _STALL_CMD      0x20
121#define _DEV_CFG        0x08
122#define _CLR_CFG        0x04
123#define STALL_EP0()     USBS_SYSCON2= _STALL_CMD
124
125// DEVSTAT:
126#define _DS_USB_Reset   0x20
127#define _DS_SUS 0x10
128#define _DS_CFG 0x08
129#define _DS_ADD 0x04
130#define _DS_DEF 0x02
131#define _DS_ATT 0x01
132
133// IRQ_EN:
134#define _SOF_IE 0x80
135#define _EPn_RX_IE      0x20
136#define _EPn_TX_IE      0x10
137#define _DS_CHG_IE      0x08
138#define _EP0_IE 0x01
139
140// IRQ_SRC:
141#define _IRQ_TXn_DONE   (1<<10)
142#define _IRQ_RXn_CNT    (1<<9)
143#define _IRQ_RXn_EOT    (1<<8)
144#define _IRQ_SOF        (1<<7)
145#define _IRQ_EPn_RX     (1<<5)
146#define _IRQ_EPn_TX     (1<<4)
147#define _IRQ_DS_CHG     (1<<3)
148#define _IRQ_SETUP      (1<<2)
149#define _IRQ_EP0_RX     (1<<1)
150#define _IRQ_EP0_TX     (1<<0)
151
152////////////////////
153
154static const u8 *tx_buffer= 0;
155static int      tx_size= 0;
156static int      tx_complete= 0;
157
158static void write_fifo (void)
159{
160        while (tx_size > 0  &&  (USBS_STAT_FLG & _NI_FIFO_FULL) == 0)
161        {
162                USBS_DATA8= *tx_buffer++;
163                --tx_size;
164        }
165
166        tx_complete= tx_size == 0  &&  (USBS_STAT_FLG & _NI_FIFO_FULL) == 0;
167        USBS_CTRL= _SET_FIFO_EN;
168}
169
170void usb_send (const void *buffer, int size)
171{
172        tx_buffer= buffer;
173        tx_size= size;
174        tx_complete= 0;
175
176        SELECT_TX (1);
177        write_fifo ();
178        UNSELECT_TX (1);
179}
180
181int usb_sent (void)
182{
183        int     result= 0;
184
185        if (USBS_IRQ_SRC & _IRQ_EPn_TX)
186        {
187                int     epnum= USBS_EPN_STAT & 0x000f;
188                USBS_IRQ_SRC= _IRQ_EPn_TX;
189
190                if (epnum == 1)
191                {
192                        SELECT_TX (1);
193
194                        if (USBS_STAT_FLG & _ACK)
195                        {
196                                if (tx_complete)
197                                        result= 1;
198                                else
199                                        write_fifo ();
200                        }
201                        UNSELECT_TX (1);
202                }
203        }
204
205        return result;
206}
207
208////////////////////
209
210static u8       *rx_buffer= NULL;
211static u8       *rx_buffer0= NULL;
212static int      rx_complete= 0;
213static int      rx_size= 0;
214
215static void read_fifo (void)
216{
217        rx_complete= (USBS_STAT_FLG & _NI_FIFO_FULL) == 0;
218
219        while ((USBS_STAT_FLG & _NI_FIFO_EMPTY) == 0  &&  rx_size-- > 0)
220                *rx_buffer++= USBS_DATA8;
221}
222
223void usb_recv (void *buffer, int size)
224{
225        rx_buffer0= rx_buffer= buffer;
226        rx_size= size;
227
228//static int in_rx= 0;
229//if (!in_rx) { in_rx= 1;
230        SELECT_RX (2);
231        USBS_CTRL= _SET_FIFO_EN;
232        UNSELECT_RX (2);
233//}
234}
235
236int usb_rcvd (void)
237{
238        int     result= 0;
239
240        if (USBS_IRQ_SRC & _IRQ_EPn_RX)
241        {
242                int     epnum= (USBS_EPN_STAT & 0x0f00) >> 8;
243                USBS_IRQ_SRC= _IRQ_EPn_RX;
244
245                if (epnum == 2)
246                {
247                        SELECT_RX (2);
248
249                        if (USBS_STAT_FLG & _ACK)
250                        {
251                                read_fifo ();
252                                if (rx_complete  ||  rx_size == 0)
253                                        result= rx_buffer - rx_buffer0;
254                                else
255                                        USBS_CTRL= _SET_FIFO_EN;
256                        }
257                        UNSELECT_RX (2);
258                }
259        }
260
261        return result;
262}
263
264void usb_reset()
265{
266        USBS_SYSCON1 &= ~_PULLUP_EN ;
267        USBS_SYSCON1 |= _PULLUP_EN ;
268}
Note: See TracBrowser for help on using the repository browser.